From 279284b143fb4a16e575c07d4401ec9d6092feaf Mon Sep 17 00:00:00 2001 From: Marcus Kammer Date: Wed, 24 Aug 2022 19:36:32 +0200 Subject: [PATCH] Update clones --- .../clojure-doc.org/articles/about/index.html | 216 ++ .../articles/content/index.html | 225 ++ .../cookbooks/data_structures/index.html | 208 ++ .../cookbooks/date_and_time/index.html | 208 ++ .../files_and_directories/index.html | 252 ++ .../articles/cookbooks/math/index.html | 252 ++ .../articles/cookbooks/middleware/index.html | 326 ++ .../articles/cookbooks/strings/index.html | 464 +++ .../articles/ecosystem/books/index.html | 230 ++ .../articles/ecosystem/community/index.html | 213 ++ .../ecosystem/core_typed/filters/index.html | 244 ++ .../core_typed/function_types/index.html | 237 ++ .../ecosystem/core_typed/home/index.html | 207 ++ .../core_typed/limitations/index.html | 222 ++ .../ecosystem/core_typed/loops/index.html | 223 ++ .../mm_protocol_datatypes/index.html | 219 ++ .../ecosystem/core_typed/poly_fn/index.html | 234 ++ .../ecosystem/core_typed/quick_guide.html | 241 ++ .../core_typed/quick_guide/index.html | 241 ++ .../ecosystem/core_typed/rationale/index.html | 227 ++ .../core_typed/start/annotations/index.html | 275 ++ .../introduction_and_motivation/index.html | 237 ++ .../ecosystem/core_typed/types/index.html | 338 ++ .../core_typed/user_documentation/index.html | 257 ++ .../ecosystem/data_processing/index.html | 208 ++ .../generating_documentation/index.html | 231 ++ .../articles/ecosystem/java_jdbc/home.html | 310 ++ .../ecosystem/java_jdbc/home/index.html | 310 ++ .../java_jdbc/reusing_connections.html | 289 ++ .../java_jdbc/reusing_connections/index.html | 289 ++ .../ecosystem/java_jdbc/using_ddl.html | 249 ++ .../ecosystem/java_jdbc/using_ddl/index.html | 249 ++ .../ecosystem/java_jdbc/using_sql.html | 510 +++ .../ecosystem/java_jdbc/using_sql/index.html | 510 +++ .../ecosystem/libraries_authoring/index.html | 343 ++ .../ecosystem/libraries_directory/index.html | 239 ++ .../articles/ecosystem/maven/index.html | 395 +++ .../ecosystem/running_cljug/index.html | 209 ++ .../articles/ecosystem/user_groups/index.html | 212 ++ .../ecosystem/web_development/index.html | 239 ++ .../collections_and_sequences/index.html | 648 ++++ .../concurrency_and_parallelism/index.html | 755 +++++ .../language/core_overview/index.html | 745 +++++ .../articles/language/functions/index.html | 398 +++ .../articles/language/glossary/index.html | 344 ++ .../articles/language/interop/index.html | 617 ++++ .../articles/language/laziness/index.html | 264 ++ .../articles/language/macros/index.html | 382 +++ .../articles/language/namespaces/index.html | 375 +++ .../articles/language/polymorphism/index.html | 385 +++ .../basic_web_development/index.html | 476 +++ .../articles/tutorials/eclipse/index.html | 250 ++ .../articles/tutorials/emacs/index.html | 445 +++ .../tutorials/getting_started/index.html | 256 ++ .../growing_a_dsl_with_clojure/index.html | 385 +++ .../tutorials/introduction/index.html | 968 ++++++ .../parsing_xml_with_zippers/index.html | 486 +++ .../tutorials/vim_fireplace/index.html | 271 ++ clones/clojure-doc.org/css/screen.css | 168 + clones/clojure-doc.org/index.html | 237 ++ clones/clojure-doc.org/js/highlight.pack.js | 2 + .../local-redirect/local-redirect.js | 13 +- .../Building_New_Contract_Combinators.html | 313 ++ .../reference/Byte_and_String_Input.html | 180 ++ .../reference/Byte_and_String_Output.html | 64 + .../reference/Command-Line_Parsing.html | 152 + .../reference/Delayed_Evaluation.html | 59 + .../reference/Equality.html | 202 ++ .../reference/Exiting.html | 19 + .../reference/Expanding_Top-Level_Forms.html | 51 + .../reference/Filesystem.html | 850 +++++ .../Generating_A_Unit_from_Context.html | 9 + .../reference/Generators.html | 49 + .../reference/Interactive_Help.html | 22 + .../reference/Kernel_Forms_and_Functions.html | 25 + .../Lazy_Data-structure_Contracts.html | 28 + .../reference/Legacy_Contracts.html | 7 + .../Locations____variable-reference.html | 18 + .../reference/Macros.html | 6 + .../reference/Manipulating_Paths.html | 237 ++ .../reference/Module_Names_and_Loading.html | 320 ++ .../reference/More_Path_Utilities.html | 65 + .../reference/Namespaces.html | 207 ++ .../reference/Object_and_Class_Contracts.html | 127 + .../reference/Printer_Extension.html | 51 + .../reference/Random_generation.html | 44 + .../reference/Reader_Extension.html | 10 + .../reference/Reading.html | 185 ++ .../reference/Sandboxed_Evaluation.html | 511 +++ .../reference/Serializing_Syntax.html | 41 + .../reference/Single-Signature_Modules.html | 15 + .../reference/Structural_Matching.html | 25 + .../Structure_Type_Property_Contracts.html | 32 + .../reference/Surrogates.html | 63 + .../Syntax_Quoting__quote-syntax.html | 13 + .../reference/Transformer_Helpers.html | 36 + .../reference/Unit_Utilities.html | 4 + .../reference/Writing.html | 140 + .../reference/__expression.html | 22 + .../reference/__top-interaction.html | 6 + .../docs.racket-lang.org/reference/__top.html | 24 + .../reference/all-sync.html | 7 + .../reference/application.html | 29 + .../reference/async-channel.html | 41 + .../attaching-contracts-to-values.html | 151 + .../docs.racket-lang.org/reference/begin.html | 30 + .../docs.racket-lang.org/reference/block.html | 8 + .../reference/booleans.html | 22 + .../docs.racket-lang.org/reference/boxes.html | 24 + .../reference/breakhandler.html | 89 + .../reference/bytestrings.html | 246 ++ .../docs.racket-lang.org/reference/case.html | 14 + .../reference/channel.html | 25 + .../reference/chaperones.html | 469 +++ .../reference/characters.html | 71 + .../reference/collapsible.html | 57 + .../reference/collects.html | 205 ++ .../reference/compiler.html | 70 + .../reference/compoundunits.html | 46 + .../reference/concurrency.html | 6 + .../docs.racket-lang.org/reference/cont.html | 177 ++ .../reference/contmarks.html | 110 + .../reference/contract-utilities.html | 98 + .../reference/contracts.html | 47 + .../reference/control.html | 2 + .../reference/createclass.html | 324 ++ .../reference/createinterface.html | 30 + .../reference/creatingmorestructs.html | 88 + .../reference/creatingunits.html | 101 + .../reference/custodians.html | 64 + .../reference/customport.html | 370 +++ .../reference/data-structure-contracts.html | 281 ++ .../docs.racket-lang.org/reference/data.html | 3 + .../reference/debugging.html | 87 + .../reference/define-sig-form.html | 16 + .../reference/define-struct.html | 146 + .../reference/define.html | 70 + .../docs.racket-lang.org/reference/dicts.html | 202 ++ .../reference/doc-bibliography.html | 2 + .../reference/doc-index.html | 35 + .../reference/encodings.html | 72 + .../reference/engine.html | 39 + .../reference/envvars.html | 48 + .../reference/ephemerons.html | 40 + .../reference/eval-model.html | 515 +++ .../docs.racket-lang.org/reference/eval.html | 347 ++ .../docs.racket-lang.org/reference/exns.html | 507 +++ .../reference/extflonums.html | 51 + .../docs.racket-lang.org/reference/extras.css | 12 + .../docs.racket-lang.org/reference/fasl.html | 56 + .../reference/file-ports.html | 163 + .../docs.racket-lang.org/reference/finger.png | Bin 0 -> 430 bytes .../reference/fixnums.html | 79 + .../reference/flonums.html | 73 + .../docs.racket-lang.org/reference/for.html | 259 ++ .../reference/function-contracts.html | 192 ++ .../reference/futures.html | 140 + .../reference/garbagecollection.html | 101 + .../reference/generic-numbers.html | 273 ++ .../reference/hashtables.html | 278 ++ .../docs.racket-lang.org/reference/icons.css | 8 + clones/docs.racket-lang.org/reference/if.html | 42 + .../reference/implementations.html | 26 + .../reference/include.html | 28 + .../docs.racket-lang.org/reference/index.html | 10 + .../reference/input-and-output.html | 2 + .../reference/inspectors.html | 90 + .../reference/interaction-info.html | 16 + .../reference/interactive.html | 38 + .../reference/invokingunits.html | 26 + .../reference/ivaraccess.html | 69 + .../reference/keywords.html | 18 + .../reference/lambda.html | 94 + .../reference/lazy-require.html | 44 + .../docs.racket-lang.org/reference/let.html | 78 + .../reference/linecol.html | 60 + .../reference/linkinference.html | 70 + .../reference/linklets.html | 247 ++ .../reference/load-lang.html | 24 + .../docs.racket-lang.org/reference/local.html | 9 + .../reference/logging.html | 155 + .../reference/magnify.png | Bin 0 -> 323 bytes .../docs.racket-lang.org/reference/match.html | 195 ++ .../reference/memory-order.html | 26 + .../reference/memory.html | 2 + .../reference/mixins.html | 12 + .../docs.racket-lang.org/reference/model.html | 2 + .../reference/modprotect.html | 50 + .../reference/module.html | 196 ++ .../reference/mpairs.html | 20 + .../reference/mzlib_class.html | 29 + .../reference/mzlib_unit.html | 10 + .../reference/networking.html | 2 + .../reference/notation.html | 113 + .../reference/number-types.html | 28 + .../reference/numbers.html | 71 + .../reference/objcreation.html | 53 + .../reference/objectequality.html | 31 + .../reference/objectprinting.html | 19 + .../reference/objectserialize.html | 40 + .../reference/objectutils.html | 61 + .../reference/os-lib.html | 3 + clones/docs.racket-lang.org/reference/os.html | 2 + .../docs.racket-lang.org/reference/pairs.html | 243 ++ .../reference/parameters.html | 57 + .../reference/parametric-contracts.html | 34 + .../reference/pathutils.html | 30 + .../reference/performance-hint.html | 12 + .../reference/phantom-bytes.html | 19 + .../reference/phase_space.html | 39 + .../reference/pipeports.html | 23 + .../reference/places.html | 215 ++ .../reference/plumbers.html | 35 + .../reference/port-buffers.html | 86 + .../reference/port-lib.html | 290 ++ .../reference/port-ops.html | 34 + .../docs.racket-lang.org/reference/ports.html | 40 + .../reference/portstructs.html | 16 + .../reference/pretty-print.html | 173 + .../reference/printing.html | 425 +++ .../reference/procedures.html | 262 ++ .../reference/quasiquote.html | 36 + .../docs.racket-lang.org/reference/quote.html | 9 + .../reference/racket_contract_base.html | 10 + .../reference/reader-procs.html | 32 + .../reference/reader.html | 468 +++ .../reference/readtables.html | 97 + .../reference/regexp.html | 329 ++ .../reference/repl-module.html | 6 + .../reference/require.html | 394 +++ .../reference/running-sa.html | 336 ++ .../reference/running.html | 2 + .../reference/runtime.html | 113 + .../reference/security.html | 2 + .../reference/securityguards.html | 59 + .../reference/semaphore.html | 52 + .../reference/sequences.html | 282 ++ .../reference/sequences_streams.html | 7 + .../reference/serialization.html | 283 ++ .../docs.racket-lang.org/reference/set_.html | 24 + .../docs.racket-lang.org/reference/sets.html | 276 ++ .../docs.racket-lang.org/reference/sha.html | 20 + .../reference/shared.html | 46 + .../reference/single-unit.html | 11 + .../reference/special-comments.html | 10 + .../reference/splicing.html | 29 + .../reference/stencil_vectors.html | 50 + .../reference/stratified-body.html | 9 + .../reference/streams.html | 104 + .../reference/stringport.html | 36 + .../reference/strings.html | 223 ++ .../reference/struct-copy.html | 24 + .../reference/struct-generics.html | 103 + .../reference/structinfo.html | 103 + .../reference/structprops.html | 74 + .../reference/structures.html | 53 + .../reference/structutils.html | 82 + .../reference/stx-patterns.html | 197 ++ .../reference/stxcerts.html | 27 + .../reference/stxcmp.html | 97 + .../reference/stxops.html | 171 + .../reference/stxparam.html | 50 + .../reference/stxprops.html | 110 + .../reference/stxtrans.html | 729 +++++ .../reference/subprocess.html | 248 ++ .../reference/symbols.html | 46 + .../docs.racket-lang.org/reference/sync.html | 144 + .../reference/syntax-model.html | 655 ++++ .../reference/syntax-util.html | 60 + .../reference/syntax.html | 22 + .../docs.racket-lang.org/reference/tcp.html | 126 + .../reference/thread-local-storage.html | 4 + .../reference/threadcells.html | 36 + .../reference/threadgroups.html | 15 + .../reference/threads.html | 137 + .../docs.racket-lang.org/reference/time.html | 83 + .../docs.racket-lang.org/reference/trait.html | 76 + .../docs.racket-lang.org/reference/udp.html | 147 + .../reference/undefined.html | 5 + .../reference/unitcontracts.html | 16 + .../reference/unixpaths.html | 27 + .../reference/unreachable.html | 10 + .../reference/unsafe.html | 211 ++ .../reference/values.html | 12 + .../reference/vectors.html | 84 + .../docs.racket-lang.org/reference/void.html | 5 + .../docs.racket-lang.org/reference/wcm.html | 13 + .../reference/weakbox.html | 14 + .../reference/when_unless.html | 6 + .../reference/willexecutor.html | 45 + .../reference/windowspaths.html | 245 ++ .../releases/8.6/doc/doc-site.css | 0 .../releases/8.6/doc/doc-site.js | 0 .../8.6/doc/guide/An_Extended_Example.html | 22 + .../releases/8.6/doc/guide/Backtracking.html | 28 + .../8.6/doc/guide/Building_New_Contracts.html | 185 ++ .../8.6/doc/guide/Contracts_for_Units.html | 16 + .../releases/8.6/doc/guide/Emacs.html | 56 + .../8.6/doc/guide/Invoking_Units.html | 18 + .../releases/8.6/doc/guide/Linking_Units.html | 17 + .../Lists__Iteration__and_Recursion.html | 96 + .../doc/guide/Looking_Ahead_and_Behind.html | 22 + .../releases/8.6/doc/guide/Module_Syntax.html | 107 + .../8.6/doc/guide/More_Libraries.html | 40 + .../Pairs__Lists__and_Racket_Syntax.html | 87 + .../8.6/doc/guide/Signatures_and_Units.html | 17 + .../releases/8.6/doc/guide/Simple_Values.html | 15 + .../releases/8.6/doc/guide/Sublime_Text.html | 3 + .../releases/8.6/doc/guide/Vim.html | 55 + .../8.6/doc/guide/Visual_Studio_Code.html | 3 + .../Whole-module_Signatures_and_Units.html | 10 + .../releases/8.6/doc/guide/application.html | 41 + .../releases/8.6/doc/guide/begin.html | 27 + .../releases/8.6/doc/guide/binding.html | 35 + .../releases/8.6/doc/guide/booleans.html | 8 + .../releases/8.6/doc/guide/boxes.html | 5 + .../releases/8.6/doc/guide/bytestrings.html | 22 + .../releases/8.6/doc/guide/case.html | 11 + .../releases/8.6/doc/guide/characters.html | 27 + .../releases/8.6/doc/guide/classes.html | 365 +++ .../releases/8.6/doc/guide/cmdline-tools.html | 27 + .../doc/guide/code-inspectors_protect.html | 34 + .../releases/8.6/doc/guide/concurrency.html | 101 + .../releases/8.6/doc/guide/conditionals.html | 47 + .../8.6/doc/guide/contract-boundaries.html | 44 + .../releases/8.6/doc/guide/contract-func.html | 132 + .../8.6/doc/guide/contracts-examples.html | 29 + .../8.6/doc/guide/contracts-exists.html | 19 + .../8.6/doc/guide/contracts-first.html | 78 + .../guide/contracts-general-functions.html | 186 ++ .../8.6/doc/guide/contracts-gotchas.html | 61 + .../8.6/doc/guide/contracts-struct.html | 107 + .../releases/8.6/doc/guide/contracts.html | 3 + .../releases/8.6/doc/guide/control.html | 4 + .../releases/8.6/doc/guide/conts.html | 32 + .../releases/8.6/doc/guide/datatypes.html | 5 + .../releases/8.6/doc/guide/default-ports.html | 13 + .../releases/8.6/doc/guide/define-struct.html | 170 + .../releases/8.6/doc/guide/define.html | 38 + .../releases/8.6/doc/guide/dialects.html | 13 + .../8.6/doc/guide/doc-bibliography.html | 2 + .../releases/8.6/doc/guide/doc-index.html | 17 + .../releases/8.6/doc/guide/encodings.html | 26 + .../releases/8.6/doc/guide/eval.html | 72 + .../releases/8.6/doc/guide/exe.html | 4 + .../releases/8.6/doc/guide/exns.html | 30 + .../releases/8.6/doc/guide/figure.css | 37 + .../releases/8.6/doc/guide/figure.js | 27 + .../releases/8.6/doc/guide/finger.png | Bin 0 -> 430 bytes .../8.6/doc/guide/firstclassunits.html | 46 + .../releases/8.6/doc/guide/for.html | 130 + .../8.6/doc/guide/hash-lang_reader.html | 23 + .../8.6/doc/guide/hash-lang_syntax.html | 43 + .../8.6/doc/guide/hash-languages.html | 9 + .../releases/8.6/doc/guide/hash-reader.html | 84 + .../releases/8.6/doc/guide/hash-tables.html | 29 + .../releases/8.6/doc/guide/i_o.html | 9 + .../releases/8.6/doc/guide/icons.css | 8 + .../releases/8.6/doc/guide/index.html | 10 + .../releases/8.6/doc/guide/intro.html | 75 + .../releases/8.6/doc/guide/io-patterns.html | 19 + .../releases/8.6/doc/guide/keywords.html | 14 + .../releases/8.6/doc/guide/lambda.html | 39 + .../8.6/doc/guide/language-collection.html | 21 + .../8.6/doc/guide/language-get-info.html | 48 + .../releases/8.6/doc/guide/languages.html | 14 + .../releases/8.6/doc/guide/let.html | 43 + .../releases/8.6/doc/guide/load.html | 40 + .../releases/8.6/doc/guide/macro-module.html | 136 + .../8.6/doc/guide/macro-transformers.html | 21 + .../releases/8.6/doc/guide/macros.html | 19 + .../releases/8.6/doc/guide/magnify.png | Bin 0 -> 323 bytes .../releases/8.6/doc/guide/match.html | 31 + .../releases/8.6/doc/guide/mk-namespace.html | 77 + .../releases/8.6/doc/guide/module-basics.html | 186 ++ .../8.6/doc/guide/module-languages.html | 49 + .../releases/8.6/doc/guide/module-macro.html | 23 + .../releases/8.6/doc/guide/module-paths.html | 83 + .../8.6/doc/guide/module-provide.html | 31 + .../8.6/doc/guide/module-require.html | 32 + .../8.6/doc/guide/module-runtime-config.html | 63 + .../releases/8.6/doc/guide/module-set.html | 25 + .../releases/8.6/doc/guide/modules.html | 3 + .../8.6/doc/guide/more-hash-lang.html | 30 + .../releases/8.6/doc/guide/numbers.html | 49 + .../releases/8.6/doc/guide/other-editors.html | 6 + .../releases/8.6/doc/guide/pairs.html | 28 + .../releases/8.6/doc/guide/parallelism.html | 162 + .../releases/8.6/doc/guide/parameterize.html | 44 + .../8.6/doc/guide/pattern-macros.html | 127 + .../releases/8.6/doc/guide/performance.html | 348 ++ .../releases/8.6/doc/guide/phases.html | 133 + .../releases/8.6/doc/guide/pict.png | Bin 0 -> 23264 bytes .../releases/8.6/doc/guide/pict_2.png | Bin 0 -> 27932 bytes .../releases/8.6/doc/guide/pict_3.png | Bin 0 -> 38288 bytes .../releases/8.6/doc/guide/pict_4.png | Bin 0 -> 28080 bytes .../releases/8.6/doc/guide/pict_5.png | Bin 0 -> 21361 bytes .../releases/8.6/doc/guide/ports.html | 24 + .../releases/8.6/doc/guide/proc-macros.html | 7 + .../releases/8.6/doc/guide/prompt.html | 26 + .../releases/8.6/doc/guide/protect-out.html | 19 + .../releases/8.6/doc/guide/qq.html | 21 + .../releases/8.6/doc/guide/quote.html | 18 + .../releases/8.6/doc/guide/racket.html | 63 + .../releases/8.6/doc/guide/read-write.html | 18 + .../releases/8.6/doc/guide/reflection.html | 4 + .../8.6/doc/guide/regexp-alternation.html | 14 + .../releases/8.6/doc/guide/regexp-assert.html | 10 + .../releases/8.6/doc/guide/regexp-chars.html | 60 + .../8.6/doc/guide/regexp-clusters.html | 50 + .../releases/8.6/doc/guide/regexp-intro.html | 41 + .../releases/8.6/doc/guide/regexp-match.html | 40 + .../releases/8.6/doc/guide/regexp-quant.html | 26 + .../releases/8.6/doc/guide/regexp.html | 7 + .../releases/8.6/doc/guide/running.html | 6 + .../releases/8.6/doc/guide/scheme-forms.html | 5 + .../releases/8.6/doc/guide/scripts.html | 41 + .../releases/8.6/doc/guide/serialization.html | 18 + .../releases/8.6/doc/guide/set_.html | 24 + .../releases/8.6/doc/guide/standards.html | 31 + .../releases/8.6/doc/guide/strings.html | 28 + .../releases/8.6/doc/guide/stx-certs.html | 34 + .../releases/8.6/doc/guide/stx-obj.html | 40 + .../releases/8.6/doc/guide/stx-phases.html | 65 + .../releases/8.6/doc/guide/symbols.html | 28 + .../releases/8.6/doc/guide/syntax-case.html | 32 + .../8.6/doc/guide/syntax-notation.html | 26 + .../8.6/doc/guide/syntax-overview.html | 145 + .../8.6/doc/guide/syntax_module-reader.html | 26 + .../8.6/doc/guide/teaching-langs.html | 6 + .../releases/8.6/doc/guide/to-scheme.html | 5 + .../8.6/doc/guide/unit_versus_module.html | 36 + .../releases/8.6/doc/guide/units.html | 15 + .../releases/8.6/doc/guide/vectors.html | 16 + .../8.6/doc/guide/void_undefined.html | 15 + .../releases/8.6/doc/guide/with-syntax.html | 20 + .../8.6/doc/local-redirect/local-redirect.js | 210 ++ .../doc/local-redirect/local-user-redirect.js | 0 .../releases/8.6/doc/manual-fonts.css | 251 ++ .../releases/8.6/doc/manual-racket.css | 326 ++ .../releases/8.6/doc/manual-racket.js | 247 ++ .../releases/8.6/doc/manual-style.css | 784 +++++ .../releases/8.6/doc/racket.css | 251 ++ .../releases/8.6/doc/scribble-common.js | 196 ++ .../releases/8.6/doc/scribble.css | 516 +++ clones/download.racket-lang.org/robots.txt | 2 + .../llthw.common-lisp.dev/1-0-0-overview.html | 1863 +++++++++++ .../1-01-00-lisp-bootcamp.html | 1847 +++++++++++ .../1-01-01-syntax-overview.html | 1891 +++++++++++ .../llthw.common-lisp.dev/1-01-02-repl.html | 1854 +++++++++++ .../1-01-03-expressions.html | 1901 +++++++++++ .../1-01-04-lists-cons-cells.html | 1877 +++++++++++ .../1-01-05-symbols.html | 1896 +++++++++++ .../1-01-06-prefix-notation.html | 1841 +++++++++++ .../1-01-07-style-guide.html | 2005 ++++++++++++ .../1-01-08-configuration.html | 1904 +++++++++++ .../1-02-00-input-output.html | 1860 +++++++++++ .../1-02-01-strings.html | 1846 +++++++++++ .../1-02-02-more-strings.html | 1845 +++++++++++ .../1-02-03-unicode.html | 1843 +++++++++++ .../llthw.common-lisp.dev/1-02-04-chars.html | 1858 +++++++++++ .../1-02-05-more-chars.html | 1854 +++++++++++ .../1-02-06-char-codes.html | 1845 +++++++++++ .../1-02-07-strings-from-chars.html | 1843 +++++++++++ .../1-02-08-printing.html | 1869 +++++++++++ .../1-02-09-more-printing.html | 1869 +++++++++++ .../llthw.common-lisp.dev/1-02-10-prin1.html | 1849 +++++++++++ .../llthw.common-lisp.dev/1-02-11-princ.html | 1850 +++++++++++ .../llthw.common-lisp.dev/1-02-12-format.html | 1868 +++++++++++ .../1-02-13-more-format.html | 1872 +++++++++++ .../1-02-14-pathnames.html | 1884 +++++++++++ .../1-02-15-streams.html | 1867 +++++++++++ .../1-02-16-file-streams.html | 1869 +++++++++++ .../1-02-17-binary-streams.html | 1857 +++++++++++ .../1-02-18-prompting-users.html | 1856 +++++++++++ .../1-02-19-pretty-printing.html | 1846 +++++++++++ .../1-03-0-getting-input-from-users.html | 2028 ++++++++++++ .../llthw.common-lisp.dev/1-04-0-lists.html | 2363 ++++++++++++++ .../1-05-0-lookups-trees.html | 2814 +++++++++++++++++ clones/llthw.common-lisp.dev/1-06-0-math.html | 1856 +++++++++++ .../1-06-01-integers.html | 1865 +++++++++++ .../1-06-02-more-integers.html | 1863 +++++++++++ .../1-06-03-hexadecimal-notation.html | 1888 +++++++++++ .../1-06-04-octal-notation.html | 1888 +++++++++++ .../1-06-05-binary-notation.html | 1893 +++++++++++ .../llthw.common-lisp.dev/1-06-06-ratios.html | 1886 +++++++++++ .../1-06-07-floating-point.html | 1875 +++++++++++ .../1-06-08-constants.html | 1864 +++++++++++ .../1-06-09-complex-numbers.html | 1848 +++++++++++ .../1-06-10-arithmetic.html | 1879 +++++++++++ .../1-06-11-more-arithmetic.html | 1873 +++++++++++ .../1-06-12-even-more-arithmetic.html | 1842 +++++++++++ .../1-06-13-exponents.html | 1847 +++++++++++ .../1-06-14-logarithms.html | 1847 +++++++++++ .../1-06-15-trigonometry.html | 1852 +++++++++++ .../1-06-16-psuedorandom-numbers.html | 1865 +++++++++++ .../llthw.common-lisp.dev/1-07-0-arrays.html | 1923 +++++++++++ .../1-08-0-variables.html | 1900 +++++++++++ .../1-09-0-closures.html | 1917 +++++++++++ .../1-10-0-functions.html | 1936 ++++++++++++ .../1-11-0-text-adventure.html | 1906 +++++++++++ .../1-12-0-namespaces.html | 2351 ++++++++++++++ .../1-13-0-simple-web-app.html | 1882 +++++++++++ .../1-14-0-conditionals.html | 1890 +++++++++++ .../1-15-0-command-line-utility.html | 1865 +++++++++++ .../1-16-0-map-loop.html | 1892 +++++++++++ .../llthw.common-lisp.dev/1-17-0-iterate.html | 1876 +++++++++++ .../llthw.common-lisp.dev/1-18-0-format.html | 1881 +++++++++++ clones/llthw.common-lisp.dev/1-19-0-dsl.html | 1897 +++++++++++ .../llthw.common-lisp.dev/1-20-0-review.html | 1845 +++++++++++ .../llthw.common-lisp.dev/2-0-0-overview.html | 1862 +++++++++++ .../2-01-0-programming-paradigms.html | 1923 +++++++++++ .../llthw.common-lisp.dev/2-02-0-regex.html | 1901 +++++++++++ .../2-03-0-objects-control.html | 1978 ++++++++++++ .../2-04-0-data-persistence.html | 1925 +++++++++++ .../2-05-0-extended-types.html | 1928 +++++++++++ .../2-06-0-threads-memos-parallel.html | 1908 +++++++++++ .../2-07-0-logic-and-more-math.html | 1945 ++++++++++++ .../2-08-0-number-theory.html | 1947 ++++++++++++ .../2-09-0-binary-octets-bits.html | 1923 +++++++++++ ...2-10-0-improved-text-adventure-engine.html | 1904 +++++++++++ .../2-11-0-conditions.html | 1903 +++++++++++ .../llthw.common-lisp.dev/2-12-0-2d-game.html | 1944 ++++++++++++ .../2-13-0-compiler.html | 1918 +++++++++++ .../2-14-0-tree-shaker.html | 1912 +++++++++++ .../2-15-0-docs-and-inspection.html | 1904 +++++++++++ .../2-16-0-foreign-libs.html | 1882 +++++++++++ .../2-17-0-debugging-testing.html | 1902 +++++++++++ clones/llthw.common-lisp.dev/2-18-0-ffi.html | 1873 +++++++++++ .../2-19-0-essential-libs.html | 1952 ++++++++++++ .../2-20-0-packaging-libs.html | 1907 +++++++++++ .../llthw.common-lisp.dev/2-21-0-review.html | 1852 +++++++++++ .../3-00-00-overview.html | 1863 +++++++++++ .../3-01-00-web-apps.html | 1899 +++++++++++ .../3-02-00-typesetting.html | 1929 +++++++++++ .../llthw.common-lisp.dev/3-03-00-mobile.html | 1860 +++++++++++ clones/llthw.common-lisp.dev/3-04-00-gui.html | 1880 +++++++++++ .../3-05-00-system-utils.html | 1878 +++++++++++ .../3-06-00-reverse-engineering.html | 1893 +++++++++++ .../3-07-00-graphics.html | 1893 +++++++++++ .../llthw.common-lisp.dev/3-08-00-gaming.html | 1885 +++++++++++ .../llthw.common-lisp.dev/3-09-00-audio.html | 1889 +++++++++++ .../llthw.common-lisp.dev/3-10-00-data.html | 1874 +++++++++++ .../3-11-00-cryptosec.html | 1884 +++++++++++ .../3-12-00-fintech.html | 1913 +++++++++++ .../3-13-00-scientific-computing.html | 1878 +++++++++++ .../3-14-00-computational-physics.html | 1889 +++++++++++ .../3-15-00-quantum-computing.html | 1918 +++++++++++ clones/llthw.common-lisp.dev/3-16-00-nlp.html | 1882 +++++++++++ clones/llthw.common-lisp.dev/3-17-00-ai.html | 1917 +++++++++++ .../3-18-00-robotics.html | 1918 +++++++++++ .../3-19-00-space-tech.html | 1905 +++++++++++ .../3-20-00-neurotech.html | 1907 +++++++++++ .../llthw.common-lisp.dev/3-21-00-lispos.html | 1890 +++++++++++ .../3-22-00-lisp-machine.html | 1911 +++++++++++ .../3-23-00-gov-mil.html | 1940 ++++++++++++ clones/llthw.common-lisp.dev/CHANGELOG.html | 1851 +++++++++++ clones/llthw.common-lisp.dev/TODO.html | 1840 +++++++++++ .../acknowledgements.html | 1838 +++++++++++ .../fontawesome/fontawesome-webfont.eot? | Bin 0 -> 76518 bytes .../fontawesome-webfont.eot?v=4.6.3 | Bin 0 -> 76518 bytes .../fontawesome-webfont.svg?v=4.6.3 | 685 ++++ .../fontawesome-webfont.ttf?v=4.6.3 | Bin 0 -> 152796 bytes .../fontawesome-webfont.woff2?v=4.6.3 | Bin 0 -> 71896 bytes .../fontawesome-webfont.woff?v=4.6.3 | Bin 0 -> 90412 bytes .../folding-chapters.css | 22 + .../folding-chapters.js | 70 + .../fontsettings.js | 240 ++ .../gitbook-plugin-fontsettings/website.css | 291 ++ .../gitbook-plugin-highlight/website.css | 434 +++ .../gitbook-plugin-hints/plugin-hints.css | 9 + .../gitbook/gitbook-plugin-lunr/lunr.min.js | 7 + .../gitbook-plugin-lunr/search-lunr.js | 59 + .../gitbook-plugin-search/search-engine.js | 50 + .../gitbook/gitbook-plugin-search/search.css | 35 + .../gitbook/gitbook-plugin-search/search.js | 213 ++ .../gitbook/gitbook-plugin-sharing/buttons.js | 90 + .../llthw.common-lisp.dev/gitbook/gitbook.js | 4 + .../apple-touch-icon-precomposed-152.png | Bin 0 -> 4817 bytes .../gitbook/images/favicon.ico | Bin 0 -> 4286 bytes .../llthw.common-lisp.dev/gitbook/style.css | 9 + clones/llthw.common-lisp.dev/gitbook/theme.js | 4 + clones/llthw.common-lisp.dev/index.html | 1882 +++++++++++ .../llthw.common-lisp.dev/introduction.html | 1853 +++++++++++ .../preface-part-three.html | 1859 +++++++++++ .../preface-part-two.html | 1864 +++++++++++ clones/llthw.common-lisp.dev/preface.html | 1838 +++++++++++ 587 files changed, 278375 insertions(+), 2 deletions(-) create mode 100644 clones/clojure-doc.org/articles/about/index.html create mode 100644 clones/clojure-doc.org/articles/content/index.html create mode 100644 clones/clojure-doc.org/articles/cookbooks/data_structures/index.html create mode 100644 clones/clojure-doc.org/articles/cookbooks/date_and_time/index.html create mode 100644 clones/clojure-doc.org/articles/cookbooks/files_and_directories/index.html create mode 100644 clones/clojure-doc.org/articles/cookbooks/math/index.html create mode 100644 clones/clojure-doc.org/articles/cookbooks/middleware/index.html create mode 100644 clones/clojure-doc.org/articles/cookbooks/strings/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/books/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/community/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/filters/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/function_types/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/home/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/limitations/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/loops/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/mm_protocol_datatypes/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/poly_fn/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/rationale/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/start/annotations/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/start/introduction_and_motivation/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/types/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/core_typed/user_documentation/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/data_processing/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/generating_documentation/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/home.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/home/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/libraries_authoring/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/libraries_directory/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/maven/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/running_cljug/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/user_groups/index.html create mode 100644 clones/clojure-doc.org/articles/ecosystem/web_development/index.html create mode 100644 clones/clojure-doc.org/articles/language/collections_and_sequences/index.html create mode 100644 clones/clojure-doc.org/articles/language/concurrency_and_parallelism/index.html create mode 100644 clones/clojure-doc.org/articles/language/core_overview/index.html create mode 100644 clones/clojure-doc.org/articles/language/functions/index.html create mode 100644 clones/clojure-doc.org/articles/language/glossary/index.html create mode 100644 clones/clojure-doc.org/articles/language/interop/index.html create mode 100644 clones/clojure-doc.org/articles/language/laziness/index.html create mode 100644 clones/clojure-doc.org/articles/language/macros/index.html create mode 100644 clones/clojure-doc.org/articles/language/namespaces/index.html create mode 100644 clones/clojure-doc.org/articles/language/polymorphism/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/basic_web_development/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/eclipse/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/emacs/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/getting_started/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/growing_a_dsl_with_clojure/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/introduction/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/parsing_xml_with_zippers/index.html create mode 100644 clones/clojure-doc.org/articles/tutorials/vim_fireplace/index.html create mode 100644 clones/clojure-doc.org/css/screen.css create mode 100644 clones/clojure-doc.org/index.html create mode 100644 clones/clojure-doc.org/js/highlight.pack.js create mode 100644 clones/docs.racket-lang.org/reference/Building_New_Contract_Combinators.html create mode 100644 clones/docs.racket-lang.org/reference/Byte_and_String_Input.html create mode 100644 clones/docs.racket-lang.org/reference/Byte_and_String_Output.html create mode 100644 clones/docs.racket-lang.org/reference/Command-Line_Parsing.html create mode 100644 clones/docs.racket-lang.org/reference/Delayed_Evaluation.html create mode 100644 clones/docs.racket-lang.org/reference/Equality.html create mode 100644 clones/docs.racket-lang.org/reference/Exiting.html create mode 100644 clones/docs.racket-lang.org/reference/Expanding_Top-Level_Forms.html create mode 100644 clones/docs.racket-lang.org/reference/Filesystem.html create mode 100644 clones/docs.racket-lang.org/reference/Generating_A_Unit_from_Context.html create mode 100644 clones/docs.racket-lang.org/reference/Generators.html create mode 100644 clones/docs.racket-lang.org/reference/Interactive_Help.html create mode 100644 clones/docs.racket-lang.org/reference/Kernel_Forms_and_Functions.html create mode 100644 clones/docs.racket-lang.org/reference/Lazy_Data-structure_Contracts.html create mode 100644 clones/docs.racket-lang.org/reference/Legacy_Contracts.html create mode 100644 clones/docs.racket-lang.org/reference/Locations____variable-reference.html create mode 100644 clones/docs.racket-lang.org/reference/Macros.html create mode 100644 clones/docs.racket-lang.org/reference/Manipulating_Paths.html create mode 100644 clones/docs.racket-lang.org/reference/Module_Names_and_Loading.html create mode 100644 clones/docs.racket-lang.org/reference/More_Path_Utilities.html create mode 100644 clones/docs.racket-lang.org/reference/Namespaces.html create mode 100644 clones/docs.racket-lang.org/reference/Object_and_Class_Contracts.html create mode 100644 clones/docs.racket-lang.org/reference/Printer_Extension.html create mode 100644 clones/docs.racket-lang.org/reference/Random_generation.html create mode 100644 clones/docs.racket-lang.org/reference/Reader_Extension.html create mode 100644 clones/docs.racket-lang.org/reference/Reading.html create mode 100644 clones/docs.racket-lang.org/reference/Sandboxed_Evaluation.html create mode 100644 clones/docs.racket-lang.org/reference/Serializing_Syntax.html create mode 100644 clones/docs.racket-lang.org/reference/Single-Signature_Modules.html create mode 100644 clones/docs.racket-lang.org/reference/Structural_Matching.html create mode 100644 clones/docs.racket-lang.org/reference/Structure_Type_Property_Contracts.html create mode 100644 clones/docs.racket-lang.org/reference/Surrogates.html create mode 100644 clones/docs.racket-lang.org/reference/Syntax_Quoting__quote-syntax.html create mode 100644 clones/docs.racket-lang.org/reference/Transformer_Helpers.html create mode 100644 clones/docs.racket-lang.org/reference/Unit_Utilities.html create mode 100644 clones/docs.racket-lang.org/reference/Writing.html create mode 100644 clones/docs.racket-lang.org/reference/__expression.html create mode 100644 clones/docs.racket-lang.org/reference/__top-interaction.html create mode 100644 clones/docs.racket-lang.org/reference/__top.html create mode 100644 clones/docs.racket-lang.org/reference/all-sync.html create mode 100644 clones/docs.racket-lang.org/reference/application.html create mode 100644 clones/docs.racket-lang.org/reference/async-channel.html create mode 100644 clones/docs.racket-lang.org/reference/attaching-contracts-to-values.html create mode 100644 clones/docs.racket-lang.org/reference/begin.html create mode 100644 clones/docs.racket-lang.org/reference/block.html create mode 100644 clones/docs.racket-lang.org/reference/booleans.html create mode 100644 clones/docs.racket-lang.org/reference/boxes.html create mode 100644 clones/docs.racket-lang.org/reference/breakhandler.html create mode 100644 clones/docs.racket-lang.org/reference/bytestrings.html create mode 100644 clones/docs.racket-lang.org/reference/case.html create mode 100644 clones/docs.racket-lang.org/reference/channel.html create mode 100644 clones/docs.racket-lang.org/reference/chaperones.html create mode 100644 clones/docs.racket-lang.org/reference/characters.html create mode 100644 clones/docs.racket-lang.org/reference/collapsible.html create mode 100644 clones/docs.racket-lang.org/reference/collects.html create mode 100644 clones/docs.racket-lang.org/reference/compiler.html create mode 100644 clones/docs.racket-lang.org/reference/compoundunits.html create mode 100644 clones/docs.racket-lang.org/reference/concurrency.html create mode 100644 clones/docs.racket-lang.org/reference/cont.html create mode 100644 clones/docs.racket-lang.org/reference/contmarks.html create mode 100644 clones/docs.racket-lang.org/reference/contract-utilities.html create mode 100644 clones/docs.racket-lang.org/reference/contracts.html create mode 100644 clones/docs.racket-lang.org/reference/control.html create mode 100644 clones/docs.racket-lang.org/reference/createclass.html create mode 100644 clones/docs.racket-lang.org/reference/createinterface.html create mode 100644 clones/docs.racket-lang.org/reference/creatingmorestructs.html create mode 100644 clones/docs.racket-lang.org/reference/creatingunits.html create mode 100644 clones/docs.racket-lang.org/reference/custodians.html create mode 100644 clones/docs.racket-lang.org/reference/customport.html create mode 100644 clones/docs.racket-lang.org/reference/data-structure-contracts.html create mode 100644 clones/docs.racket-lang.org/reference/data.html create mode 100644 clones/docs.racket-lang.org/reference/debugging.html create mode 100644 clones/docs.racket-lang.org/reference/define-sig-form.html create mode 100644 clones/docs.racket-lang.org/reference/define-struct.html create mode 100644 clones/docs.racket-lang.org/reference/define.html create mode 100644 clones/docs.racket-lang.org/reference/dicts.html create mode 100644 clones/docs.racket-lang.org/reference/doc-bibliography.html create mode 100644 clones/docs.racket-lang.org/reference/doc-index.html create mode 100644 clones/docs.racket-lang.org/reference/encodings.html create mode 100644 clones/docs.racket-lang.org/reference/engine.html create mode 100644 clones/docs.racket-lang.org/reference/envvars.html create mode 100644 clones/docs.racket-lang.org/reference/ephemerons.html create mode 100644 clones/docs.racket-lang.org/reference/eval-model.html create mode 100644 clones/docs.racket-lang.org/reference/eval.html create mode 100644 clones/docs.racket-lang.org/reference/exns.html create mode 100644 clones/docs.racket-lang.org/reference/extflonums.html create mode 100644 clones/docs.racket-lang.org/reference/extras.css create mode 100644 clones/docs.racket-lang.org/reference/fasl.html create mode 100644 clones/docs.racket-lang.org/reference/file-ports.html create mode 100644 clones/docs.racket-lang.org/reference/finger.png create mode 100644 clones/docs.racket-lang.org/reference/fixnums.html create mode 100644 clones/docs.racket-lang.org/reference/flonums.html create mode 100644 clones/docs.racket-lang.org/reference/for.html create mode 100644 clones/docs.racket-lang.org/reference/function-contracts.html create mode 100644 clones/docs.racket-lang.org/reference/futures.html create mode 100644 clones/docs.racket-lang.org/reference/garbagecollection.html create mode 100644 clones/docs.racket-lang.org/reference/generic-numbers.html create mode 100644 clones/docs.racket-lang.org/reference/hashtables.html create mode 100644 clones/docs.racket-lang.org/reference/icons.css create mode 100644 clones/docs.racket-lang.org/reference/if.html create mode 100644 clones/docs.racket-lang.org/reference/implementations.html create mode 100644 clones/docs.racket-lang.org/reference/include.html create mode 100644 clones/docs.racket-lang.org/reference/index.html create mode 100644 clones/docs.racket-lang.org/reference/input-and-output.html create mode 100644 clones/docs.racket-lang.org/reference/inspectors.html create mode 100644 clones/docs.racket-lang.org/reference/interaction-info.html create mode 100644 clones/docs.racket-lang.org/reference/interactive.html create mode 100644 clones/docs.racket-lang.org/reference/invokingunits.html create mode 100644 clones/docs.racket-lang.org/reference/ivaraccess.html create mode 100644 clones/docs.racket-lang.org/reference/keywords.html create mode 100644 clones/docs.racket-lang.org/reference/lambda.html create mode 100644 clones/docs.racket-lang.org/reference/lazy-require.html create mode 100644 clones/docs.racket-lang.org/reference/let.html create mode 100644 clones/docs.racket-lang.org/reference/linecol.html create mode 100644 clones/docs.racket-lang.org/reference/linkinference.html create mode 100644 clones/docs.racket-lang.org/reference/linklets.html create mode 100644 clones/docs.racket-lang.org/reference/load-lang.html create mode 100644 clones/docs.racket-lang.org/reference/local.html create mode 100644 clones/docs.racket-lang.org/reference/logging.html create mode 100644 clones/docs.racket-lang.org/reference/magnify.png create mode 100644 clones/docs.racket-lang.org/reference/match.html create mode 100644 clones/docs.racket-lang.org/reference/memory-order.html create mode 100644 clones/docs.racket-lang.org/reference/memory.html create mode 100644 clones/docs.racket-lang.org/reference/mixins.html create mode 100644 clones/docs.racket-lang.org/reference/model.html create mode 100644 clones/docs.racket-lang.org/reference/modprotect.html create mode 100644 clones/docs.racket-lang.org/reference/module.html create mode 100644 clones/docs.racket-lang.org/reference/mpairs.html create mode 100644 clones/docs.racket-lang.org/reference/mzlib_class.html create mode 100644 clones/docs.racket-lang.org/reference/mzlib_unit.html create mode 100644 clones/docs.racket-lang.org/reference/networking.html create mode 100644 clones/docs.racket-lang.org/reference/notation.html create mode 100644 clones/docs.racket-lang.org/reference/number-types.html create mode 100644 clones/docs.racket-lang.org/reference/numbers.html create mode 100644 clones/docs.racket-lang.org/reference/objcreation.html create mode 100644 clones/docs.racket-lang.org/reference/objectequality.html create mode 100644 clones/docs.racket-lang.org/reference/objectprinting.html create mode 100644 clones/docs.racket-lang.org/reference/objectserialize.html create mode 100644 clones/docs.racket-lang.org/reference/objectutils.html create mode 100644 clones/docs.racket-lang.org/reference/os-lib.html create mode 100644 clones/docs.racket-lang.org/reference/os.html create mode 100644 clones/docs.racket-lang.org/reference/pairs.html create mode 100644 clones/docs.racket-lang.org/reference/parameters.html create mode 100644 clones/docs.racket-lang.org/reference/parametric-contracts.html create mode 100644 clones/docs.racket-lang.org/reference/pathutils.html create mode 100644 clones/docs.racket-lang.org/reference/performance-hint.html create mode 100644 clones/docs.racket-lang.org/reference/phantom-bytes.html create mode 100644 clones/docs.racket-lang.org/reference/phase_space.html create mode 100644 clones/docs.racket-lang.org/reference/pipeports.html create mode 100644 clones/docs.racket-lang.org/reference/places.html create mode 100644 clones/docs.racket-lang.org/reference/plumbers.html create mode 100644 clones/docs.racket-lang.org/reference/port-buffers.html create mode 100644 clones/docs.racket-lang.org/reference/port-lib.html create mode 100644 clones/docs.racket-lang.org/reference/port-ops.html create mode 100644 clones/docs.racket-lang.org/reference/ports.html create mode 100644 clones/docs.racket-lang.org/reference/portstructs.html create mode 100644 clones/docs.racket-lang.org/reference/pretty-print.html create mode 100644 clones/docs.racket-lang.org/reference/printing.html create mode 100644 clones/docs.racket-lang.org/reference/procedures.html create mode 100644 clones/docs.racket-lang.org/reference/quasiquote.html create mode 100644 clones/docs.racket-lang.org/reference/quote.html create mode 100644 clones/docs.racket-lang.org/reference/racket_contract_base.html create mode 100644 clones/docs.racket-lang.org/reference/reader-procs.html create mode 100644 clones/docs.racket-lang.org/reference/reader.html create mode 100644 clones/docs.racket-lang.org/reference/readtables.html create mode 100644 clones/docs.racket-lang.org/reference/regexp.html create mode 100644 clones/docs.racket-lang.org/reference/repl-module.html create mode 100644 clones/docs.racket-lang.org/reference/require.html create mode 100644 clones/docs.racket-lang.org/reference/running-sa.html create mode 100644 clones/docs.racket-lang.org/reference/running.html create mode 100644 clones/docs.racket-lang.org/reference/runtime.html create mode 100644 clones/docs.racket-lang.org/reference/security.html create mode 100644 clones/docs.racket-lang.org/reference/securityguards.html create mode 100644 clones/docs.racket-lang.org/reference/semaphore.html create mode 100644 clones/docs.racket-lang.org/reference/sequences.html create mode 100644 clones/docs.racket-lang.org/reference/sequences_streams.html create mode 100644 clones/docs.racket-lang.org/reference/serialization.html create mode 100644 clones/docs.racket-lang.org/reference/set_.html create mode 100644 clones/docs.racket-lang.org/reference/sets.html create mode 100644 clones/docs.racket-lang.org/reference/sha.html create mode 100644 clones/docs.racket-lang.org/reference/shared.html create mode 100644 clones/docs.racket-lang.org/reference/single-unit.html create mode 100644 clones/docs.racket-lang.org/reference/special-comments.html create mode 100644 clones/docs.racket-lang.org/reference/splicing.html create mode 100644 clones/docs.racket-lang.org/reference/stencil_vectors.html create mode 100644 clones/docs.racket-lang.org/reference/stratified-body.html create mode 100644 clones/docs.racket-lang.org/reference/streams.html create mode 100644 clones/docs.racket-lang.org/reference/stringport.html create mode 100644 clones/docs.racket-lang.org/reference/strings.html create mode 100644 clones/docs.racket-lang.org/reference/struct-copy.html create mode 100644 clones/docs.racket-lang.org/reference/struct-generics.html create mode 100644 clones/docs.racket-lang.org/reference/structinfo.html create mode 100644 clones/docs.racket-lang.org/reference/structprops.html create mode 100644 clones/docs.racket-lang.org/reference/structures.html create mode 100644 clones/docs.racket-lang.org/reference/structutils.html create mode 100644 clones/docs.racket-lang.org/reference/stx-patterns.html create mode 100644 clones/docs.racket-lang.org/reference/stxcerts.html create mode 100644 clones/docs.racket-lang.org/reference/stxcmp.html create mode 100644 clones/docs.racket-lang.org/reference/stxops.html create mode 100644 clones/docs.racket-lang.org/reference/stxparam.html create mode 100644 clones/docs.racket-lang.org/reference/stxprops.html create mode 100644 clones/docs.racket-lang.org/reference/stxtrans.html create mode 100644 clones/docs.racket-lang.org/reference/subprocess.html create mode 100644 clones/docs.racket-lang.org/reference/symbols.html create mode 100644 clones/docs.racket-lang.org/reference/sync.html create mode 100644 clones/docs.racket-lang.org/reference/syntax-model.html create mode 100644 clones/docs.racket-lang.org/reference/syntax-util.html create mode 100644 clones/docs.racket-lang.org/reference/syntax.html create mode 100644 clones/docs.racket-lang.org/reference/tcp.html create mode 100644 clones/docs.racket-lang.org/reference/thread-local-storage.html create mode 100644 clones/docs.racket-lang.org/reference/threadcells.html create mode 100644 clones/docs.racket-lang.org/reference/threadgroups.html create mode 100644 clones/docs.racket-lang.org/reference/threads.html create mode 100644 clones/docs.racket-lang.org/reference/time.html create mode 100644 clones/docs.racket-lang.org/reference/trait.html create mode 100644 clones/docs.racket-lang.org/reference/udp.html create mode 100644 clones/docs.racket-lang.org/reference/undefined.html create mode 100644 clones/docs.racket-lang.org/reference/unitcontracts.html create mode 100644 clones/docs.racket-lang.org/reference/unixpaths.html create mode 100644 clones/docs.racket-lang.org/reference/unreachable.html create mode 100644 clones/docs.racket-lang.org/reference/unsafe.html create mode 100644 clones/docs.racket-lang.org/reference/values.html create mode 100644 clones/docs.racket-lang.org/reference/vectors.html create mode 100644 clones/docs.racket-lang.org/reference/void.html create mode 100644 clones/docs.racket-lang.org/reference/wcm.html create mode 100644 clones/docs.racket-lang.org/reference/weakbox.html create mode 100644 clones/docs.racket-lang.org/reference/when_unless.html create mode 100644 clones/docs.racket-lang.org/reference/willexecutor.html create mode 100644 clones/docs.racket-lang.org/reference/windowspaths.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/doc-site.css create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/doc-site.js create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/An_Extended_Example.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Backtracking.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Building_New_Contracts.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Contracts_for_Units.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Emacs.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Invoking_Units.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Linking_Units.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Lists__Iteration__and_Recursion.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Looking_Ahead_and_Behind.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Module_Syntax.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/More_Libraries.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Pairs__Lists__and_Racket_Syntax.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Signatures_and_Units.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Simple_Values.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Sublime_Text.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Vim.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Visual_Studio_Code.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/Whole-module_Signatures_and_Units.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/application.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/begin.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/binding.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/booleans.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/boxes.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/bytestrings.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/case.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/characters.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/classes.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/cmdline-tools.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/code-inspectors_protect.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/concurrency.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/conditionals.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contract-boundaries.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contract-func.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-examples.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-exists.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-first.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-general-functions.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-gotchas.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-struct.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/contracts.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/control.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/conts.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/datatypes.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/default-ports.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/define-struct.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/define.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/dialects.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/doc-bibliography.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/doc-index.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/encodings.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/eval.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/exe.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/exns.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/figure.css create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/figure.js create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/finger.png create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/firstclassunits.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/for.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_reader.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_syntax.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/hash-languages.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/hash-reader.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/hash-tables.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/i_o.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/icons.css create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/index.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/intro.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/io-patterns.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/keywords.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/lambda.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/language-collection.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/language-get-info.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/languages.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/let.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/load.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/macro-module.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/macro-transformers.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/macros.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/magnify.png create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/match.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/mk-namespace.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-basics.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-languages.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-macro.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-paths.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-provide.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-require.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-runtime-config.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/module-set.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/modules.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/more-hash-lang.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/numbers.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/other-editors.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/pairs.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/parallelism.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/parameterize.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/pattern-macros.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/performance.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/phases.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/pict.png create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/pict_2.png create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/pict_3.png create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/pict_4.png create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/pict_5.png create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/ports.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/proc-macros.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/prompt.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/protect-out.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/qq.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/quote.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/racket.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/read-write.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/reflection.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-alternation.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-assert.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-chars.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-clusters.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-intro.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-match.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-quant.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/regexp.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/running.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/scheme-forms.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/scripts.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/serialization.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/set_.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/standards.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/strings.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/stx-certs.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/stx-obj.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/stx-phases.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/symbols.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-case.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-notation.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-overview.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/syntax_module-reader.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/teaching-langs.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/to-scheme.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/unit_versus_module.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/units.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/vectors.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/void_undefined.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/guide/with-syntax.html create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/local-redirect/local-redirect.js create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/local-redirect/local-user-redirect.js create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/manual-fonts.css create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/manual-racket.css create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/manual-racket.js create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/manual-style.css create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/racket.css create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/scribble-common.js create mode 100644 clones/download.racket-lang.org/releases/8.6/doc/scribble.css create mode 100644 clones/download.racket-lang.org/robots.txt create mode 100644 clones/llthw.common-lisp.dev/1-0-0-overview.html create mode 100644 clones/llthw.common-lisp.dev/1-01-00-lisp-bootcamp.html create mode 100644 clones/llthw.common-lisp.dev/1-01-01-syntax-overview.html create mode 100644 clones/llthw.common-lisp.dev/1-01-02-repl.html create mode 100644 clones/llthw.common-lisp.dev/1-01-03-expressions.html create mode 100644 clones/llthw.common-lisp.dev/1-01-04-lists-cons-cells.html create mode 100644 clones/llthw.common-lisp.dev/1-01-05-symbols.html create mode 100644 clones/llthw.common-lisp.dev/1-01-06-prefix-notation.html create mode 100644 clones/llthw.common-lisp.dev/1-01-07-style-guide.html create mode 100644 clones/llthw.common-lisp.dev/1-01-08-configuration.html create mode 100644 clones/llthw.common-lisp.dev/1-02-00-input-output.html create mode 100644 clones/llthw.common-lisp.dev/1-02-01-strings.html create mode 100644 clones/llthw.common-lisp.dev/1-02-02-more-strings.html create mode 100644 clones/llthw.common-lisp.dev/1-02-03-unicode.html create mode 100644 clones/llthw.common-lisp.dev/1-02-04-chars.html create mode 100644 clones/llthw.common-lisp.dev/1-02-05-more-chars.html create mode 100644 clones/llthw.common-lisp.dev/1-02-06-char-codes.html create mode 100644 clones/llthw.common-lisp.dev/1-02-07-strings-from-chars.html create mode 100644 clones/llthw.common-lisp.dev/1-02-08-printing.html create mode 100644 clones/llthw.common-lisp.dev/1-02-09-more-printing.html create mode 100644 clones/llthw.common-lisp.dev/1-02-10-prin1.html create mode 100644 clones/llthw.common-lisp.dev/1-02-11-princ.html create mode 100644 clones/llthw.common-lisp.dev/1-02-12-format.html create mode 100644 clones/llthw.common-lisp.dev/1-02-13-more-format.html create mode 100644 clones/llthw.common-lisp.dev/1-02-14-pathnames.html create mode 100644 clones/llthw.common-lisp.dev/1-02-15-streams.html create mode 100644 clones/llthw.common-lisp.dev/1-02-16-file-streams.html create mode 100644 clones/llthw.common-lisp.dev/1-02-17-binary-streams.html create mode 100644 clones/llthw.common-lisp.dev/1-02-18-prompting-users.html create mode 100644 clones/llthw.common-lisp.dev/1-02-19-pretty-printing.html create mode 100644 clones/llthw.common-lisp.dev/1-03-0-getting-input-from-users.html create mode 100644 clones/llthw.common-lisp.dev/1-04-0-lists.html create mode 100644 clones/llthw.common-lisp.dev/1-05-0-lookups-trees.html create mode 100644 clones/llthw.common-lisp.dev/1-06-0-math.html create mode 100644 clones/llthw.common-lisp.dev/1-06-01-integers.html create mode 100644 clones/llthw.common-lisp.dev/1-06-02-more-integers.html create mode 100644 clones/llthw.common-lisp.dev/1-06-03-hexadecimal-notation.html create mode 100644 clones/llthw.common-lisp.dev/1-06-04-octal-notation.html create mode 100644 clones/llthw.common-lisp.dev/1-06-05-binary-notation.html create mode 100644 clones/llthw.common-lisp.dev/1-06-06-ratios.html create mode 100644 clones/llthw.common-lisp.dev/1-06-07-floating-point.html create mode 100644 clones/llthw.common-lisp.dev/1-06-08-constants.html create mode 100644 clones/llthw.common-lisp.dev/1-06-09-complex-numbers.html create mode 100644 clones/llthw.common-lisp.dev/1-06-10-arithmetic.html create mode 100644 clones/llthw.common-lisp.dev/1-06-11-more-arithmetic.html create mode 100644 clones/llthw.common-lisp.dev/1-06-12-even-more-arithmetic.html create mode 100644 clones/llthw.common-lisp.dev/1-06-13-exponents.html create mode 100644 clones/llthw.common-lisp.dev/1-06-14-logarithms.html create mode 100644 clones/llthw.common-lisp.dev/1-06-15-trigonometry.html create mode 100644 clones/llthw.common-lisp.dev/1-06-16-psuedorandom-numbers.html create mode 100644 clones/llthw.common-lisp.dev/1-07-0-arrays.html create mode 100644 clones/llthw.common-lisp.dev/1-08-0-variables.html create mode 100644 clones/llthw.common-lisp.dev/1-09-0-closures.html create mode 100644 clones/llthw.common-lisp.dev/1-10-0-functions.html create mode 100644 clones/llthw.common-lisp.dev/1-11-0-text-adventure.html create mode 100644 clones/llthw.common-lisp.dev/1-12-0-namespaces.html create mode 100644 clones/llthw.common-lisp.dev/1-13-0-simple-web-app.html create mode 100644 clones/llthw.common-lisp.dev/1-14-0-conditionals.html create mode 100644 clones/llthw.common-lisp.dev/1-15-0-command-line-utility.html create mode 100644 clones/llthw.common-lisp.dev/1-16-0-map-loop.html create mode 100644 clones/llthw.common-lisp.dev/1-17-0-iterate.html create mode 100644 clones/llthw.common-lisp.dev/1-18-0-format.html create mode 100644 clones/llthw.common-lisp.dev/1-19-0-dsl.html create mode 100644 clones/llthw.common-lisp.dev/1-20-0-review.html create mode 100644 clones/llthw.common-lisp.dev/2-0-0-overview.html create mode 100644 clones/llthw.common-lisp.dev/2-01-0-programming-paradigms.html create mode 100644 clones/llthw.common-lisp.dev/2-02-0-regex.html create mode 100644 clones/llthw.common-lisp.dev/2-03-0-objects-control.html create mode 100644 clones/llthw.common-lisp.dev/2-04-0-data-persistence.html create mode 100644 clones/llthw.common-lisp.dev/2-05-0-extended-types.html create mode 100644 clones/llthw.common-lisp.dev/2-06-0-threads-memos-parallel.html create mode 100644 clones/llthw.common-lisp.dev/2-07-0-logic-and-more-math.html create mode 100644 clones/llthw.common-lisp.dev/2-08-0-number-theory.html create mode 100644 clones/llthw.common-lisp.dev/2-09-0-binary-octets-bits.html create mode 100644 clones/llthw.common-lisp.dev/2-10-0-improved-text-adventure-engine.html create mode 100644 clones/llthw.common-lisp.dev/2-11-0-conditions.html create mode 100644 clones/llthw.common-lisp.dev/2-12-0-2d-game.html create mode 100644 clones/llthw.common-lisp.dev/2-13-0-compiler.html create mode 100644 clones/llthw.common-lisp.dev/2-14-0-tree-shaker.html create mode 100644 clones/llthw.common-lisp.dev/2-15-0-docs-and-inspection.html create mode 100644 clones/llthw.common-lisp.dev/2-16-0-foreign-libs.html create mode 100644 clones/llthw.common-lisp.dev/2-17-0-debugging-testing.html create mode 100644 clones/llthw.common-lisp.dev/2-18-0-ffi.html create mode 100644 clones/llthw.common-lisp.dev/2-19-0-essential-libs.html create mode 100644 clones/llthw.common-lisp.dev/2-20-0-packaging-libs.html create mode 100644 clones/llthw.common-lisp.dev/2-21-0-review.html create mode 100644 clones/llthw.common-lisp.dev/3-00-00-overview.html create mode 100644 clones/llthw.common-lisp.dev/3-01-00-web-apps.html create mode 100644 clones/llthw.common-lisp.dev/3-02-00-typesetting.html create mode 100644 clones/llthw.common-lisp.dev/3-03-00-mobile.html create mode 100644 clones/llthw.common-lisp.dev/3-04-00-gui.html create mode 100644 clones/llthw.common-lisp.dev/3-05-00-system-utils.html create mode 100644 clones/llthw.common-lisp.dev/3-06-00-reverse-engineering.html create mode 100644 clones/llthw.common-lisp.dev/3-07-00-graphics.html create mode 100644 clones/llthw.common-lisp.dev/3-08-00-gaming.html create mode 100644 clones/llthw.common-lisp.dev/3-09-00-audio.html create mode 100644 clones/llthw.common-lisp.dev/3-10-00-data.html create mode 100644 clones/llthw.common-lisp.dev/3-11-00-cryptosec.html create mode 100644 clones/llthw.common-lisp.dev/3-12-00-fintech.html create mode 100644 clones/llthw.common-lisp.dev/3-13-00-scientific-computing.html create mode 100644 clones/llthw.common-lisp.dev/3-14-00-computational-physics.html create mode 100644 clones/llthw.common-lisp.dev/3-15-00-quantum-computing.html create mode 100644 clones/llthw.common-lisp.dev/3-16-00-nlp.html create mode 100644 clones/llthw.common-lisp.dev/3-17-00-ai.html create mode 100644 clones/llthw.common-lisp.dev/3-18-00-robotics.html create mode 100644 clones/llthw.common-lisp.dev/3-19-00-space-tech.html create mode 100644 clones/llthw.common-lisp.dev/3-20-00-neurotech.html create mode 100644 clones/llthw.common-lisp.dev/3-21-00-lispos.html create mode 100644 clones/llthw.common-lisp.dev/3-22-00-lisp-machine.html create mode 100644 clones/llthw.common-lisp.dev/3-23-00-gov-mil.html create mode 100644 clones/llthw.common-lisp.dev/CHANGELOG.html create mode 100644 clones/llthw.common-lisp.dev/TODO.html create mode 100644 clones/llthw.common-lisp.dev/acknowledgements.html create mode 100644 clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.eot? create mode 100644 clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.eot?v=4.6.3 create mode 100644 clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.svg?v=4.6.3 create mode 100644 clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.ttf?v=4.6.3 create mode 100644 clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.woff2?v=4.6.3 create mode 100644 clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.woff?v=4.6.3 create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.css create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/fontsettings.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/website.css create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-highlight/website.css create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-hints/plugin-hints.css create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-lunr/lunr.min.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-lunr/search-lunr.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-search/search-engine.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-search/search.css create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-search/search.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-sharing/buttons.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/gitbook.js create mode 100644 clones/llthw.common-lisp.dev/gitbook/images/apple-touch-icon-precomposed-152.png create mode 100644 clones/llthw.common-lisp.dev/gitbook/images/favicon.ico create mode 100644 clones/llthw.common-lisp.dev/gitbook/style.css create mode 100644 clones/llthw.common-lisp.dev/gitbook/theme.js create mode 100644 clones/llthw.common-lisp.dev/index.html create mode 100644 clones/llthw.common-lisp.dev/introduction.html create mode 100644 clones/llthw.common-lisp.dev/preface-part-three.html create mode 100644 clones/llthw.common-lisp.dev/preface-part-two.html create mode 100644 clones/llthw.common-lisp.dev/preface.html diff --git a/clones/clojure-doc.org/articles/about/index.html b/clones/clojure-doc.org/articles/about/index.html new file mode 100644 index 00000000..5b0b2c28 --- /dev/null +++ b/clones/clojure-doc.org/articles/about/index.html @@ -0,0 +1,216 @@ + + + + + Clojure Guides: About + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

CDS (Clojure Documentation Site) is a community documentation project for the Clojure programming language. It is not affiliated with +Clojure/core, does not require going through the Clojure Contributor Agreement, and is developed on GitHub.

Rationale

The rationale is explained in more detail in the announcement blog post.

History

CDS was started in early October, 2012, by several active members of the Clojure community due to their dissatisfaction +with the state of documentation and documentation contribution process (that involved mailing Clojure Contributor Agreement in paper).

Goals

The goal is to produce quality technical documentation for Clojure users and potential adopters with various expertise levels.

CDS strives to cover all aspects of Clojure: from tutorials and language guides to overview of the ecosystem, how +libraries are developed and published, topics operations engineers will be interested in, JVM ecosystem tools +and so on.

Adopting a language always takes more than just reading a book or a few tutorials about language features. Understanding +design goals, the ecosystem and operations is just as important. CDS will try to address this.

What CDS is Not

What's not here:

Clojuredocs needs a lot of work and redesign (as in, the way it works) which will take a while. CDS is not concerned with providing the API reference; +only tutorials, guides, and linking to other relevant resources.

Structure

CDS is structured as a number of guides. They broadly fall into 4 categories:

Tutorials

These guides are for complete newcomers and should include a lot of hand holding. They don't assume any +previous familiarity with Clojure, the JVM, the JVM tool ecosystem, functional programming, immutability, and so on.

Target audience: newcomers to the language.

Language guides

These guides are more in-depth, focused on various aspects of the language and interoperability. +Examples of such guides include:

  • Sequences
  • Interoperability
  • Reference types
  • Laziness
  • Macros and compilation

Target audience: from developers who already have some familiarity with the language to those who have been using it for +a while.

Tools & Ecosystem guides

These guides cover key Clojure ecosystem tools such as Leiningen, Clojars, REPLy, +nREPL, Emacs clojure-mode, VimClojure, Counterclockwise, La Clojure, etc. It also covers important ecosystem projects that are not tools: books, +ClojureSphere, ClojureWerkz, Flatland and so on.

Target audience: all developers using or interested in the Clojure programming language.

Cookbooks

Concise Clojure example code, categorized by subject.

Mailing List

CDS currently uses Clojure mailing list for discussions. Feel free to join it and ask any questions you may have.

News & Announcements

News and announcements are posted primarily on the Clojurians Slack #news-and-articles channel.

Reporting Issues

If you find a mistake, poor grammar, an important topic not covered, or an outdated example, please file an issue on Github.

Contributing

CDS uses Cryogen. All tutorials and guides are written in Markdown.

The toolchain and setup process are described in the README.

To submit changes, create a branch and make your changes on it. Once you are done with your changes and all tests pass, submit a pull request +on GitHub.

+ +
+ + + + Table of Contents » + +
+
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/content/index.html b/clones/clojure-doc.org/articles/content/index.html new file mode 100644 index 00000000..a4a0ba92 --- /dev/null +++ b/clones/clojure-doc.org/articles/content/index.html @@ -0,0 +1,225 @@ + + + + + Clojure Guides: Table of Contents + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

The content is a categorized and +manifold collection of documentation guides for the Clojure programming language and +its ecosystem.

We recognize that different Clojure users have different level of expertise +and separates content into several groups:

Essentials

Note that the editing environments are listed in alphabetical order and indicate no preference or endorsement. The last +"State of the Union" Clojure survey indicated +that Emacs is still the most popular editing environment, followed by IntelliJ/Cursive, VS Code, Vim, and Atom.

Getting Started

If you're new to Clojure, this is a good place to start.

Introduction

A swift introduction to the Clojure language, covering most of the +basics.

Atom for Clojure Development

The Chlorine package for Clojure development in Atom (via a Socket REPL).

IntelliJ / Cursive for Clojure Development

The user guide for Cursive, the Clojure plugin for IntelliJ.

Eclipse for Clojure Development

A brief introduction to Counterclockwise, a Clojure plugin for Eclipse.

Emacs for Clojure Development

A brief introduction to Emacs, Clojure mode, CIDER and Clojure development workflow with Emacs.

Vim for Clojure Development

A brief introduction to Clojure development in Vim with fireplace.vim.

VS Code for Clojure Development

The Calva extension for Clojure development in VS Code (via nREPL).

See also Clover for VS Code +for Clojure development in VS Code (via a Socket REPL).

Language Guides

Functions

Functions are at the heart of Clojure.

This guide covers:

  • How to define functions
  • How to invoke functions
  • Multi-arity functions
  • Variadic functions
  • Higher order functions
  • Other topics related to functions

clojure.core Overview (incomplete)

clojure.core is the core Clojure library.

This guide covers:

  • Key functions of clojure.core
  • Key macros of clojure.core
  • Key vars of clojure.core

Interoperability with Java

The Clojure language implementation is symbiotic with its host +platform (the JVM), providing direct interoperability.

This guide covers:

  • How to instantiate Java classes
  • How to invoke Java methods
  • How to extend Java classes with proxy
  • How to implement Java interfaces with reify
  • How to generate Java classes with gen-class
  • Other topics related to interop

Namespaces

Namespaces organize Clojure functions.

This guide covers:

  • An overview of Clojure namespaces
  • How to define a namespace
  • How to use functions in other namespaces
  • require, refer and use
  • How to Look up and invoke a function by name
  • Common compilation exceptions and their causes
  • How code compilation works in Clojure

Polymorphism: Protocols and Multimethods

This guide covers:

  • What are polymorphic functions
  • Type-based polymorphism with protocols
  • Ad-hoc polymorphism with multimethods
  • How to create your own data types that behave like core Clojure data types

Collections and Sequences

This guide covers:

  • Collections in Clojure
  • Sequences in Clojure
  • Core collection types
  • Key operations on collections and sequences
  • Other topics related to collections and sequences

Concurrency & Parallelism

This guide covers:

  • An overview of concurrency hazards
  • Clojure's approach to state and identity
  • Immutable data structures
  • Reference types (atoms, vars, agents, refs)
  • Using Clojure functions with java.util.concurrent abstractions
  • The Reducers framework (Clojure 1.5+)
  • Other topics related to concurrency and runtime parallelism

Macros and Metaprogramming

This guide covers:

  • Clojure macros
  • Clojure compilation process
  • Other topics related to metaprogramming

Laziness and Lazy Sequences (incomplete)

This guide covers:

  • What are lazy sequences
  • How to create functions that produce lazy sequences
  • How to force evaluation
  • Pitfalls with lazy sequences

Glossary

This guide includes definitons of various Clojure-related terminology.

The Clojure Ecosystem

Books

This guide covers:

  • Books on Clojure
  • Books on ClojureScript

Getting Started with Leiningen

This guide covers:

  • What is Leiningen and what it can do for you
  • How to create a project with Leiningen
  • How to manage project dependencies
  • Accessing the REPL
  • How to run tests for your project
  • How to run the app
  • How to compile your code and dependencies into a single JAR for deployment ("รผberjar")
  • How to share (publish) a library

Maven for Clojure Development

This guide covers:

  • An overview of Apache Maven
  • Maven Clojure plugin

Clojure Library Directory

A curated and highly opinionated categorized directory of available Clojure libraries and tools.

Clojure Community

This guide covers:

  • Planet Clojure, mailing lists, IRC channel
  • Clojure conferences
  • Local Clojure user groups
  • Other Clojure community resources

core.typed

  • What is Clojure core.typed
  • core.typed documentation, tutorials, and guides.

java.jdbc

This guide covers:

  • An overview of Clojure's JDBC wrapper
  • Setting up a data source
  • Manipulating data with SQL
  • Manipulating tables with DDL
  • How to use connection pooling
  • How to use some common DSLs with java.jdbc
  • Where to go beyond java.jdbc

Library Development and Distribution

This guide covers:

  • Basic setup for library development
  • How to publish a library to Clojars

Leiningen Profiles

This guide covers:

  • What are Leiningen profiles
  • How to use them

Distributing Libraries with Leiningen

This guide covers:

  • How Clojure libraries are distributed
  • How to publish Clojure libraries to clojars.org
  • How to publish Clojure libraries to Maven Central
  • How to publish Clojure libraries to your own Maven repository

Writing Leiningen Plugins

This guide covers:

  • What Leiningen plugins can do
  • How to install Leiningen plugins
  • How to develop plugins
  • How to distribute plugins

Documentation Tools

  • Tools for generating documentation from docstrings and other project +metadata.

Data Processing (Overview) (TBD)

This guide covers:

  • An overview of why Clojure is an excellent choice for data processing
  • Popular tools and libraries in the area

Clojure User Groups

This guide covers:

  • Clojure User Groups (CLJUGs) around the world

Tutorials and Cookbooks

Basic Web Development

A brief tutorial/walkthrough of building a small web app using Ring, +Compojure, Hiccup, and H2.

Parsing XML in Clojure

This guide covers:

  • How to parse XML in Clojure with zippers (clojure.data.zip)

Growing a DSL with Clojure

How to create a simple DSL with Clojure.

Includes introductions to:

  • Multimethods
  • Hierarchies
  • Metaprogramming and the "Code as data" philosophy

Strings

This cookbook covers:

  • How to work with strings
  • How to work with characters
  • How to work with regular expressions
  • How to work with context-free grammars
  • How to format text

Mathematics

Includes coverage of facilities for doing math with Clojure.

Data Structures (TBD)

This cookbook covers:

  • Vectors
  • Maps
  • Lists
  • Sets
  • Generic operations on sequences

Files and Directories

This cookbook covers:

  • Reading and writing text and binary files
  • Listing directory contents
  • Creating files and directories
  • Moving files and directories
  • Removing files and directories
  • Accessing file metadata
  • Other operations on files and directories

Date and Time (TBD)

This guide covers:

  • Working with JDK dates
  • Working with Joda Time and clj-time
  • Instant literals (Clojure 1.4+)

Middleware (incomplete)

This guide covers:

  • What middleware is and how it works
  • Creating middleware for a client function
  • Combining middleware to create a new client

License

All the content is distributed under the +CC BY 3.0 license +and are copyright their respective primary author(s).

Tell Us What You Think!

Please take a moment to tell us what you think about this guide on the Clojurians Slack #clojure-doc channel or the Clojure mailing list.

Let us know what was unclear or what has not been covered. Maybe you do not like the guide style or grammar or discover spelling mistakes. +Reader feedback is key to making the documentation better.

+ +
+ + « About + + + || + + + Getting Started with Clojure » + +
+
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/cookbooks/data_structures/index.html b/clones/clojure-doc.org/articles/cookbooks/data_structures/index.html new file mode 100644 index 00000000..5cffc1cf --- /dev/null +++ b/clones/clojure-doc.org/articles/cookbooks/data_structures/index.html @@ -0,0 +1,208 @@ + + + + + Clojure Guides: Data Structures (Help wanted) + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Help wanted

Please follow the instructions on how to contribute and start writing over here

This cookbook covers working with core Clojure data structures.

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on Github.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/cookbooks/date_and_time/index.html b/clones/clojure-doc.org/articles/cookbooks/date_and_time/index.html new file mode 100644 index 00000000..fee2067e --- /dev/null +++ b/clones/clojure-doc.org/articles/cookbooks/date_and_time/index.html @@ -0,0 +1,208 @@ + + + + + Clojure Guides: Date and Time (Help wanted) + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Help wanted

Please follow the instructions on how to contribute and start writing over here

This cookbook covers working with date and time values in Clojure.

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on Github.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/cookbooks/files_and_directories/index.html b/clones/clojure-doc.org/articles/cookbooks/files_and_directories/index.html new file mode 100644 index 00000000..c9dd6589 --- /dev/null +++ b/clones/clojure-doc.org/articles/cookbooks/files_and_directories/index.html @@ -0,0 +1,252 @@ + + + + + Clojure Guides: Working with Files and Directories in Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This cookbook covers working with files and directories from Clojure, +using functions in the clojure.java.io namespace as well as parts of +the JDK via interoperability.

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

Preliminaries

Note that for the examples below, "io" is an alias for +clojure.java.io. That is, it's assumed your ns macro contains:

(:require [clojure.java.io :as io])
+

or else in the repl you've loaded it:

(require '[clojure.java.io :as io])
+

Recipes

Read a file into one long string

(def a-long-string (slurp "foo.txt"))
+

Note, you can pass urls to slurp as well. See also slurp at +Clojuredocs.

Read a file one line at a time

Suppose you'd like to call my-func on every line in a file, +and return the resulting sequence:

(with-open [rdr (io/reader "foo.txt")]
+  (doall (map my-func (line-seq rdr))))
+

The doall is needed because the map call is lazy. The lines that +line-seq gives you have no trailing newlines (and empty lines in the +file will yield empty strings ("")).

Write a long string out to a new file

(spit "foo.txt"
+      "A long
+multi-line string.
+Bye.")
+

Overwrites the file if it already exists. To append, use

(spit "foo.txt" "file content" :append true)
+

Write a file one line at a time

Suppose you'd like to write out every item in a vector, one item per +line:

(with-open [wrtr (io/writer "foo.txt")]
+  (doseq [i my-vec]
+    (.write wrtr (str i "\n"))))
+

Check if a file exists

(.exists (io/file "filename.txt"))
+

Is it a directory? :

(.isDirectory (io/file "path/to/something"))
+

An io/file is a java.io.File object (a file or a directory). You can +call a number of functions on it, including:

exists        Does the file exist?
+isDirectory   Is the File object a directory?
+getName       The basename of the file.
+getParent     The dirname of the file.
+getPath       Filename with directory.
+mkdir         Create this directory on disk.
+

To read about more available methods, see the java.io.File +docs.

Get a list of the files and dirs in a given directory

As File objects:

(.listFiles (io/file "path/to/some-dir"))
+

Same, but just the names (strings), not File objects:

(.list (io/file "path/to/some-dir"))
+

The results of those calls are seqable.

See also

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/cookbooks/math/index.html b/clones/clojure-doc.org/articles/cookbooks/math/index.html new file mode 100644 index 00000000..d0186d89 --- /dev/null +++ b/clones/clojure-doc.org/articles/cookbooks/math/index.html @@ -0,0 +1,252 @@ + + + + + Clojure Guides: Mathematics with Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This cookbook covers working with mathematics in Clojure, using +built-in functions, contrib libraries, and parts of the JDK via +interoperability.

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

Preliminaries

Some examples herein make use of the +math.numeric-tower +and +math.combinatorics +contrib libraries. It's assumed that either you have the following in +your source code's ns macro:

(:require [clojure.math.numeric-tower :as math]
+          [clojure.math.combinatorics :as combo])
+

or else in the repl you've loaded them like so:

(require '[clojure.math.numeric-tower :as math])
+(require '[clojure.math.combinatorics :as combo])
+

Recipes

Simple Math

(+ 3 4)    ;=> 7
+(- 3 4)    ;=> -1
+(* 3 4)    ;=> 12
+(/ 3 4)    ;=> 3/4  (an exact ratio)
+(/ 3.0 4)  ;=> 0.75
+
+(inc 5)    ;=> 6
+(dec 5)    ;=> 4
+

For doing integer division and getting remainders (modulus), see the +docs for +quot, +rem, and +mod.

For exponents, square roots, rounding, ceiling, floor, absolute value, +and greatest/least common multiples, see the docs for +math.numeric-tower.

Trigonometry

Use what the Java platform provides, for example:

Math/PI       ;=> 3.14159...
+(Math/sin x)
+(Math/cos x)
+(Math/tan x)
+

There are many more functions available, which you can read about in +the docs for +java.lang.Math.

Combinatorics

For combinatoric functions (such as combinations and +permutations), see the docs for +math.combinatorics.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/cookbooks/middleware/index.html b/clones/clojure-doc.org/articles/cookbooks/middleware/index.html new file mode 100644 index 00000000..2e2db724 --- /dev/null +++ b/clones/clojure-doc.org/articles/cookbooks/middleware/index.html @@ -0,0 +1,326 @@ + + + + + Clojure Guides: Middleware in Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

What is Middleware?

Middleware in Clojure is a common design pattern for threading a +request through a series of functions designed to operate on it as +well as threading the response through the same series of functions.

Middleware is used in many Clojure projects such as +Ring, +clj-http and +something else here.

The client function

The base of all middleware in Clojure is the client function, which +takes a request object (usually a Clojure map) and returns a response +object (also usually a Clojure map).

For example, let's use a client function that pulls some keys out of +a map request and does an HTTP GET on a site:

(ns middleware.example
+  (:require [clj-http.client :as http]))
+
+(defn client [request]
+  (http/get (:site request) (:options request)))
+

To use the client method, call it like so (response shortened to fit +here):

(client {:site "http://www.aoeu.com" :options {}})
+;; โ‡’ {:status 200, :headers {...}, :request-time 3057, :body "..."}
+

Now that a client function exists, middleware can be wrapped around it +to change the request, the response, or both.

Let's start with a middleware function that doesn't do anything. We'll +call it the no-op middleware:

;; It is standard convention to name middleware wrap-<something>
+(defn wrap-no-op
+  ;; the wrapping function takes a client function to be used...
+  [client-fn]
+  ;; ...and returns a function that takes a request...
+  (fn [request]
+    ;; ...that calls the client function with the request
+    (client-fn request)))
+

So how is this middleware used? First, it must be 'wrapped' around the +existing client function:

(def new-client (wrap-no-op client))
+
+;; Now new-client can be used just like the client function:
+(new-client {:site "http://www.aoeu.com" :options {}})
+;; โ‡’ {:status 200, :headers {...}, :request-time 3057, :body "..."}
+

It works! Now it's not very exiting because it doesn't do anything +yet, so let's add another middleware wrapper that does something more +exiting.

Let's add a middleware function that automatically changes all "HTTP" +requests into "HTTPS" requests. Again, we need a function that returns +another function, so we can end up with a new method to call:

(defn wrap-https
+  [client-fn]
+  (fn [request]
+    (let [site (:site request)
+          new-site (.replaceAll site "http:" "https:")
+          new-request (assoc request :site new-site)]
+      (client-fn new-request))))
+

The wrap-https middleware can be tested again by creating a new +client function:

(def https-client (wrap-https client))
+
+;; Notice the :trace-redirects key shows that HTTPS was used instead
+;; of HTTP
+(https-client {:site "http://www.google.com" :options {}})
+;; โ‡’ {:trace-redirects ["https://www.google.com"],
+;;    :status 200,
+;;    :headers {...},
+;;    :request-time 3057,
+;;    :body "..."}
+

Middleware can be tested independently of the client function by +providing the identity function (or any other function that returns a +map). For example, we can see the wrap-https middleware returns the +clojure map with the :site changed from 'http' to 'https':

((wrap-https identity) {:site "http://www.example.com"})
+;; โ‡’ {:site "https://www.example.com"}
+

Combining middleware

In the previous example, we showed how to create and use middleware, +but what about using multiple middleware functions? Let's define one +more middleware so we have a total of three to work with. Here's the +source for a middleware function that adds the current data to the +response map:

(defn wrap-add-date
+  [client]
+  (fn [request]
+    (let [response (client request)]
+      (assoc response :date (java.util.Date.)))))
+

And again, we can test it without using any other functions using +identity as the client function:

((wrap-add-date identity) {})
+;; โ‡’ {:date #inst "2012-11-09T12:41:05.171-00:00"}
+

Middleware is useful on its own, but where it becomes truly more +useful is in combining middleware together. Here's what a new client +function looks like combining all the middleware:

(def my-client (wrap-add-date (wrap-https (wrap-no-op client))))
+
+(my-client {:site "http://www.google.com"})
+;; โ‡’ {:date #inst "2012-11-09T12:43:39.451-00:00",
+;;    :cookies {...},
+;;    :trace-redirects ["https://www.google.com/"],
+;;    :request-time 1634,
+;;    :status 200,
+;;    :headers {...},
+;;    :body "..."}
+

(The response map has been edited to take less space where you see +'...')

Here we can see that the wrap-https middleware has successfully +turned the request for http://www.google.com into one for +https://www.google.com, additionally the wrap-add-date middleware +has added the :date key with the date the request happened. (the +wrap-no-op middleware did execute, but since it didn't do anything, +there's no output to tell)

This is a good start, but adding middleware can be expressed in a much +cleaner and clearer way by using Clojure's threading macro, ->. The +my-client definition from above can be expressed like this:

(def my-client
+  (-> client
+      wrap-no-op
+      wrap-https
+      wrap-add-date))
+
+(my-client {:site "http://www.google.com"})
+;; โ‡’ {:date #inst "2012-11-09T12:47:32.130-00:00",
+;;    :cookies {...},
+;;    :trace-redirects ["https://www.google.com/"],
+;;    :request-time 1630,
+;;    :status 200,
+;;    :headers {...},
+;;    :body "..."}
+

Something else to keep in mind is that middleware expressed in this +way will be executed from the bottom up, so in this case, +wrap-add-date will call wrap-https, which in turn calls +wrap-no-op, which finally calls the client function.

For an example of combining a large amount of middleware, see +clj-http's +client.clj +file

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/cookbooks/strings/index.html b/clones/clojure-doc.org/articles/cookbooks/strings/index.html new file mode 100644 index 00000000..7e952461 --- /dev/null +++ b/clones/clojure-doc.org/articles/cookbooks/strings/index.html @@ -0,0 +1,464 @@ + + + + + Clojure Guides: Strings + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This cookbook covers working with strings in Clojure using built-in +functions, standard and contrib libraries, and parts of the JDK via +interoperability.

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

Overview

  • Strings are plain Java +strings. +You can use anything which operates on them.
  • Java strings are immutable, so they're convenient to use in Clojure.
  • You can't add metadata to Java strings.
  • Clojure supports some convenient notations:
    "foo"    java.lang.String
+    #"\d"    java.util.regex.Pattern (in this case, one which matches a single digit)
+    \f       java.lang.Character (in this case, the letter 'f')
+
  • Caveat: Human brains and electronic computers are rather different +devices. So Java strings (sequences of UTF-16 +characters) +don't always map nicely to user-perceived characters. For example, a +single Unicode "code point" doesn't necessarily equal a user-perceived +character. (Like Korean Hangul Jamo, where user-perceived characters +are composed from two or three Unicode code points.) Also, a Unicode +code point may sometimes require 2 UTF-16 characters to encode it.

Preliminaries

Some examples use +clojure.string, +clojure.edn and +clojure.pprint. We'll +assume your ns macro contains:

(:require [clojure.string :as str]
+          [clojure.edn :as edn]
+          [clojure.pprint :as pp])
+

or else in the repl you've loaded it:

(require '[clojure.string :as str])
+(require '[clojure.edn :as edn])
+(require '[clojure.pprint :as pp])
+

Recipes

Basics

;; Size measurements
+(count "0123")      ;=> 4
+(empty? "0123")     ;=> false
+(empty? "")         ;=> true
+(str/blank? "    ") ;=> true
+
+;; Concatenate
+(str "foo" "bar")            ;=> "foobar"
+(str/join ["0" "1" "2"])     ;=> "012"
+(str/join "." ["0" "1" "2"]) ;=> "0.1.2"
+
+;; Matching using plain Java methods.
+;;
+;; You might prefer regexes for these. For instance, failure returns
+;; -1, which you have to test for. And characters like \o are
+;; instances of java.lang.Character, which you may have to convert to
+;; int or String.
+(.indexOf "foo" "oo")         ;=> 1
+(.indexOf "foo" "x")          ;=> -1
+(.lastIndexOf "foo" (int \o)) ;=> 2
+
+;; Substring
+(subs "0123" 1)       ;=> "123"
+(subs "0123" 1 3)     ;=> "12"
+(str/trim "  foo  ")  ;=> "foo"
+(str/triml "  foo  ") ;=> "foo  "
+(str/trimr "  foo  ") ;=> "  foo"
+
+;; Multiple substrings
+(seq "foo")                       ;=> (\f \o \o)
+(str/split "foo/bar/quux" #"/")   ;=> ["foo" "bar" "quux"]
+(str/split "foo/bar/quux" #"/" 2) ;=> ["foo" "bar/quux"]
+(str/split-lines "foo
+bar")                             ;=> ["foo" "bar"]
+
+;; Case
+(str/lower-case "fOo") ;=> "foo"
+(str/upper-case "fOo") ;=> "FOO"
+(str/capitalize "fOo") ;=> "Foo"
+
+;; Escaping
+(str/escape "foo|bar|quux" {\| "||"}) ;=> "foo||bar||quux"
+
+;; Get byte array of given encoding.
+;; (The output will likely have a different number than "3c3660".)
+(.getBytes "foo" "UTF-8") ;=> #<byte[] [B@3c3660>
+
+;; Parsing keywords
+(keyword "foo")    ;=> :foo
+
+;; Parsing numbers
+(bigint "20000000000000000000000000000") ;=> 20000000000000000000000000000N
+(bigdec "20000000000000000000.00000000") ;=> 20000000000000000000.00000000M
+(Integer/parseInt "2")                   ;=> 2
+(Float/parseFloat "2")                   ;=> 2.0
+
+;; Parsing edn, a subset of Clojure forms.
+(edn/read-string "0xffff") ;=> 65535
+
+;; The sledgehammer approach to reading Clojure forms.
+;;
+;; SECURITY WARNING: Ensure *read-eval* is false when dealing with
+;; strings you don't 100% trust. Even though *read-eval* is false by
+;; default since Clojure 1.5, be paranoid and set it to false right
+;; before you use it, because anything could've re-bound it to true.
+(binding [*read-eval* false]
+  (read-string "#\"[abc]\""))
+;=> #"[abc]"
+

Parsing complex strings

Regexes

Regexes offer a boost in string-matching power. You can express ideas +like repetition, alternatives, etc.

Regex +reference.

Groups: Regex groups are useful, when we want to match more than +one substring. (Or refer to matches later.) In the regex #"(group-1) (group-2)", the 0th group is the whole match. The 1st group is +started by the left-most (, the 2nd group is started by the +second-left-most (, etc. You can even nest groups. You can refer to +groups later using $0, $1, etc.

Matching

;; Simple matching
+(re-find #"\d+" "foo 123 bar") ;=> "123"
+
+;; What happens when a match fails.
+(re-find #"\d+" "foobar") ;=> nil
+
+;; Return only the first groups which satisfy match.
+(re-matches #"(@\w+)\s([.0-9]+)%"
+            "@shanley 19.8%")
+;=>["@shanley 19.8%" "@shanley" "19.8"]
+
+;; Return seq of all matching groups which occur in string.
+(re-seq #"(@\w+)\s([.0-9]+)%"
+        "@davidgraeber 12.3%,@shanley 19.8%")
+;=> (["@davidgraeber 12.3%" "@davidgraeber" "12.3"]
+;    ["@shanley 19.8%" "@shanley" "19.8"])
+

Replacing

We use str/replace. Aside from the first arg (the initial string), +the next two args are match and replacement:

   match / replacement can be:
+     string / string
+     char / char
+     pattern / (string or function of match).
+
;; In the replacement string, $0, $1, etc refer to matched groups.
+(str/replace "@davidgraeber 12.3%,@shanley 19.8%"
+             #"(@\S+)\s([.0-9]+)%"
+             "$2 ($1)")
+;=> "12.3 (@davidgraeber),19.8 (@shanley)"
+
+;; Using a function to replace text gives us power.
+(println
+  (str/replace "@davidgraeber 12.3%,@shanley 19.8%"
+               #"(@\w+)\s([.0-9]+)%,?"
+               (fn [[_ person percent]]
+                   (let [points (-> percent Float/parseFloat (* 100) Math/round)]
+                     (str person "'s followers grew " points " points.\n")))))
+;print=> @davidgraeber's followers grew 1230 points.
+;print=> @shanley's followers grew 1980 points.
+;print=>
+

Context-free grammars

Context-free grammars offer yet another boost in expressive matching +power, compared to regexes. You can express ideas like nesting.

We'll use Instaparse on +JSON's grammar. (This example isn't seriously +tested nor a featureful parser. Use +data.json instead.)

;; Your project.clj should contain this (you may need to restart your JVM):
+;;   :dependencies [[instaparse "1.2.4"]]
+;;
+;;  We'll assume your ns macro contains:
+;;   (:require [instaparse.core :as insta])
+;; or else in the repl you've loaded it:
+;;   (require '[instaparse.core :as insta])
+
+(def barely-tested-json-parser
+  (insta/parser
+   "object     = <'{'> <w*> (members <w*>)* <'}'>
+    <members>  = pair (<w*> <','> <w*> members)*
+    <pair>     = string <w*> <':'> <w*> value
+    <value>    = string | number | object | array | 'true' | 'false' | 'null'
+    array      = <'['> elements* <']'>
+    <elements> = value <w*> (<','> <w*> elements)*
+    number     = int frac? exp?
+    <int>      = '-'? digits
+    <frac>     = '.' digits
+    <exp>      = e digits
+    <e>        = ('e' | 'E') (<'+'> | '-')?
+    <digits>   = #'[0-9]+'
+    (* First sketched state machine; then it was easier to figure out
+       regex syntax and all the maddening escape-backslashes. *)
+    string     = <'\\\"'> #'([^\"\\\\]|\\\\.)*' <'\\\"'>
+    <w>        = #'\\s+'"))
+
+(barely-tested-json-parser "{\"foo\": {\"bar\": 99.9e-9, \"quux\": [1, 2, -3]}}")
+;=> [:object
+;     [:string "foo"]
+;     [:object
+;       [:string "bar"]
+;       [:number "99" "." "9" "e" "-" "9"]
+;       [:string "quux"]
+;       [:array [:number "1"] [:number "2"] [:number "-" "3"]]]]
+
+;; That last output is a bit verbose. Let's process it further.
+(->> (barely-tested-json-parser "{\"foo\": {\"bar\": 99.9e-9, \"quux\": [1, 2, -3]}}")
+     (insta/transform {:object hash-map
+                       :string str
+                       :array vector
+                       :number (comp edn/read-string str)}))
+;=> {"foo" {"quux" [1 2 -3], "bar" 9.99E-8}}
+
+
+;; Now we can appreciate what those <angle-brackets> were all about.
+;;
+;; When to the right of the grammar's =, it totally hides the enclosed
+;; thing in the output. For example, we don't care about whitespace,
+;; so we hide it with <w*>.
+;;
+;; When to the left of the grammar's =, it merely prevents a level of
+;; nesting in the output. For example, "members" is a rather
+;; artificial entity, so we prevent a pointless level of nesting with
+;; <members>.
+

Building complex strings

Redirecting streams

with-out-str provides a simple way to build strings. It redirects +standard output (*out*) to a fresh StringWriter, then returns the +resulting string. So you can use functions like print, even in +nested functions, and get the resulting string at the end.

(let [shrimp-varieties ["shrimp-kabobs" "shrimp creole" "shrimp gumbo"]]
+  (with-out-str
+    (print "We have ")
+    (doseq [name (str/join ", " shrimp-varieties)]
+      (print name))
+    (print "...")))
+;=> "We have shrimp-kabobs, shrimp creole, shrimp gumbo..."
+

Format strings

Java's templating mini-language helps you build many strings +conveniently. Reference.

;; %s is most commonly used to print args. Escape %'s with %%.
+(format "%s enjoyed %s%%." "Mozambique" 19.8) ;=> "Mozambique enjoyed 19.8%."
+
+;; The 1$ prefix allows you to keep referring to the first arg.
+(format "%1$tY-%1$tm-%1$td" #inst"2000-01-02T00:00:00") ;=> "2000-01-02"
+
+;; Again, 1$, 2$, etc prefixes let us refer to args in arbitrary orders.
+(format "New year: %2$tY. Old year: %1$tY"
+        #inst"2000-01-02T00:00:00"
+        #inst"3111-12-31T00:00:00")
+;=> "New year: 3111. Old year: 2000"
+

CL-Format

cl-format is a port of Common Lisp's notorious, powerful string +formatting mini-language. For example, you can build strings from +sequences. (As well as oddities like print numbers in English or two +varieties of Roman numerals.) However, it's weaker than plain format +with printing dates and referring to args in arbitrary order.

Remember that cl-format represents a (potentially unreadable) +language which your audience didn't sign up to learn. If you're the +sort of person who likes it, try to only use it in sweetspots where it +provides clarity for little complexity.

Tutorial +in Practical Common +Lisp. Reference +in Common Lisp's Hyperspec.

;; The first param prints to *out* if true. To string if false.
+;; To a stream if it's a stream.
+(pp/cl-format true "~{~{~a had ~s percentage point~:p.~}~^~%~}"
+              {"@davidgraeber" 12.3
+               "@shanley" 19.8
+               "@tjgabbour" 1})
+;print=> @davidgraeber had 12.3 percentage points.
+;print=> @tjgabbour had 1 percentage point.
+;print=> @shanley had 19.8 percentage points.
+
+(def format-string "~{~#[~;~a~;~a and ~a~:;~@{~a~#[~;, and ~:;, ~]~}~]~}")
+(pp/cl-format nil format-string [])
+;=> ""
+(pp/cl-format nil format-string ["@shanley"])
+;=> "@shanley"
+(pp/cl-format nil format-string ["@shanley", "@davidgraeber"])
+;=> "@shanley and @davidgraeber"
+(pp/cl-format nil format-string ["@shanley", "@davidgraeber", "@sarahkendzior"])
+;=> "@shanley, @davidgraeber, and @sarahkendzior"
+

Contributors

Tj Gabbour tjg@simplevalue.de, 2013 (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/books/index.html b/clones/clojure-doc.org/articles/ecosystem/books/index.html new file mode 100644 index 00000000..1f26cc23 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/books/index.html @@ -0,0 +1,230 @@ + + + + + Clojure Guides: Books about Clojure and ClojureScript + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • Books about Clojure
  • Books about ClojureScript

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

Overview

As of September 2014, Clojure has over a dozen books published (or available for +preview) about it, plus two about ClojureScript. This guide lists some of them +in reverse chronological order and intended to provide a very brief +overview of each. It is by no means comprehensive and may be quite +opinionated. The goal is to identify books that are more useful to +newcomers than others and recommend books that cover recent releases +of Clojure (1.3+).

Books About Clojure

Note: books are listed in reverse chronological order.

Getting Clojure: Build Your Functional Skills One Idea at a Time

By Russ Olsen

Notes

An accessible introduction to Clojure that focuses on the ideas behind the language as well as the practical details of writing code.

Where You Can Buy It

Clojure: Microservices with Clojure

By Anuj Kumar

Notes

The common patterns and practices of the microservice architecture and their application using the Clojure programming language.

Where You Can Buy It

Clojure: High Performance JVM Programming

By Eduardo Dรญaz, Shantanu Kumar, Akhil Wali

Notes

Explore the world of lightning fast Clojure apps with asynchronous channels, logic, reactive programming and more.

Where You Can Buy It

Clojure Standard Library (An Annotated Guide)

By Renzo Borgatti

Notes

The book illustrates the functions and macros contained in the Clojure standard library adding examples and implementation notes. Currently in early access.

Where You Can Buy It

Clojure Programming Cookbook

By Makoto Hashimoto, Nicolas Modrzyk

Notes

Handle every problem you come across in the world of Clojure programming with this expert collection of recipes

Where You Can Buy It

Mastering Clojure

By Akhil Wali

Notes

Understand the philosophy of the Clojure language and dive into its inner workings to unlock its advanced features, methodologies, and constructs

Where You Can Buy It

Clojure for Java Developers

By Eduardo Dรญaz

Notes

Discover Clojureโ€™s features and advantages and use them in your existing projects

Where You Can Buy It

Clojure for Finance

By Timothy Washington

Notes

A practical step-by-step tutorial that provides a basic overview of the concepts but focuses on providing the skills required to analyze data.

Where You Can Buy It

Mastering Clojure Macros

By Colin Jones.

Notes

A book that walks you step-by-step from the basic building blocks of macros to creating new language features.

Where You Can Buy It

The Joy of Clojure, 2nd Edition

By Michael Fogus and Chris Houser.

Notes

Updated for Clojure 1.6 with new content.

Where You Can Buy It

Mastering Clojure Data Analysis

By Eric Rochester.

Notes

This book presents a more in-depth look into Data Analysis than the author's +other book Clojure Data Analysis Cookbook. +Several topics (Network Analysis, GIS Analysis, Topic Modeling, Sentiment +Analysis, etc) are examined with examples using Clojure to process real-world data.

Where You Can Buy It

Clojure for Machine Learning

By Akhil Wali.

Notes

An introduction to machine learning problems, techniques and algorithms and +how they can be applied against real-world problems using Clojure.

Where You Can Buy It

Web Development with Clojure: Build Bulletproof Web Apps with Less Code

By Dmitri Sotnikov.

Notes

This book shows you how to leverage Clojure web-development libraries to +create web applications using an example-based approach.

Where You Can Buy It

Clojure High Performance Programming

By Shantanu Kumar.

Notes

A book on all things performant code in Clojure and on the JVM: profiling, +benchmarking, data structures, laziness impact, and more.

Where You Can Buy It

Clojure For The Brave and True

By Daniel Higginbotham.

Notes

A book for beginners. Covers the language and key parts of the ecosystem.

Where You Can Buy It

Clojure Cookbook

By Luke VanderHart, Ryan Neufeld.

Notes

Crowdsourced cookbook of about 200 recipes from O'Reilly. Work in progress +as of September 2013 but over 100 recipes are already available in the repository.

Where You Can Buy It

Functional Programming for the Object-Oriented Programmer

By Brian Marick.

Notes

This is a book about functional programming for those with object-oriented programming +backgrounds that uses Clojure in examples.

It is often cited as a good introductory book for newcomers to Clojure.

Where You Can Buy It

Clojure Programming

By Chas Emerick, Brian Carper, and Christophe Grand.

Notes

An excellent introductory book. Friendly to newcomers to the language and functional programming in general.

Where You Can Buy It

Programming Clojure, 2nd Ed

By Stuart Halloway and Aaron Bedra.

Notes

2nd edition of the oldest book about Clojure. Updated for Clojure 1.3+ and includes new content, for example, introduction +to test.generative, a Clojure testing framework similar to QuickCheck. A good book for beginners.

Where You Can Buy It

The Joy of Clojure, 1st Ed

By Michael Fogus and Chris Houser.

Notes

It's not an overstatement to say that this is a legendary book in the Clojure community. Covers "the what and why of Clojure". +To really appreciate it, however, you will need to have some real Clojure experience under your belt.

Where You Can Buy It

Clojure Data Analysis Cookbook

By Eric Rochester.

Notes

Covers multiple topics related to data analysis and data processing:

  • Acquiring data
  • Cleaning data
  • Analyzing data
  • Visualizing data
  • Basic statistics
  • Basic machine learning

Where You Can Buy It

Clojure in Action, 2nd Ed

By Amit Rathore.

Notes

Extended version of the first edition that covers Clojure 1.5, ClojureScript and Datomic.

Where You Can Buy It

  • From Manning, MEAP eBook (Kindle, ePub, PDF).

Clojure Made Simple

By John Stevenson.

Notes

A quick taste of Clojure for developers curious about the language. Its aimed at the complete beginner who wants to give Clojure a quick try before making a big investment. Its a short book in ebook only form and available for a few dollars.

Where You Can Buy It

Practical Clojure

By Luke VanderHart, Stuart Sierra.

Notes

A good introductory book.

Where You Can Buy It

Clojure in Action, 1st Ed

By Amit Rathore.

Notes

Contains many practical examples. The last chapter on metaprogramming and DSLs is fantastic.

This book covers Clojure 1.2. There were breaking changes in the language between Clojure 1.2 and 1.3, +keep this in mind.

Where You Can Buy It

Clojure - Grundlagen, Concurrent Programming, Java

By Stefan Kamphausen, Tim Oliver Kaiser

Notes

  • Written in German
  • This book covers Clojure 1.2. There were breaking changes in +the language between Clojure 1.2 and 1.3, keep this in mind. The +chapter on the contrib library in particular can be considered +outdated.

Where You Can Buy It

Programming Clojure, 1st Ed

By Stuart Halloway.

Notes

The oldest book on Clojure. Please consider getting the 2nd edition which covers a more recent version +and includes several updates.

This book covers Clojure 1.2.

Where You Can Buy It

Books About ClojureScript

Learning ClojureScript

By W. David Jarvis, Rafik Naccache & Allen Rohner

Notes

Master the art of agile single page web application development with ClojureScript

Where You Can Buy It

ClojureScript: Up and Running

By Stuart Sierra and Luke VanderHart.

Notes

The first book about ClojureScript, a Clojure implementation that compiles to JavaScript.

Where You Can Buy It

  • From O'Reilly, eBook (Kindle, ePub, PDF) or paperback.
+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/community/index.html b/clones/clojure-doc.org/articles/ecosystem/community/index.html new file mode 100644 index 00000000..77366eac --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/community/index.html @@ -0,0 +1,213 @@ + + + + + Clojure Guides: Clojure Community + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • The Official Clojure mailing lists
  • IRC channel
  • Documentation sites
  • Clojure User Groups around the globe
  • Conferences about or related to Clojure
  • Various Community sites about Clojure (subreddit, etc)

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

Clojure Mailing Lists

Clojure IRC Channels

Main Channel

#clojure on irc.freenode.net.

Channel logs are available at clojure-log.n01se.net and www.raynes.me/logs/irc.freenode.net/clojure/.

Documentation Channel

#clojure-doc on irc.freenode.net.

Documentation

Courses

User Groups

Videos About Clojure

Videos of talks about Clojure are often made available on InfoQ, and Clojure YouTube channel.

Podcasts About Clojure

Code Repositories

Most folks host their projects at +GitHub, and most pure Clojure +library distributions (with the exception of contrib) are available at +Clojars.

Websites

Forums

Conferences

In no particular order:

Email Newsletters

Workshops

Core development

See the Clojure Confluence wiki for full details on +how core development is handled.

Coordination of development efforts happen on the development mailing list, on the Confluence wiki, +and make use of the JIRA bug and issue tracker.

Although Clojure and the contrib libraries all have homes at GitHub, +pull-requests are not accepted. All core development happens via JIRA, patches and the Confluence wiki.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/filters/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/filters/index.html new file mode 100644 index 00000000..563a8a0d --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/filters/index.html @@ -0,0 +1,244 @@ + + + + + Clojure Guides: core.typed - Filters + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

core.typed includes an implementation of occurrence typing, which helps the type +checker refine types according to control flow.

Occurrence typing helps core.typed infer a very accurate type for this expression +by recognising the semantics of predicates like symbol? and number?.

clojure.core.typed=> (cf (let [a (ann-form 1 Any)]
+                           (cond
+                             (symbol? a) a
+                             (number? a) a)))
+(U clojure.lang.Symbol java.lang.Number nil)
+

Filters

core.typed collects more information than just types for each expression.

A structure called a filter set is also inferred. A filter set is a collection +of two filters:

  • a filter that is true if the expression is a true value, called the then filter
  • a filter that is true if the expression is a false value, called the else filter

Trivial Filters

There are two trivial filters:

  • tt, the trivially true filter
  • ff, the impossible filter

We can use cf to check the filters of expressions.

clojure.core.typed=> (cf 1)
+[(Value 1) {:then tt, :else ff}]
+

The second place of the result vector is the filter set inferred for the expression. +{:then tt, :else ff} reads: the expression could be a true value, but it is impossible +for it to be a false value. This of course aligns with the semantics of numbers in Clojure.

False values are never true:

clojure.core.typed=> (cf nil)
+[nil {:then ff, :else tt}]
+

Positive and Negative Type Filters

Filters can hold information relating bindings to types.

A positive type filter refines a local binding to be a type.

This filter says that the local binding a is of type Number.

(is Number a)
+

A negative type filter refines a local binding to not be a type.

This filter says that the local binding a is not of type Number.

(! Number a)
+

Latent Filters

Filters almost never need to be written directly in normal code. Latent filters +however are very useful, and provide the most useful information to core.typed.

A latent filter set is a filter set attached to a function type. It is latent +because it is not used directly: instead when a function with a latent filter set +is called, the filter set is instantiated in a way that makes sense in the current +context before it is used like a normal filter.

Predicates

A very common place for a latent filters are in the types for predicates.

The type for symbol?, is

[Any -> Boolean :filters {:then (is Symbol 0), :else (! Symbol 0)}]
+

First, notice that latent type predicates can also take an integer as an identifier. +The 0 represents the first argument of the function the latent filter set is attached to.

So the latent then filter (is Symbol 0) says the first argument to symbol? is of type Symbol +if the whole expression is a true value. To retrieve a non-latent filter, the 0 is instantiated to +the appropriate local binding.

Note: Use `clojure.core.typed/print-filterset` to print the filter set of an expression.
+
clojure.core.typed=> (cf (let [a (ann-form 1 Any)]
+                           (print-filterset "symbol filters"
+                             (symbol? a))))
+"symbol filters"
+{:then (is clojure.lang.Symbol a), :else (! clojure.lang.Symbol a)}
+empty-object
+Flow tt
+boolean
+

By printing the filter set of (symbol? a) we can see this in work, which +has a non-latent filter set of {:then (is clojure.lang.Symbol a), :else (! clojure.lang.Symbol a)}.

Paths and Objects

TODO

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/function_types/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/function_types/index.html new file mode 100644 index 00000000..ace7dba7 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/function_types/index.html @@ -0,0 +1,237 @@ + + + + + Clojure Guides: core.typed - Functions + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +
  • Function types are quite different from Typed Racket +
    • anything can implement the IFn interface
    • In core.typed the Function type is more a special type than the type for lambdas

Common things that are IFns:

- clojure.lang.Function
+- c.l.Keyword
+  - [Any -> Any]
+- (c.l.PersistentHashMap k v)
+  - (All [x]
+      (Fn [Any -> (U nil v)]
+          [Any x -> (U x v)]))
+- (c.l.PersistentHashSet v)
+  - (All [x]
+      (Fn [Any -> (U nil v)]))
+- c.l.Symbol
+  - [Any -> Any]
+- (Value :a)
+  - (All [x]
+      [Any -> x :filters {:then (is {:a x} 0)}])
+- (Value sym)
+  - (All [x] [Any -> (U nil v)])
+

The IFn class might be parameterised by a Function type. +The immediate problem is intersections allows us to have more +than one function type.

eg. What function type is this?

(I (Value :a)
+   (All [x]
+     [Any -> x :filters {:then (is {:a x} 0)}])
+

Even (Value :a) inherits two function types:

  • that for c.l.Keyword
  • that for (Value :a)

(Value :a) <: (IFn x) infers x to be:

(I [Any -> Any]
+   (All [x]
+     [Any -> x :filters {:then (is {:a x} 0)}])
+

The second member of the intersection is more specific, +thus can be simplified to:

(All [x]
+  [Any -> x :filters {:then (is {:a x} 0)}])
+

Does this work in general? As long as there is a subtyping relationship +between the possible Function types, we can infer the most useful +one.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/home/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/home/index.html new file mode 100644 index 00000000..0916cd60 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/home/index.html @@ -0,0 +1,207 @@ + + + + + Clojure Guides: core.typed - User Documentation Home + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

core.typed is an optional type system for Clojure.

Quickstart

(clojure.core.typed/ann v t) gives var v the static type t.

(clojure.core.typed/ann-form f t) ensures form f is of the static type t.

(clojure.core.typed/check-ns) type checks the current namespace.

(clojure.core.typed/cf t) type checks the form t.

See the Quick Guide.

Rationale

Why core.typed exists, what can it do for you?

Getting Started Guide

If you are new to core.typed, gradual type systems, or even types in general, and want to learn how +core.typed can help verify your programs, start here.

Introduction and Motivation

We discuss some theory and design goals of core.typed.

Annotations

Where and how to annotate your code to help core.typed check your code.

Types

Syntax and descriptions of core.typed types.

Polymorphic Functions, Bounds and Higher-kinded Variables

Filters

An overview of filters for occurrence typing.

Datatypes and Protocols

Typing definitions and usages of Clojure datatypes and protocols.

Looping constructs

core.typed provides several wrapper macros for common looping constructs.

Dotted Functions

Java Classes, Arrays and Interop

Miscellaneous Tutorials

Hole-Driven Development

A fun diversion playing with holes.

  • Requires some knowledge of Haskell.

Examples

IRC Bot

Limitations - Known issues

Documentation Contributors

Ambrose Bonnaire-Sergeant (@ambrosebs)

Copyright 2013, Ambrose Bonnaire-Sergeant

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/limitations/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/limitations/index.html new file mode 100644 index 00000000..0e7a843f --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/limitations/index.html @@ -0,0 +1,222 @@ + + + + + Clojure Guides: core.typed - Limitations + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Namespace management

Typed dependencies NYI.

Destructuring

Only map destructuring without options is supported.

Other forms of destructuring require equality filters.

Shadowing bindings

If an argument is shadowed and the shadowed binding is referenced +in filters or object then the shadow is indistinguishable from the parameter +and parameter will be incorrectly abstracted.

eg.

(fn [a]
+  (if (= a 1)
+    (let [a 'foo] ; here this shadows the argument, impossible to recover filters
+      a)          ; in fact any new filters about a will be incorrectly assumed to be the argument
+      false))
+

(See abstract-result in typed/test.clj)

Dotted Functions

A dotted function contains a dotted variable in its function type.

eg. map's type: +(All [c a b ...] [[a b ... b -> c] (U nil (Seqable a)) (U nil (Seqable b)) ... b -> (Seqable c)]))

We can't currently check the definitions of functions with dotted rest arguments.

Rest Arguments

Currently cannot check the definition of functions with rest arguments, +but usage checking should work.

Using filter

Not everything can be inferred from a filter. A common example is +(filter identity coll) does not work. The reason is identity only +gives negative information when its result is true: that the argument is not(U nil false).

This idiom must be converted to this syntax (fn [a] a) and then annotated with +positive propositions.

;eg.
+
+(filter (ann-form (fn [a] a)
+                  [(U nil Number) -> (U nil Number) :filters {:then (is Number 0)}])
+        [1 nil 2])
+; :- (Seqable Number)
+

Positive information infers just fine, like (filter number? coll). +The above idiom is useful when you are filtering something like a (Seqable (U nil x)) and there is no +predicate to test for x, so you can only test if something isn't nil.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/loops/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/loops/index.html new file mode 100644 index 00000000..bd62c3a4 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/loops/index.html @@ -0,0 +1,223 @@ + + + + + Clojure Guides: core.typed - Looping constructs + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Due to limitations in core.typed's inference, we require using "typed" versions +of several core forms.

loop

Usages of loop should be replaced with clojure.core.typed/loop>.

The syntax is identical except each loop variable requires a type annotation.

(loop> [[a :- Number] 1
+        [b :- (U nil Number)] nil]
+  ...)
+

Named fn's

Named fn's require full annotation for accurate recursive calls inside the fn body.

clojure.core.typed=> (cf (ann-form (fn a [n] (+ (a 1) n))
+                                   [Number -> Number]))
+(Fn [java.lang.Number -> java.lang.Number])
+

for

Use clojure.core.typed/for> instead of for.

for> requires annotations for the return type of the body +of the for, and the left hand side of each binding form.

(for> :- Number
+      [[a :- (U nil AnyInteger)] [1 nil 2 3]
+       :when a]
+  (inc a))
+

doseq

Use clojure.core.typed/doseq> instead of doseq.

doseq> requires annotations for the left hand side of each binding form.

(doseq> [[a :- (U nil AnyInteger)] [1 nil 2 3]
+         :when a]
+   (inc a))
+
+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/mm_protocol_datatypes/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/mm_protocol_datatypes/index.html new file mode 100644 index 00000000..5f0a900f --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/mm_protocol_datatypes/index.html @@ -0,0 +1,219 @@ + + + + + Clojure Guides: core.typed - Protocols + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Annotating Protocols

clojure.core.typed/ann-protocol annotates protocols.

Takes a name and a optionally a :methods keyword argument mapping +method names to expected types.

Protocol definitions should use clojure.core.typed/defprotocol> (identical syntax to defprotocol).

(ann-protocol IUnifyWithLVar
+              unify-with-lvar [Term LVar ISubstitutions -> (U ISubstitutions Fail)])
+
+(defprotocol> IUnifyWithLVar
+  (unify-with-lvar [v u s]))
+

Each protocol method argument (including the first) is explicit in the type annotation. +Often, the the first argument (aka. this) will just be the protocol, but in some cases +it is convenient to add more general types.

Annotating datatypes

clojure.core.typed/ann-datatype annotates datatypes.

Takes a name and a vector of fieldname/type type entries.

(ann-datatype Pair [lhs :- Term
+                    rhs :- Term])
+
+(deftype Pair [lhs rhs]
+  ...)
+

Each protocol extended in deftype must have an annotated expected type with ann-protocol.

The types for Java interface method are inferred from their corresponding Java type.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/poly_fn/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/poly_fn/index.html new file mode 100644 index 00000000..2ac82b58 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/poly_fn/index.html @@ -0,0 +1,234 @@ + + + + + Clojure Guides: core.typed - Polymorphic Functions + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

core.typed supports polymorphic function types. They allow us to specify +function types which are both general and accurate.

All

The primitive All constructor creates a polymorphic binder and scopes +type variables in a type.

The identity function has a simple polymorphic type:

(All [x]
+  [x -> x])
+

Read: for all types x, a function that takes an x and returns an x.

Polymorphic types are introduced with annotations, but where are they eliminated? +We use local type inference to infer type variable types based on how they are used.

(identity :a)
+

In the above example, we infer x to be Keyword, and instantiate the polymorphic +type as [Keyword -> Keyword].

Bounds

Type variables support upper and lower type bounds, which default to Any and Nothing +respectively.

Equivalently, the type:

(All [x] ...)
+

is shorthand for:

(All [[x :> Nothing :< Any]] ...)
+

We use bounds to ensure a type variable can only be instantiated to a particular type.

The type of an identity function that only accepts Numbers can be written:

(All [[x :< Number]]
+  [x -> x])
+

Bounds do not seem as useful in core.typed as languages like Java or Scala. +Often, combinations of ordered function intersections and unions are more useful.

Bounds are also recursive: a bound can refer to the variable it's bounding. +Type variables to the left of the type variable being bounded in the same binder are in scope in a bound.

Higher-kinded variables

Note: Experimental feature

A type variable can be of a higher-kind.

(def-alias AnyMonad
+  (TFn [[m :kind (TFn [[x :variance :covariant]] Any)]]
+    '{:m-bind (All [x y]
+                [(m x) [x -> (m y)] -> (m y)])
+      :m-result (All [x]
+                  [x -> (m x)])
+      :m-zero (U (All [x] (m x)) Undefined)
+      :m-plus (U (All [x]
+                   [(m x) * -> (m x)])
+                 Undefined)}))
+

In this type, x is a type function taking a type and returning a type. +For those familiar with Haskell, x is of kind * -> *.

The type function is also covariant, which further ensures x is instantiated +to a covariant type function.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide.html new file mode 100644 index 00000000..31d4dd6d --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide.html @@ -0,0 +1,241 @@ + + + + + Clojure Guides: core.typed - Quick Guide + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Design choices

All vars must have annotated static types

Use clojure.core.typed/ann to assign types to vars

eg. Assign my-fn in the current namespace the type [Any -> Any] (a function of one argument).

(ann my-fn [Any -> Any])
+

Type checking is separate to compilation and must be explicitly run

Use clojure.core.typed/check-ns to type check the current namespace. +This can be done at the REPL.

Note: Global annotations like ann are only valid when found in a namespace currently being +checked with check-ns, or wrapped in a cf. A raw ann in a REPL has no effect. +Global annotations should be top-level forms or inside a (possibly nested) top-level do.

All function arguments need to be annotated, or default to Any

Use clojure.core.typed/ann-form to annotate a function.

eg.

(ann-form #(+ 1 %) [Number -> Number])
+

Everything is type checked, but core.typed can ignore certain expressions

core.typed is early in development and there are Clojure idioms it cannot +currently type check. Wrap top-level expressions in clojure.core.typed/tc-ignore +to ignore them.

Suggestion: If porting a namespace to core.typed, initially use tc-ignore liberally to ignore problematic +code while determining the types for expressions. Once most vars are annotated, revisit +these sites to determine the issue.

Debugging

clojure.core.typed/print-env takes a debug string and prints the local type environment at the current expression.

Use cf to experiment at the REPL

clojure.core.typed/cf takes an expression and optionally an expected type and type checks the expression, +returning its inferred type.

eg.

clojure.core.typed=> (cf (fn [a]
+                           {:pre [(number? a)]}
+                           (inc a)))
+[(Fn [Any -> java.lang.Number]) {:then tt, :else ff}]
+

If cf returns a vector of results, the first element is the static type.

Use ann-form to ensure expressions are particular types

clojure.core.typed/ann-form can be used as a kind of static assert.

clojure.core.typed=> (cf (let [a (+ 1 2)
+                               _ (ann-form a clojure.lang.Symbol)]
+                           a))
+#<AssertionError java.lang.AssertionError: Assert failed: 6: Local binding a expected type clojure.lang.Symbol, but actual type clojure.core.typed/AnyInteger
+(or (not expected) (subtype? t (ret-t expected)))>
+

core.typed understands assertions and conditionals

Normal "untyped" Clojure code often use type predicates combined with assertions or conditionals to direct control flow. +core.typed uses them to gain type information about the current environment.

(let [a (ann-form 1 Number)
+      _ (print-env "before assert")
+      _ (assert (integer? a))
+      _ (print-env "after assert")])
+; "before assert"{:env {a java.lang.Number},
+;                 :props ()}
+; "after assert"{:env {_28338 nil, _ nil, a clojure.core.typed/AnyInteger},
+;                :props ((is clojure.core.typed/AnyInteger a) (when (! (U false nil) _) ff) (when (! (U false nil) _) ff) (when (! (U false nil) _28338) ff))}
+

The :env map is maps local bindings to their current types. +:props is a list of propositions currently in scope (can usually be ignored, mostly useful for internal debugging purposes).

Notice the local binding a has a more accurate type after the assert expression.

Note: core.typed operates on a hygienic AST, so shadowed bindings will have gensymed names.

Typing core constructs

core.typed understands datatype definitions

Use clojure.core.typed/ann-datatype to give a datatype an expected type.

Use defprotocol> instead of defprotocol

core.typed currently cannot understand protocol definitions. Simply replace references to defprotocol +with clojure.core.typed/defprotocol>

core.typed understands simple multimethods

core.typed can infer accurate types for multimethods that dispatch on simple things like keywords or class. +Just assign an expected type to the multimethod's var with ann and core.typed will use it to infer accurate +types in each defmethod.

If in doubt whether a multimethod is being inferred properly, use the debugging techniques to double check. +core.typed may not throw an exception if the dispatch is too complex to type check currently.

Macros & Macro Definitions

Macro definitions are ignored. The type checker operates on the macroexpanded form from +the Compiler's analysis phase.

Type Syntax

Types use the current global scope of the namespace

Simply adding an (:import ...) to the ns declaration as usual in Clojure brings the class name into scope. +Otherwise, refers to classes via their fully qualified name.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide/index.html new file mode 100644 index 00000000..48f53863 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/quick_guide/index.html @@ -0,0 +1,241 @@ + + + + + Clojure Guides: core.typed - Quick Guide + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Design choices

All vars must have annotated static types

Use clojure.core.typed/ann to assign types to vars

eg. Assign my-fn in the current namespace the type [Any -> Any] (a function of one argument).

(ann my-fn [Any -> Any])
+

Type checking is separate to compilation and must be explicitly run

Use clojure.core.typed/check-ns to type check the current namespace. +This can be done at the REPL.

Note: Global annotations like ann are only valid when found in a namespace currently being +checked with check-ns, or wrapped in a cf. A raw ann in a REPL has no effect. +Global annotations should be top-level forms or inside a (possibly nested) top-level do.

All function arguments need to be annotated, or default to Any

Use clojure.core.typed/ann-form to annotate a function.

eg.

(ann-form #(+ 1 %) [Number -> Number])
+

Everything is type checked, but core.typed can ignore certain expressions

core.typed is early in development and there are Clojure idioms it cannot +currently type check. Wrap top-level expressions in clojure.core.typed/tc-ignore +to ignore them.

Suggestion: If porting a namespace to core.typed, initially use tc-ignore liberally to ignore problematic +code while determining the types for expressions. Once most vars are annotated, revisit +these sites to determine the issue.

Debugging

clojure.core.typed/print-env takes a debug string and prints the local type environment at the current expression.

Use cf to experiment at the REPL

clojure.core.typed/cf takes an expression and optionally an expected type and type checks the expression, +returning its inferred type.

eg.

clojure.core.typed=> (cf (fn [a]
+                           {:pre [(number? a)]}
+                           (inc a)))
+[(Fn [Any -> java.lang.Number]) {:then tt, :else ff}]
+

If cf returns a vector of results, the first element is the static type.

Use ann-form to ensure expressions are particular types

clojure.core.typed/ann-form can be used as a kind of static assert.

clojure.core.typed=> (cf (let [a (+ 1 2)
+                               _ (ann-form a clojure.lang.Symbol)]
+                           a))
+#<AssertionError java.lang.AssertionError: Assert failed: 6: Local binding a expected type clojure.lang.Symbol, but actual type clojure.core.typed/AnyInteger
+(or (not expected) (subtype? t (ret-t expected)))>
+

core.typed understands assertions and conditionals

Normal "untyped" Clojure code often use type predicates combined with assertions or conditionals to direct control flow. +core.typed uses them to gain type information about the current environment.

(let [a (ann-form 1 Number)
+      _ (print-env "before assert")
+      _ (assert (integer? a))
+      _ (print-env "after assert")])
+; "before assert"{:env {a java.lang.Number},
+;                 :props ()}
+; "after assert"{:env {_28338 nil, _ nil, a clojure.core.typed/AnyInteger},
+;                :props ((is clojure.core.typed/AnyInteger a) (when (! (U false nil) _) ff) (when (! (U false nil) _) ff) (when (! (U false nil) _28338) ff))}
+

The :env map is maps local bindings to their current types. +:props is a list of propositions currently in scope (can usually be ignored, mostly useful for internal debugging purposes).

Notice the local binding a has a more accurate type after the assert expression.

Note: core.typed operates on a hygienic AST, so shadowed bindings will have gensymed names.

Typing core constructs

core.typed understands datatype definitions

Use clojure.core.typed/ann-datatype to give a datatype an expected type.

Use defprotocol> instead of defprotocol

core.typed currently cannot understand protocol definitions. Simply replace references to defprotocol +with clojure.core.typed/defprotocol>

core.typed understands simple multimethods

core.typed can infer accurate types for multimethods that dispatch on simple things like keywords or class. +Just assign an expected type to the multimethod's var with ann and core.typed will use it to infer accurate +types in each defmethod.

If in doubt whether a multimethod is being inferred properly, use the debugging techniques to double check. +core.typed may not throw an exception if the dispatch is too complex to type check currently.

Macros & Macro Definitions

Macro definitions are ignored. The type checker operates on the macroexpanded form from +the Compiler's analysis phase.

Type Syntax

Types use the current global scope of the namespace

Simply adding an (:import ...) to the ns declaration as usual in Clojure brings the class name into scope. +Otherwise, refers to classes via their fully qualified name.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/rationale/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/rationale/index.html new file mode 100644 index 00000000..99962bb5 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/rationale/index.html @@ -0,0 +1,227 @@ + + + + + Clojure Guides: core.typed - Rationale + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Static typing has well known benefits. For example, statically typed languages catch many common +programming errors at the earliest time possible: compile time. +Types also serve as an excellent form of (machine checkable) documentation that +almost always augment existing hand-written documentation.

Languages without static type checking (dynamically typed) bring other benefits. +Without the strict rigidity of mandatory static typing, they can provide more flexible and forgiving +idioms that can help in rapid prototyping. +Often the benefits of static type checking are desired as the program grows.

This work adds static type checking (and some of its benefits) to Clojure, a dynamically typed language, +while still preserving idioms that characterise the language. +It allows static and dynamically typed code to be mixed so the programmer can use whichever +is more appropriate.

(For a detailed treatment, see my Honours Dissertation, A Practical Optional Type System for Clojure)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/start/annotations/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/start/annotations/index.html new file mode 100644 index 00000000..bc24d88d --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/start/annotations/index.html @@ -0,0 +1,275 @@ + + + + + Clojure Guides: core.typed - Annotations + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

core.typed requires a moderate amount of assistance from the user to help infer types.

There are two main things that need annotating:

  1. All vars must be annotated
  2. All function parameters must be annotated, or default to Any.

From the provided annotations, core.typed uses local type inference to infer +the types for local bindings, interop calls, and other expressions, mostly +without further assistance.

Vars

When core.typed finds a var reference, def, binding, or some other var-related construct +that relys on the derefereced value of a var, it requires an expected type.

clojure.core.typed=> (declare abc)
+#'clojure.core.typed/abc
+clojure.core.typed=> (cf abc)
+#<AssertionError java.lang.AssertionError: Assert failed: Untyped var reference: clojure.core.typed/abc
+(contains? (clojure.core/deref *var-annotations*) nsym)>
+

Vars in current namespace

Use clojure.core.typed/ann to associate a static type with a var.

clojure.core.typed=> (cf (ann abc Number))
+[clojure.core.typed/abc java.lang.Number]
+clojure.core.typed=> (cf (def abc 1))
+clojure.lang.Var
+clojure.core.typed=> (cf abc)
+java.lang.Number
+

ann qualifies the var in the current namespace if unqualified.

Vars in other namespaces

Sometimes vars from other namespaces need annotation. Just qualify the var as you +would in the current namespace (aliases are recognised) to associate it with a static type.

clojure.core.typed=> (cf clojure.core/*compile-path*)
+#<AssertionError java.lang.AssertionError: Assert failed: Untyped var reference: clojure.core/*compile-path*
+(contains? (clojure.core/deref *var-annotations*) nsym)>
+clojure.core.typed=> (cf (ann clojure.core/*compile-path* String))
+[clojure.core/*compile-path* java.lang.String]
+clojure.core.typed=> (cf clojure.core/*compile-path*)
+java.lang.String
+

Unchecked Vars

We can instruct core.typed to ignore certain var definitions by adding :nocheck metadata +to ann forms.

(ns typed.nocheck
+  (:require [clojure.core.typed :refer [ann-nocheck ann check-ns]]))
+
+(ann ^:nocheck foo [Number -> Number])
+(defn foo [a]
+  'a)
+
+(ann bar [Number -> Number])
+(defn bar [b]
+  (+ 2 (foo b)))
+

Var Warnings

After type checking has been performed, core.typed warns about vars that have been assigned types +but have no corresponding checked def form. The def must at least make a binding, +so it would be a warning if the var was only declared.

(ns clojure.core.typed.test.nocheck
+  (:require [clojure.core.typed :refer [ann-nocheck ann check-ns]]))
+
+(ann ^:nocheck foo [Number -> Number])
+(defn foo [a]
+  'a)
+
+(ann bar [Number -> Number])
+(defn bar [b]
+  (+ 2 (foo b)))
+
+;(check-ns)
+; ...
+; WARNING: Var clojure.core.typed.test.var-usage/foo used without checking definition
+;=> nil
+

Functions

There are several ways to annotate a function type.

Partial annotation with fn>

To annotate just the arguments of a fn, use the fn> wrapper. It is exactly like fn, +except each argument is wrapped in a vector which includes its static type.

clojure.core.typed=> (cf (fn> [[a :- Number]] (+ a 1)))
+[(Fn [java.lang.Number -> java.lang.Number]) {:then tt, :else ff}]
+

All the usual destructuring is supported.

clojure.core.typed=> (cf (fn> [[{:keys [a b c]} :- '{:a Number :b Long :c Double}]]
+                           [a b c]))
+[(Fn ['{:a java.lang.Number, :b java.lang.Long, :c java.lang.Double} -> '[java.lang.Number java.lang.Long java.lang.Double]])
+ {:then tt, :else ff}]
+

Full annotation with ann-form

Often it is more useful to provide a full function type as a fn's annotation. This +especially works well with Clojure's anonymous function syntax.

clojure.core.typed=> (cf (ann-form #(inc %)
+                                   [Number -> Number]))
+(Fn [java.lang.Number -> java.lang.Number])
+

This way, you can also assign anonymous functions ordered intersection function types.

clojure.core.typed=> (cf (fn [a]
+                           (cond
+                             (number? a) 1
+                             (symbol? a) 'a))
+                         (Fn [Number -> Number]
+                             [Symbol -> Symbol]))
+(Fn [java.lang.Number -> java.lang.Number]
+    [clojure.lang.Symbol -> clojure.lang.Symbol])
+
+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/start/introduction_and_motivation/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/start/introduction_and_motivation/index.html new file mode 100644 index 00000000..52c0d9a8 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/start/introduction_and_motivation/index.html @@ -0,0 +1,237 @@ + + + + + Clojure Guides: core.typed - Getting Started: Introduction and Motivation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

core.typed is an optional type system for Clojure. If you are interesting in how core.typed +can help you verify your programs as correct, read on.

"I use Clojure to avoid types!"

Many programmers use Clojure as relief from popular typed languages such as Java or C#. +Java's verbosity and redundant type annotations help make the move to Clojure feel liberating +and enjoyable: so why go back to types?

core.typed has a different story to tell:

  • type checking is optional +
    • only use the type system where you need it
  • local type inference is used to infer local bindings +
    • locals rarely need type annotations
  • it can type check (mostly) normal Clojure code +
    • the Clojure you know and love!

If Java has driven you away from types, core.typed could be pleasant surprise. +It might even become one of your go-to tools for code verification in Clojure.

What are types?

This is a good question, especially in the context of a dynamically-typed (DT) language +where we don't have "types".

We use the term "type" to mean static type and "tag" for runtime tags. +Types only exist at compile time and are used by the static type system to model runtime +invariants and properties.

Thinking of compile-time and runtime as distinct phases in terms of types often helps. +The type system uses types to reason about the runtime behaviour of code, which can +also include tag invariants.

There are no types in Clojure, only tags. We can also say that Clojure has exactly one type: Any (subtype of all types). +The closest equivalent to types we have +are ad-hoc comments or doc-strings which describe the input/output behaviour +of functions.

For example, the number? predicate returns true if its (runtime) argument +has a tag that is a subtype of java.lang.Number, otherwise false. In core.typed +we use a type to model these invariants. +The tag of number? might be IFn, while its type is [Any -> boolean :filters {:then (is Number 0) :else (! Number 0)}].

In summary:

  • types only exist at compile time
  • tags only exist at runtime

Why types?

Why use types at all? A static type checker gives earlier and often clearer type errors.

For example, you might observe:

  • fewer "Boolean is not an ISeq" errors without line numbers in production
  • more "Cannot pass Boolean to second argument of map" with line numbers at compile time in development.

Types, when coupled with an appropriate doc-string, are excellent machine checkable documentation. +They never go out of date, and are often invaluable as a quick reminder of what a function does.

Types are useful when a program grows, especially when there are multiple contributors. +If a contribution passes the type system, we know that it is type correct (type errors are amongst +the most common user errors in programming).

Great, types are the answer!

Not quite. Types can help verify that a program is basically correct, but not if it does the right thing. +Use as many verification techniques as you can: core.typed works great coupled with unit testing or +generative testing.

Clojure simply is not built with static typing in mind. It is impractical to expect core.typed alone +to prevent as many user errors as say Haskell's type system: core.typed either needs to choose some +subset of Clojure optimised for user error prevention, or attempt to check all Clojure code +while making some compromises (it does the latter).

This might seem discouraging, but in practice core.typed will catch all type errors in your code. +The problem is some Clojure idioms are so flexible it is often impossible to distinguish +between intended and unintended usage.

A small example: map accepts either nil or a Seqable as a second argument. It is perfectly +valid to provide an argument that is always nil, but it's probably not what the user intended.

So for best results, couple core.typed with all the usual testing/verification techniques.

Before we begin

There are some details to keep in mind when using core.typed before you jump in to use it.

Read the Quick Guide, and keep a copy handy when you follow along the rest of the tutorial.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/types/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/types/index.html new file mode 100644 index 00000000..7b80b623 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/types/index.html @@ -0,0 +1,338 @@ + + + + + Clojure Guides: core.typed - Types + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Common types

Any and Nothing

Every type is a subtype to Any, written x <: Any for all types x. Equivalently, any place that Any is valid, +any other type can be used. Any is also known as the "Top" type.

Conversely, there are no types that are subtypes to Nothing. However for all types x +it holds that Nothing <: x. Put another way, Nothing is a valid type to give use +in positions expecting any other type. In practice, Nothing is not as useful as Any, +and is usually used internally to detect dead code and other code properties.

Functions

core.typed has a special function type, which is an ordered intersection of arities. +It allows us to specify fine grained function invariants.

Starting simply,

(Fn [Any -> Any])
+

is a function taking one argument of type Any. [Any -> Any] +is an equivalent shorthand for single-arity function types.

Multiple arities

We can specify multiple arities:

(Fn [Any -> Any]
+    [Any Any -> Any])
+

Here we can call a function of this type with either one or two arguments. +In this case, the ordered intersection type acts as a simple overloading on arity.

Finer invariants can be expressed by specifying multiple signatures of the same arity:

(Fn [Symbol -> Number]
+    [Number -> Symbol])
+

This function returns a Number if passed a Symbol, and returns a Symbol if passed a Number.

The exact return type for a function application expression involving multiple arities +is chosen by matching the actual types provided with each arities, top-to-bottom +(this explains why our functions are "ordered" intersections). +In this case, each arity is disjoint because no combination of arguments could +potentially trigger both arities. More concretely, there is no type that is both +a Symbol and a Number, so at most one arity triggers for any given arguments.

Overlapping arities hints at the power of ordered intersections.

(Fn [Long -> Symbol]
+    [Number -> Keyword])
+

This type always returns a Symbol for Long arguments.

Beware, swapping the arities produces different results!

(Fn [Number -> Keyword]
+    [Long -> Symbol])
+

The first arity always "wins" because Number is strictly more general than Long. +Arities are usually ordered from more-specific parameters to less-specific parameters.

What about arities that have partially overlapping parameters? +Consider:

(Fn [Long Any -> Keyword]
+    [Any Number -> Symbol])
+

Calling with Long Long arguments gives Keyword, and Number Long gives Symbol.

Flipping the arities gives different results:

(Fn [Any Number -> Symbol]
+    [Long Any -> Keyword])
+

Now Long Long gives Symbol, and Number Long gives Symbol. +Partially overlapping arities can be tricky and can unexpectedly trigger earlier arities, +so care must be taken here.

Finally, a common idiom is to provide a base arity, which has arguments at least as general +as the ones above it.

For example, we might want our function of type (Fn [Long -> Symbol] [Number -> Keyword]) to handle the case where +the argument is either a Long or a Number. +We can express this by using a union (to express a least-upper-bound of Long and Number).

(Fn [Long -> Symbol]
+    [Number -> Keyword]
+    [(U Long Number) -> (U Symbol Keyword)])
+

Note the result type is sufficiently general to show the result type is either a Symbol or Keyword.

Rest parameters

Rest parameters are specified using a *.

eg.

(Fn [Any Number * -> Any])
+

is a function taking at least one parameter, and any number of parameters after it +of type Number.

Keyword parameters

Keyword parameters are specified using & after the fixed domain.

eg.

(Fn [Any & {:a Number} -> Any])
+

is a function that takes a fixed parameter and an optional keyword argument :a, of +type Number.

We can also specify mandatory keyword parameters:

(Fn [Any & {} :mandatory {:a Number} -> Any])
+

is the same function, except the keyword argumetn :a now must be present when calling.

We can express finer grained invariants by combining keyword types and ordered +function intersection types:

(Fn [Any & {} :mandatory {:a Number :b Number} -> Number]
+    [Any & {:a Number :b Number} -> Any])
+

This function type returns a Number if provided both :a and :b parameters, +otherwise returns Any if some other combination of :a and :b is provided.

Java Classes

core.typed reuses Java and clojure.lang.* classes. The normal scoping rules apply in types, +e.g., use :import to bring classes into scope.

Note: java.lang.* classes are implicitly in scope in Clojure namespaces.

Numbers, Strings and other Java types

core.typed follows the normal rules that apply to Clojure code.

clojure.core.typed=> (cf 1 Long)
+java.lang.Long
+clojure.core.typed=> (cf 1.1 Double)
+java.lang.Double
+clojure.core.typed=> (cf "a" String)
+java.lang.String
+clojure.core.typed=> (cf \a Character)
+java.lang.Character
+

Symbols and Keywords

Symbols and Keywords are instances of their corresponding clojure.lang classes.

clojure.core.typed=> (cf 'a clojure.lang.Symbol)
+clojure.lang.Symbol
+clojure.core.typed=> (cf :a clojure.lang.Keyword)
+clojure.lang.Keyword
+

Seqables

Seqables extend (Seqable a), which is covariant in its argument. +Types that extend (Seqable a) are capable of creating a sequence +(aka. an (ISeq a)) representation of itself via functions like seq.

clojure.core.typed=> (cf {'a 2 'b 3} (Seqable (IMapEntry Symbol Number)))
+(clojure.lang.Seqable (clojure.lang.IMapEntry clojure.lang.Symbol java.lang.Number))
+clojure.core.typed=> (cf [1 2 3] (Seqable Number))
+(clojure.lang.Seqable java.lang.Number)
+clojure.core.typed=> (cf '#{a b c} (Seqable Symbol))
+(clojure.lang.Seqable clojure.lang.Symbol)
+

Seqs

Seqs extend (ISeq a), which is covariant in its argument.

clojure.core.typed=> (cf (seq [1 2]) (ISeq Number))
+(clojure.lang.ISeq java.lang.Number)
+

Lists

Lists extend (IPersistentList a), which is covariant in its argument.

clojure.core.typed=> (cf '(1 2) (IPersistentList Number))
+(clojure.lang.IPersistentList java.lang.Number)
+

Vectors

Vectors extend (IPersistentVector a), which is covariant in its argument.

clojure.core.typed=> (cf [1 2] (IPersistentVector Number))
+(clojure.lang.IPersistentVector java.lang.Number)
+

Maps

Maps extend (IPersistentMap a b), which is covariant in both its arguments.

clojure.core.typed=> (cf {'a 1 'b 3} (IPersistentMap Symbol Long))
+(clojure.lang.IPersistentMap clojure.lang.Symbol java.lang.Long)
+

Sets

Sets extend (IPersistentSet a), which is covariant in its argument.

clojure.core.typed=> (cf #{1 2 3} (IPersistentSet Number))
+(clojure.lang.IPersistentSet java.lang.Number)
+

Atoms

An Atom of type (Atom w r) can accept values of type w and provide values of type r. +It is contravariant in w and covariant in r.

Usually w and r are identical, so an alias (clojure.core.typed/Atom1 wr) is provided, +which is equivalent to (Atom wr wr).

clojure.core.typed=> (cf (atom {}) (Atom1 (IPersistentMap Symbol Number)))
+(clojure.core.typed/Atom1 (clojure.lang.IPersistentMap clojure.lang.Symbol java.lang.Number))
+

Type Grammar

A rough grammar for core.typed types.

Type :=  nil
+     |   true
+     |   false
+     |   (U Type*)
+     |   (I Type+)
+     |   FunctionIntersection
+     |   (Value CONSTANT-VALUE)
+     |   (Rec [Symbol] Type)
+     |   (All [Symbol+] Type)
+     |   (All [Symbol* Symbol ...] Type)
+     |   (HMap {Keyword Type*})        ;eg (HMap {:a (Value 1), :b nil})
+     |   '{Keyword Type*}              ;eg '{:a (Value 1), :b nil}
+     |   (Vector* Type*)
+     |   '[Type*]
+     |   (Seq* Type*)
+     |   (List* Type*)
+     |   Symbol  ;class/protocol/free resolvable in context
+
+FunctionIntersection :=  ArityType
+                     |   (Fn ArityType+)
+
+ArityType :=   [FixedArgs -> Type]
+           |   [FixedArgs RestArgs * -> Type]
+           |   [FixedArgs DottedType ... Symbol -> Type]
+
+FixedArgs := Type*
+RestArgs := Type
+DottedType := Type
+

Types

Value shorthands

nil, true and false resolve to the respective singleton types for those values

Intersections

(I Type+) creates an intersection of types.

Unions

(U Type*) creates a union of types.

Functions

A function type is an ordered intersection of arity types.

There is a vector sugar for functions of one arity.

Heterogeneous Maps

Warning: Heterogeneous maps are alpha and their design is subject to change.

A heterogeneous map type represents a map that has at least a particular set of keyword keys.

clojure.core.typed=> (cf {:a 1})
+[(HMap {:a (Value 1)}) {:then tt, :else ff}]
+

This type can also be written '{:a (Value 1)}.

Lookups of known keys infer accurate types.

clojure.core.typed=> (cf (-> {:a 1} :a))
+(Value 1)
+

Currently, they are limited (but still quite useful):

  • the presence of keys is recorded, but not their absence
  • only keyword value keys are allowed.

These rules have several implications.

Absent keys

Looking up keys that are not recorded as present give inaccurate types

clojure.core.typed=> (cf (-> {:a 1} :b))
+Any
+

Non-keyword keys

Literal maps without keyword keys are inferred as APersistentMap.

clojure.core.typed=> (cf {(inc 1) 1})
+[(clojure.lang.APersistentMap clojure.core.typed/AnyInteger (Value 1)) {:then tt, :else ff}]
+

Optional keys can be defined either by constructing a union of map types, or by passing +the HMap type constructor an :optional keyword argument with a map of optional keys.

Heterogeneous Vectors

(Vector* (Value 1) (Value 2)) is a IPersistentVector of length 2, essentially +representing the value [1 2]. The type '[(Value 1) (Value 2)] is identical.

Polymorphism

The binding form All introduces a number of free variables inside a scope.

Optionally scopes a dotted variable by adding ... after the last symbol in the binder.

eg. The identity function: (All [x] [x -> x]) +eg. Introducing dotted variables: `(All [x y ...] [x y ... y -> x])

Recursive Types

Rec introduces a recursive type. It takes a vector of one symbol and a type. +The symbol is scoped to represent the entire type in the type argument.

; Type for {:op :if
+;           :test {:op :var, :var #'A}
+;           :then {:op :nil}
+;           :else {:op :false}}
+(Rec [x]
+     (U (HMap {:op (Value :if)
+               :test x
+               :then x
+               :else x})
+        (HMap {:op (Value :var)
+               :var clojure.lang.Var})
+        (HMap {:op (Value :nil)})
+        (HMap {:op (Value :false)})))))
+
+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/core_typed/user_documentation/index.html b/clones/clojure-doc.org/articles/ecosystem/core_typed/user_documentation/index.html new file mode 100644 index 00000000..85c656b9 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/core_typed/user_documentation/index.html @@ -0,0 +1,257 @@ + + + + + Clojure Guides: core.typed - User Documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Usage

Type Aliases

clojure.core.typed/def-alias defines a type alias.

(def-alias Term (I IUnifyTerms
+                   IUnifyWithNil
+                   IUnifyWithObject
+                   IUnifyWithLVar
+                   IUnifyWithSequential
+                   IUnifyWithMap
+                   IUnifyWithSet
+                   IReifyTerm
+                   IWalkTerm
+                   IOccursCheckTerm
+                   IBuildTerm))
+

Primitive Java Arrays

"Typed" arrays can be created with into-array>, which has a 2 and 3 arity version.

The correspondence between core.typed types and Java types is subtle here. Usually +into-array> accepts a core.typed type as its first argument, followed by a collection (as clojure.core/into-array).

;; `int` is the primitive int in Java. This creates a primitive array.
+(class (into-array> int [1]))
+;=> [I
+
+;; This is a Number array with nullable elements.
+(class (into-array> (U nil Number) [1]))
+;=> [Ljava.lang.Number;
+
+;; This is a Number array with non-nullable elements.
+;; Notice this generates the same type as before as Java does not distinguish
+;; non-/nullable arrays. core.typed statically disallows nil to be added
+;; as an element from any Clojure it checks.
+(class (into-array> Number [1]))
+;=> [Ljava.lang.Number;
+
+;; An array of nullable primitive ints does not make sense in Java,
+;; so it is generalised to an array of Objects.
+(class (into-array> (U nil int) [1]))
+;=> [Ljava.lang.Object;
+
+;; Unions are often generalised to Object
+(class (into-array> (U clojure.lang.Symbol Number) [1]))
+;=> [Ljava.lang.Object;
+

When more control is needed of the Java type, the 3 arity version of into-array> accepts +the Java type (in core.typed syntax) as first argument, followed by the Clojure type, and the collection.

;; Generalising to Number instead of Object.
+(class (into-array> Number (U Integer Number) [1]))
+;=> [Ljava.lang.Number;
+

The Clojure element type should be a subtype to the Java element type.

Declarations

clojure.core.typed/declare-types, clojure.core.typed/declare-names and clojure.core.typed/declare-protocols are similar +to declare in that they allow you to use types before they are defined.

(declare-datatypes Substitutions)
+(declare-protocols LVar)
+(declare-names MyAlias)
+

Checking typed namespaces

clojure.core.typed/check-ns checks the namespace that its symbol argument represents.

(check-ns 'my.ns)
+

Debugging

clojure.core.typed/print-env prints the current environment.

(let [a 1]
+  (print-env "Env:")
+  a)
+; Prints: "Env:" {:env {a (Value 1)},  ....}
+

clojure.core.typed/cf (pronounced "check form") can be used at the REPL to return the type of a form.

(cf 1)
+;=> [(Value 1) {:then [top-filter], :else [bot-filter]} empty-object]
+

Macros & Macro Definitions

Macro definitions are ignored. The type checker operates on the macroexpanded form from +the Compiler's analysis phase.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/data_processing/index.html b/clones/clojure-doc.org/articles/ecosystem/data_processing/index.html new file mode 100644 index 00000000..c1314c4d --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/data_processing/index.html @@ -0,0 +1,208 @@ + + + + + Clojure Guides: Data Processing (Help Wanted) + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Help wanted

Please follow the instructions on how to contribute and start writing over here

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on Github.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/generating_documentation/index.html b/clones/clojure-doc.org/articles/ecosystem/generating_documentation/index.html new file mode 100644 index 00000000..f8f894ff --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/generating_documentation/index.html @@ -0,0 +1,231 @@ + + + + + Clojure Guides: Generating Documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide notes some commonly-used tools for generating project +documentation.

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.4.

Overview

Projects commonly (hopefully?) have at least two types of +documentation:

  • standalone +markdown-formatted docs +in the project's doc directory
  • docstrings

There are a number of tools for generating handsome API docs from +docstrings and other project metadata.

Codox

If you'd like to generate nice-looking html API docs for your library, +use codox. Usage instructions +are in the codox readme. Running codox (it's a lein plug-in and is run +via lein codox in your project) will create a "doc" subdirectory +containing the resulting html.

Marginalia

If you'd like to render API docs side-by-side with the source code +it's documenting, use the marginalia lein +plug-in. Usage instructions +are in the readme.

Cadastre

If you'd like to generate copious raw data from a project (which +includes docstrings as well as other metadata), have a look at +cadastre.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/home.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/home.html new file mode 100644 index 00000000..40762d4e --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/home.html @@ -0,0 +1,310 @@ + + + + + Clojure Guides: java.jdbc - Getting Started + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide is intended to help you the Clojure Contrib JDBC wrapper: clojure.java.jdbc

A modern JDBC wrapper has since been written (by the same author/maintainer) -- read about next.jdbc on cljdoc.org

Contents

Overview

java.jdbc is intended to be a low-level Clojure wrapper around various Java +JDBC drivers and supports a wide range of databases. The java.jdbc source is +on GitHub and there is a dedicated java.jdbc mailing +list. The detailed java.jdbc reference is +automatically generated from the java.jdbc source.

Generally, when using java.jdbc, you will set up a data source as a "database +spec" and pass that to the various CRUD (create, read, update, delete) +functions that java.jdbc provides. These operations are detailed within the +Using SQL page, but a quick overview is provided by the +walkthrough below.

By default, each operation opens a connection and executes the SQL inside a +transaction. You can also run multiple operations against the same connection, +either within a transaction or via connection pooling, or just with a shared +connection. You can read more about reusing connections on the Reusing +Connections page.

Higher-level DSL and migration libraries

If you need more abstraction than the java.jdbc wrapper provides, you may want +to consider using a library that provides a DSL. All of the following libraries +are built on top of java.jdbc and provide such abstraction:

In particular, Korma goes beyond a SQL DSL to provide "entities" and +"relationships" (in the style of classical Object-Relational Mappers, but +without the pain).

Another common need with SQL is for database migration libraries. Some of the +more popular options are:

A brief java.jdbc walkthrough

Setting up a data source

A "database spec" is a Clojure map that specifies how to access the data +source. Most commonly, you specify the database type, the database name, +and the username and password. For example,

(def db-spec
+  {:dbtype "mysql"
+   :dbname "mydb"
+   :user "myaccount"
+   :password "secret"})
+

See Database Support below for a complete list of +databases and drivers supported by java.jdbc out of the box.

A "Hello World" Query

Querying the database can be as simple as:

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(jdbc/query db-spec ["SELECT 3*5 AS result"])
+=> {:result 15}
+

Of course, we will want to do more with our database than have it perform +simple calculations. Once we can successfully connect to it, we will likely +want to create tables and manipulate data.

Creating tables

java.jdbc provides create-table-ddl and drop-table-ddl to generate basic +CREATE TABLE and DROP TABLE DDL strings. Anything beyond that can be +constructed manually as a string.

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(def fruit-table-ddl
+  (jdbc/create-table-ddl :fruit
+                         [[:name "varchar(32)"]
+                          [:appearance "varchar(32)"]
+                          [:cost :int]
+                          [:grade :real]]))
+

We can use the function db-do-commands to create our table and indexes in a +single transaction:

(jdbc/db-do-commands db-spec
+                     [fruit-table-ddl
+                      "CREATE INDEX name_ix ON fruit ( name );"])
+

For more details on DDL functionality within java.jdbc, see the Using DDL and +Metadata Guide.

Querying the database

The four basic CRUD operations java.jdbc provides are:

(jdbc/insert! db-spec :table {:col1 42 :col2 "123"})               ;; Create
+(jdbc/query   db-spec ["SELECT * FROM table WHERE id = ?" 13])     ;; Read
+(jdbc/update! db-spec :table {:col1 77 :col2 "456"} ["id = ?" 13]) ;; Update
+(jdbc/delete! db-spec :table ["id = ?" 13])                        ;; Delete
+

The table name can be specified as a string or a keyword.

insert! takes a single record in hash map form to insert. insert! can also +take a vector of column names (as strings or keywords), followed by a vector of +column values to insert into those respective columns, much like an INSERT +statement in SQL. Entries in the map that have the value nil will cause +NULL values to be inserted into the corresponding columns.

If you wish to insert multiple rows (in hash map form) at once, you can use +insert-multi!; however, insert-multi! will write a separate insertion +statement for each row, so it is suggested you use the column-based form of +insert-multi! over the row-based form. Passing multiple column values to +insert-multi! will generate a single batched insertion statement and yield +better performance.

query allows us to run selection queries on the database. Since you provide +the query string directly, you have as much flexibility as you like to perform +complex queries.

update! takes a map of columns to update, with their new values, and a SQL +clause used to select which rows to update (prepended by WHERE in the +generated SQL). As with insert!, nil values in the map cause the +corresponding columns to be set to NULL.

delete! takes a SQL clause used to select which rows to delete, similar to +update!.

By default, the table name and column names are converted to strings +corresponding to the keyword names in the underlying SQL. We can control how we +transform keywords into SQL names using an optional :entities argument which +is described in more detail in the Using SQL section.

Dropping our tables

To clean out the database from our example, we can generate a the command to +drop the fruit table:

(def drop-fruit-table-ddl (jdbc/drop-table-ddl :fruit))
+

Ensure you tear down your tables and indexes in the opposite order of creation:

(jdbc/db-do-commands db-spec
+                     ["DROP INDEX name_ix;"
+                      drop-fruit-table-ddl])
+

These are all the commands we need to write a simple migration for our database!

Database Support

Out of the box, java.jdbc understands the following :dbtype values (with +their default class names):

  • "derby" - org.apache.derby.jdbc.EmbeddedDriver
  • "h2" - org.h2.Driver
  • "h2:mem" - org.h2.Driver
  • "hsqldb" or "hsql" - org.hsqldb.jdbcDriver
  • "jtds:sqlserver" or "jtds" - net.sourceforge.jtds.jdbc.Driver
  • "mysql" - com.mysql.jdbc.Driver
  • "oracle:oci" - oracle.jdbc.OracleDriver
  • "oracle:thin" or "oracle" - oracle.jdbc.OracleDriver
  • "postgresql" or "postgres" - org.postgresql.Driver
  • "pgsql" - com.impossibl.postgres.jdbc.PGDriver
  • "redshift" - com.amazon.redshift.jdbc.Driver
  • "sqlite" - org.sqlite.JDBC
  • "sqlserver" - "mssql" - com.microsoft.sqlserver.jdbc.SQLServerDriver

You must specify the appropriate JDBC driver dependency in your project -- these +drivers are not included with java.jdbc.

You can overide the default class name by specifying :classname as well as +:dbtype.

For databases that require a hostname or IP address, java.jdbc assumes +"127.0.0.1" but that can be overidden with the :host option.

For databases that require a port, java.jdbc has the following defaults, +which can be overridden with the :port option:

  • Microsoft SQL Server - 1433
  • MySQL - 3306
  • Oracle - 1521
  • PostgreSQL - 5432

Some databases require a different format for the "database spec". Here is an example +that was required for an in-memory H2 database prior +to java.jdbc release 0.7.6:

(def db-spec
+  {:classname   "org.h2.Driver"
+   :subprotocol "h2:mem"                  ; the prefix `jdbc:` is added automatically
+   :subname     "demo;DB_CLOSE_DELAY=-1"  ; `;DB_CLOSE_DELAY=-1` very important!!!
+                    ; http://www.h2database.com/html/features.html#in_memory_databases
+   :user        "sa"                      ; default "system admin" user
+   :password    ""                        ; default password => empty string
+  })
+

This is the most general form of database spec, that allows you to control each +piece of the JDBC connection URL that would be created.

Note: as of java.jdbc 0.7.6, in-memory H2 databases are supported directly +via the simple spec form:

(def db-spec
+  {:dbtype "h2:mem"
+   :dbname "mydb"})
+

For file-based databases, such as H2, Derby, SQLite etc, the :dbname will +specify the filename:

(def db-spec
+  {:dbtype "h2"
+   :dbname "/path/to/my/database"})
+

More detailed java.jdbc documentation

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/home/index.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/home/index.html new file mode 100644 index 00000000..ffd8cfb2 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/home/index.html @@ -0,0 +1,310 @@ + + + + + Clojure Guides: java.jdbc - Getting Started + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide is intended to help you the Clojure Contrib JDBC wrapper: clojure.java.jdbc

A modern JDBC wrapper has since been written (by the same author/maintainer) -- read about next.jdbc on cljdoc.org

Contents

Overview

java.jdbc is intended to be a low-level Clojure wrapper around various Java +JDBC drivers and supports a wide range of databases. The java.jdbc source is +on GitHub and there is a dedicated java.jdbc mailing +list. The detailed java.jdbc reference is +automatically generated from the java.jdbc source.

Generally, when using java.jdbc, you will set up a data source as a "database +spec" and pass that to the various CRUD (create, read, update, delete) +functions that java.jdbc provides. These operations are detailed within the +Using SQL page, but a quick overview is provided by the +walkthrough below.

By default, each operation opens a connection and executes the SQL inside a +transaction. You can also run multiple operations against the same connection, +either within a transaction or via connection pooling, or just with a shared +connection. You can read more about reusing connections on the Reusing +Connections page.

Higher-level DSL and migration libraries

If you need more abstraction than the java.jdbc wrapper provides, you may want +to consider using a library that provides a DSL. All of the following libraries +are built on top of java.jdbc and provide such abstraction:

In particular, Korma goes beyond a SQL DSL to provide "entities" and +"relationships" (in the style of classical Object-Relational Mappers, but +without the pain).

Another common need with SQL is for database migration libraries. Some of the +more popular options are:

A brief java.jdbc walkthrough

Setting up a data source

A "database spec" is a Clojure map that specifies how to access the data +source. Most commonly, you specify the database type, the database name, +and the username and password. For example,

(def db-spec
+  {:dbtype "mysql"
+   :dbname "mydb"
+   :user "myaccount"
+   :password "secret"})
+

See Database Support below for a complete list of +databases and drivers supported by java.jdbc out of the box.

A "Hello World" Query

Querying the database can be as simple as:

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(jdbc/query db-spec ["SELECT 3*5 AS result"])
+=> {:result 15}
+

Of course, we will want to do more with our database than have it perform +simple calculations. Once we can successfully connect to it, we will likely +want to create tables and manipulate data.

Creating tables

java.jdbc provides create-table-ddl and drop-table-ddl to generate basic +CREATE TABLE and DROP TABLE DDL strings. Anything beyond that can be +constructed manually as a string.

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(def fruit-table-ddl
+  (jdbc/create-table-ddl :fruit
+                         [[:name "varchar(32)"]
+                          [:appearance "varchar(32)"]
+                          [:cost :int]
+                          [:grade :real]]))
+

We can use the function db-do-commands to create our table and indexes in a +single transaction:

(jdbc/db-do-commands db-spec
+                     [fruit-table-ddl
+                      "CREATE INDEX name_ix ON fruit ( name );"])
+

For more details on DDL functionality within java.jdbc, see the Using DDL and +Metadata Guide.

Querying the database

The four basic CRUD operations java.jdbc provides are:

(jdbc/insert! db-spec :table {:col1 42 :col2 "123"})               ;; Create
+(jdbc/query   db-spec ["SELECT * FROM table WHERE id = ?" 13])     ;; Read
+(jdbc/update! db-spec :table {:col1 77 :col2 "456"} ["id = ?" 13]) ;; Update
+(jdbc/delete! db-spec :table ["id = ?" 13])                        ;; Delete
+

The table name can be specified as a string or a keyword.

insert! takes a single record in hash map form to insert. insert! can also +take a vector of column names (as strings or keywords), followed by a vector of +column values to insert into those respective columns, much like an INSERT +statement in SQL. Entries in the map that have the value nil will cause +NULL values to be inserted into the corresponding columns.

If you wish to insert multiple rows (in hash map form) at once, you can use +insert-multi!; however, insert-multi! will write a separate insertion +statement for each row, so it is suggested you use the column-based form of +insert-multi! over the row-based form. Passing multiple column values to +insert-multi! will generate a single batched insertion statement and yield +better performance.

query allows us to run selection queries on the database. Since you provide +the query string directly, you have as much flexibility as you like to perform +complex queries.

update! takes a map of columns to update, with their new values, and a SQL +clause used to select which rows to update (prepended by WHERE in the +generated SQL). As with insert!, nil values in the map cause the +corresponding columns to be set to NULL.

delete! takes a SQL clause used to select which rows to delete, similar to +update!.

By default, the table name and column names are converted to strings +corresponding to the keyword names in the underlying SQL. We can control how we +transform keywords into SQL names using an optional :entities argument which +is described in more detail in the Using SQL section.

Dropping our tables

To clean out the database from our example, we can generate a the command to +drop the fruit table:

(def drop-fruit-table-ddl (jdbc/drop-table-ddl :fruit))
+

Ensure you tear down your tables and indexes in the opposite order of creation:

(jdbc/db-do-commands db-spec
+                     ["DROP INDEX name_ix;"
+                      drop-fruit-table-ddl])
+

These are all the commands we need to write a simple migration for our database!

Database Support

Out of the box, java.jdbc understands the following :dbtype values (with +their default class names):

  • "derby" - org.apache.derby.jdbc.EmbeddedDriver
  • "h2" - org.h2.Driver
  • "h2:mem" - org.h2.Driver
  • "hsqldb" or "hsql" - org.hsqldb.jdbcDriver
  • "jtds:sqlserver" or "jtds" - net.sourceforge.jtds.jdbc.Driver
  • "mysql" - com.mysql.jdbc.Driver
  • "oracle:oci" - oracle.jdbc.OracleDriver
  • "oracle:thin" or "oracle" - oracle.jdbc.OracleDriver
  • "postgresql" or "postgres" - org.postgresql.Driver
  • "pgsql" - com.impossibl.postgres.jdbc.PGDriver
  • "redshift" - com.amazon.redshift.jdbc.Driver
  • "sqlite" - org.sqlite.JDBC
  • "sqlserver" - "mssql" - com.microsoft.sqlserver.jdbc.SQLServerDriver

You must specify the appropriate JDBC driver dependency in your project -- these +drivers are not included with java.jdbc.

You can overide the default class name by specifying :classname as well as +:dbtype.

For databases that require a hostname or IP address, java.jdbc assumes +"127.0.0.1" but that can be overidden with the :host option.

For databases that require a port, java.jdbc has the following defaults, +which can be overridden with the :port option:

  • Microsoft SQL Server - 1433
  • MySQL - 3306
  • Oracle - 1521
  • PostgreSQL - 5432

Some databases require a different format for the "database spec". Here is an example +that was required for an in-memory H2 database prior +to java.jdbc release 0.7.6:

(def db-spec
+  {:classname   "org.h2.Driver"
+   :subprotocol "h2:mem"                  ; the prefix `jdbc:` is added automatically
+   :subname     "demo;DB_CLOSE_DELAY=-1"  ; `;DB_CLOSE_DELAY=-1` very important!!!
+                    ; http://www.h2database.com/html/features.html#in_memory_databases
+   :user        "sa"                      ; default "system admin" user
+   :password    ""                        ; default password => empty string
+  })
+

This is the most general form of database spec, that allows you to control each +piece of the JDBC connection URL that would be created.

Note: as of java.jdbc 0.7.6, in-memory H2 databases are supported directly +via the simple spec form:

(def db-spec
+  {:dbtype "h2:mem"
+   :dbname "mydb"})
+

For file-based databases, such as H2, Derby, SQLite etc, the :dbname will +specify the filename:

(def db-spec
+  {:dbtype "h2"
+   :dbname "/path/to/my/database"})
+

More detailed java.jdbc documentation

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections.html new file mode 100644 index 00000000..98c3eae7 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections.html @@ -0,0 +1,289 @@ + + + + + Clojure Guides: java.jdbc - How to reuse database connections + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Contents

Reusing Connections

Since you rarely want every database operation to create a new connection, +there are two ways to reuse connections:

  • Grouping Operations using with-db-connection: If you don't want to deal +with a connection pooling library, you can use this macro to automatically open a +connection and maintain it for a body of code, with each operation executed in its +own transaction, then close the connection.
  • Grouping Operations using with-db-transaction: If you want to execute multiple +operations in a single transaction, you can use this macro to automatically open a +connection, start a transaction, execute multiple operations, commit the transaction, +and then close the connection.
  • Connection Pooling: This is the recommended approach and is fairly +straightforward, with a number of connection pooling libraries available. See +How To Use Connection Pooling below for more information.

Using with-db-connection

This macro provides the simplest way to reuse connections, without having to +add a dependency on an external connection pooling library:

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(jdbc/with-db-connection [db-con db-spec]
+  (let [;; fetch some rows using this connection
+        rows (jdbc/query db-con ["SELECT * FROM table WHERE id = ?" 42])]
+    ;; insert a copy of the first row using the same connection
+    (jdbc/insert! db-con :table (dissoc (first rows) :id))))
+

The query and the insert! are each run in their own transaction and committed +if they succeed. If you want to run multiple operations in a single transaction +see the next section about with-db-transaction.

Using with-db-transaction

This macro provides a way to reuse connections, committing or rolling back +multiple operations in a single transaction:

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(jdbc/with-db-transaction [t-con db-spec]
+  (let [;; fetch some rows using this connection
+        rows (jdbc/query t-con ["SELECT * FROM table WHERE id = ?" 42])]
+    ;; insert a copy of the first row using the same connection
+    (jdbc/insert! t-con :table (dissoc (first rows) :id))))
+

If any operation inside with-db-transaction fails (throws an exception), then +all of the operations performed so far are rolled back. If all the operations +succeed, then the entire transaction is committed.

Transactions are not nested (since not all databases support that) so if this is +used another active transaction, the outer transaction (and connection) are used +as-is. If the isolation levels of the outer and inner transaction do not match +you will get an IllegalStateException.

See also db-set-rollback-only!, db-unset-rollback-only!, and db-is-rollback-only +for additional control over the commit/rollback behavior of the enclosing transaction.

Using Connection Pooling

java.jdbc does not provide connection pooling directly but it is relatively +easy to add to your project. There are several connection pooling libraries out +there, but here we will provide instructions for the popular c3p0 library.

The basic idea is to add your chosen connection pooling library to your +project, import the appropriate class(es), define a function that consumes a +"database spec" and produces a map containing a :datasource key whose value +is the constructed pooled DataSource object, then use that hash map in place of your +bare db-spec variable. You are responsible for creating the pooled data +source object and passing the map containing it into any functions that need a +database connection.

Using the c3p0 library

For more information on c3p0, consult the c3p0 +documentation.

If you're using Leiningen, you can add the following to your dependencies:

[com.mchange/c3p0 "0.9.5.2"]  ;; check the documentation for latest version
+

For a Maven-based project, you would add:

<dependency>
+  <groupId>com.mchange</groupId>
+  <artifactId>c3p0</artifactId>
+  <version>0.9.5.2</version>
+</dependency>
+

Create the pooled datasource from your db-spec

Define your db-spec using the long form, for example (for MySQL):

(def db-spec
+  {:classname "com.mysql.jdbc.Driver"
+   :subprotocol "mysql"
+   :subname "//127.0.0.1:3306/mydb"
+   :user "myaccount"
+   :password "secret"})
+

We have to use the long form here because c3p0 operates on the class name, subprotocol, +and subname elements. Of course, you don't really need to define a db-spec here +because you're not going to use it with java.jdbc directly, only with c3p0.

Import the c3p0 class as part of your namespace declaration, for example:

(ns example.db
+  (:import (com.mchange.v2.c3p0 ComboPooledDataSource)))
+

Define a function that creates a pooled datasource:

(defn pool
+  [spec]
+  (let [cpds (doto (ComboPooledDataSource.)
+               (.setDriverClass (:classname spec))
+               (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
+               (.setUser (:user spec))
+               (.setPassword (:password spec))
+               ;; expire excess connections after 30 minutes of inactivity:
+               (.setMaxIdleTimeExcessConnections (* 30 60))
+               ;; expire connections after 3 hours of inactivity:
+               (.setMaxIdleTime (* 3 60 60)))]
+    {:datasource cpds}))
+

Now you can create a single connection pool:

(def pooled-db (delay (pool db-spec)))
+
+(defn db-connection [] @pooled-db)
+

And then call (db-connection) wherever you need access to it. If you're using +a component lifecycle for your +application, you won't need pooled-db or db-connection. You'll just create +(pool db-spec) as part of your application's initialization and pass it +around as part of your system configuration.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections/index.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections/index.html new file mode 100644 index 00000000..16ba78d3 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections/index.html @@ -0,0 +1,289 @@ + + + + + Clojure Guides: java.jdbc - How to reuse database connections + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Contents

Reusing Connections

Since you rarely want every database operation to create a new connection, +there are two ways to reuse connections:

  • Grouping Operations using with-db-connection: If you don't want to deal +with a connection pooling library, you can use this macro to automatically open a +connection and maintain it for a body of code, with each operation executed in its +own transaction, then close the connection.
  • Grouping Operations using with-db-transaction: If you want to execute multiple +operations in a single transaction, you can use this macro to automatically open a +connection, start a transaction, execute multiple operations, commit the transaction, +and then close the connection.
  • Connection Pooling: This is the recommended approach and is fairly +straightforward, with a number of connection pooling libraries available. See +How To Use Connection Pooling below for more information.

Using with-db-connection

This macro provides the simplest way to reuse connections, without having to +add a dependency on an external connection pooling library:

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(jdbc/with-db-connection [db-con db-spec]
+  (let [;; fetch some rows using this connection
+        rows (jdbc/query db-con ["SELECT * FROM table WHERE id = ?" 42])]
+    ;; insert a copy of the first row using the same connection
+    (jdbc/insert! db-con :table (dissoc (first rows) :id))))
+

The query and the insert! are each run in their own transaction and committed +if they succeed. If you want to run multiple operations in a single transaction +see the next section about with-db-transaction.

Using with-db-transaction

This macro provides a way to reuse connections, committing or rolling back +multiple operations in a single transaction:

(ns dbexample
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec ... ) ;; see above
+
+(jdbc/with-db-transaction [t-con db-spec]
+  (let [;; fetch some rows using this connection
+        rows (jdbc/query t-con ["SELECT * FROM table WHERE id = ?" 42])]
+    ;; insert a copy of the first row using the same connection
+    (jdbc/insert! t-con :table (dissoc (first rows) :id))))
+

If any operation inside with-db-transaction fails (throws an exception), then +all of the operations performed so far are rolled back. If all the operations +succeed, then the entire transaction is committed.

Transactions are not nested (since not all databases support that) so if this is +used another active transaction, the outer transaction (and connection) are used +as-is. If the isolation levels of the outer and inner transaction do not match +you will get an IllegalStateException.

See also db-set-rollback-only!, db-unset-rollback-only!, and db-is-rollback-only +for additional control over the commit/rollback behavior of the enclosing transaction.

Using Connection Pooling

java.jdbc does not provide connection pooling directly but it is relatively +easy to add to your project. There are several connection pooling libraries out +there, but here we will provide instructions for the popular c3p0 library.

The basic idea is to add your chosen connection pooling library to your +project, import the appropriate class(es), define a function that consumes a +"database spec" and produces a map containing a :datasource key whose value +is the constructed pooled DataSource object, then use that hash map in place of your +bare db-spec variable. You are responsible for creating the pooled data +source object and passing the map containing it into any functions that need a +database connection.

Using the c3p0 library

For more information on c3p0, consult the c3p0 +documentation.

If you're using Leiningen, you can add the following to your dependencies:

[com.mchange/c3p0 "0.9.5.2"]  ;; check the documentation for latest version
+

For a Maven-based project, you would add:

<dependency>
+  <groupId>com.mchange</groupId>
+  <artifactId>c3p0</artifactId>
+  <version>0.9.5.2</version>
+</dependency>
+

Create the pooled datasource from your db-spec

Define your db-spec using the long form, for example (for MySQL):

(def db-spec
+  {:classname "com.mysql.jdbc.Driver"
+   :subprotocol "mysql"
+   :subname "//127.0.0.1:3306/mydb"
+   :user "myaccount"
+   :password "secret"})
+

We have to use the long form here because c3p0 operates on the class name, subprotocol, +and subname elements. Of course, you don't really need to define a db-spec here +because you're not going to use it with java.jdbc directly, only with c3p0.

Import the c3p0 class as part of your namespace declaration, for example:

(ns example.db
+  (:import (com.mchange.v2.c3p0 ComboPooledDataSource)))
+

Define a function that creates a pooled datasource:

(defn pool
+  [spec]
+  (let [cpds (doto (ComboPooledDataSource.)
+               (.setDriverClass (:classname spec))
+               (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
+               (.setUser (:user spec))
+               (.setPassword (:password spec))
+               ;; expire excess connections after 30 minutes of inactivity:
+               (.setMaxIdleTimeExcessConnections (* 30 60))
+               ;; expire connections after 3 hours of inactivity:
+               (.setMaxIdleTime (* 3 60 60)))]
+    {:datasource cpds}))
+

Now you can create a single connection pool:

(def pooled-db (delay (pool db-spec)))
+
+(defn db-connection [] @pooled-db)
+

And then call (db-connection) wherever you need access to it. If you're using +a component lifecycle for your +application, you won't need pooled-db or db-connection. You'll just create +(pool db-spec) as part of your application's initialization and pass it +around as part of your system configuration.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl.html new file mode 100644 index 00000000..2ea8369d --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl.html @@ -0,0 +1,249 @@ + + + + + Clojure Guides: java.jdbc - Using DDL and Metadata + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Contents

Using DDL

DDL operations can be executed using the db-do-commands function. The general +approach is:

(jdbc/db-do-commands db-spec [sql-command-1 sql-command-2 .. sql-command-n])
+

The commands are executed as a single, batched statement, wrapped in a +transaction. If you want to avoid the transaction, use this approach:

(jdbc/db-do-commands db-spec false [sql-command-1 sql-command-2 .. sql-command-n])
+

This is necessary for some databases that do not allow DDL operations to be +wrapped in a transaction.

Creating tables

For the common operations of creating and dropping tables, java.jdbc provides a +little assistance that recognizes :entities so you can use keywords (or +strings) and have your chosen naming strategy applied, just as you can for +several of the SQL functions.

(jdbc/create-table-ddl :fruit
+                       [[:name "varchar(32)" :primary :key]
+                        [:appearance "varchar(32)"]
+                        [:cost :int]
+                        [:grade :real]]
+                       {:table-spec "ENGINE=InnoDB"
+                        :entities clojure.string/upper-case})
+

This will generate:

CREATE TABLE FRUIT
+    (NAME varchar(32) primary key,
+     APPEARANCE varchar(32),
+     COST int,
+     GRADE real) ENGINE=InnoDB
+

which you can pass to db-do-commands.

create-table-ddl also supports a conditional? option which can be a simple +Boolean, which, if true, will add IF NOT EXISTS before the table name. If +that syntax doesn't work for your database, you can pass a string that will be +used instead. If that isn't enough, you can pass a function of two arguments: +the first argument will be the table name and the second argument will be the +DDL string (this approach is needed for Microsoft SQL Server).

Dropping tables

Similarly there is a drop-table-ddl function which takes a table name and an +optional :entities option to generate DDL to drop a table.

(jdbc/drop-table-ddl :fruit) ; drop table fruit
+(jdbc/drop-table-ddl :fruit {:entities clojure.string/upper-case}) ; drop table FRUIT
+

This will generate:

DROP TABLE FRUIT
+

drop-table-ddl also supports a conditional? option which can be a simple +Boolean, which, if true, will add IF EXISTS before the table name. If +that syntax doesn't work for your database, you can pass a string that will be +used instead. If that isn't enough, you can pass a function of two arguments: +the first argument will be the table name and the second argument will be the +DDL string (this approach is needed for Microsoft SQL Server).

Accessing metadata

java.jdbc provides two functions for working with database metadata:

  • with-db-metadata for creating an active metadata object backed by an open +connection
  • metadata-result for turning metadata results into Clojure data structures

For example:

(jdbc/with-db-metadata [md db-spec]
+  (jdbc/metadata-result (.getTables md nil nil nil (into-array ["TABLE" "VIEW"]))))
+

This returns a sequence of maps describing all the tables and views in the +current database. metadata-result only transforms ResultSet objects, other +results are returned as-is. metadata-result can also accept an options map +containing :identifiers and :as-arrays?, like the query function, +and those options control how the metatadata is transformed and/or returned.

Both with-db-metadata and metadata-result can accept an options hash map +which will be passed through various java.jdbc functions (get-connections +for the former and result-set-seq for the latter).

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl/index.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl/index.html new file mode 100644 index 00000000..d2bd8d35 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl/index.html @@ -0,0 +1,249 @@ + + + + + Clojure Guides: java.jdbc - Using DDL and Metadata + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Contents

Using DDL

DDL operations can be executed using the db-do-commands function. The general +approach is:

(jdbc/db-do-commands db-spec [sql-command-1 sql-command-2 .. sql-command-n])
+

The commands are executed as a single, batched statement, wrapped in a +transaction. If you want to avoid the transaction, use this approach:

(jdbc/db-do-commands db-spec false [sql-command-1 sql-command-2 .. sql-command-n])
+

This is necessary for some databases that do not allow DDL operations to be +wrapped in a transaction.

Creating tables

For the common operations of creating and dropping tables, java.jdbc provides a +little assistance that recognizes :entities so you can use keywords (or +strings) and have your chosen naming strategy applied, just as you can for +several of the SQL functions.

(jdbc/create-table-ddl :fruit
+                       [[:name "varchar(32)" :primary :key]
+                        [:appearance "varchar(32)"]
+                        [:cost :int]
+                        [:grade :real]]
+                       {:table-spec "ENGINE=InnoDB"
+                        :entities clojure.string/upper-case})
+

This will generate:

CREATE TABLE FRUIT
+    (NAME varchar(32) primary key,
+     APPEARANCE varchar(32),
+     COST int,
+     GRADE real) ENGINE=InnoDB
+

which you can pass to db-do-commands.

create-table-ddl also supports a conditional? option which can be a simple +Boolean, which, if true, will add IF NOT EXISTS before the table name. If +that syntax doesn't work for your database, you can pass a string that will be +used instead. If that isn't enough, you can pass a function of two arguments: +the first argument will be the table name and the second argument will be the +DDL string (this approach is needed for Microsoft SQL Server).

Dropping tables

Similarly there is a drop-table-ddl function which takes a table name and an +optional :entities option to generate DDL to drop a table.

(jdbc/drop-table-ddl :fruit) ; drop table fruit
+(jdbc/drop-table-ddl :fruit {:entities clojure.string/upper-case}) ; drop table FRUIT
+

This will generate:

DROP TABLE FRUIT
+

drop-table-ddl also supports a conditional? option which can be a simple +Boolean, which, if true, will add IF EXISTS before the table name. If +that syntax doesn't work for your database, you can pass a string that will be +used instead. If that isn't enough, you can pass a function of two arguments: +the first argument will be the table name and the second argument will be the +DDL string (this approach is needed for Microsoft SQL Server).

Accessing metadata

java.jdbc provides two functions for working with database metadata:

  • with-db-metadata for creating an active metadata object backed by an open +connection
  • metadata-result for turning metadata results into Clojure data structures

For example:

(jdbc/with-db-metadata [md db-spec]
+  (jdbc/metadata-result (.getTables md nil nil nil (into-array ["TABLE" "VIEW"]))))
+

This returns a sequence of maps describing all the tables and views in the +current database. metadata-result only transforms ResultSet objects, other +results are returned as-is. metadata-result can also accept an options map +containing :identifiers and :as-arrays?, like the query function, +and those options control how the metatadata is transformed and/or returned.

Both with-db-metadata and metadata-result can accept an options hash map +which will be passed through various java.jdbc functions (get-connections +for the former and result-set-seq for the latter).

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html new file mode 100644 index 00000000..fb1ccf5f --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html @@ -0,0 +1,510 @@ + + + + + Clojure Guides: java.jdbc - Manipulating data with SQL + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Contents

Using SQL

Here are some examples of using java.jdbc to manipulate data with SQL. +These examples assume a simple table called fruit (see Using DDL and +Metadata). These examples all assume the following in your +ns declaration:

(:require [clojure.java.jdbc :as jdbc])
+

Reading and processing rows

java.jdbc provides a simple query function to allow you to read rows from +tables, as well as optionally performing processing on them at the same time.

Reading rows

To obtain a fully realized result set as a sequence of maps, you can use +query with a vector containing the SQL string and any parameters needed by +the SQL:

(jdbc/query db-spec ["SELECT * FROM fruit"])
+;; ({:id 1 :name "Apple" :appearance "red" :cost 59 :grade 87}
+;;  {:id 2 :name "Banana" :appearance "yellow" :cost 29 :grade 92.2}
+;;  ...)
+
+(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50])
+;; ({:id 2 :name "Banana" :appearance "yellow" :cost 29 :grade 92.2}
+;;  ...)
+

You can also return the result set as a sequence of vectors. The first vector +will contain the column names, and each subsequent vector will represent a row +of data with values in the same order as the columns.

(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]
+         {:as-arrays? true})
+;; ([:id :name :appearance :cost :grade]
+;;  [2 "Banana" "yellow" 29 92.2]
+;;  ...)
+

Processing a result set lazily

Since query returns a fully realized result set, it can be difficult to +process very large results. Fortunately, java.jdbc provides a number of ways to process a +large result set lazily while the connection is open, either by passing a function via +the :result-set-fn option or, since release 0.7.0, via reducible-query.

query and :result-set-fn

If you are using release 0.7.0 or later, consider using reducible-query instead -- see below.

For :result-set-fn, the function you pass must force +realization of the result to avoid the connection closing while the result set +is still being processed. A reduce-based function is a good choice.

(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]
+            {:result-set-fn (fn [rs]
+                              (reduce (fn [total row-map]
+                                        (+ total (:cost row-map)))
+                              0 rs))})
+;; produces the total cost of all the cheap fruits: 437
+

Of course, a simple sum like this could be computed directly in SQL instead:

(jdbc/query db-spec ["SELECT SUM(cost) FROM fruit WHERE cost < ?" 50]
+            {:result-set-fn first})
+;; {:sum(cost) 437}
+

We know we will only get one row back so passing first to :result-set-fn is +a quick way to get just that row.

Remember that if you also specify :as-arrays? true, your result set function +will be passed a sequence of vectors in which the first vector contains the +column names and subsequent vectors represent the values in the rows, matching +the order of the column names.

reducible-query

This is the recommended approach since release 0.7.0 but it does come with a few +restrictions:

You cannot use any of the following options that query accepts: +as-arrays?, :explain, :explain-fn, :result-set-fn, or :row-fn.

On the other hand, you have access to a much faster way to process result sets: +you can specify :raw? true and no conversion from Java's ResultSet to +Clojure's sequence of hash maps will be performed. In particular, it's as if you +specified :identifiers identity :keywordize? false :qualifier nil, and the +sequence representation of each row is not available. That means no keys, +no vals, no seq calls, just simple key lookup (for convenience, you can +still use keyword lookup for columns, but you can also call get with either a +string or a keyword).

So how does this work? reducible-query produces a clojure.lang.IReduce which, +when reduced with a function f, performs the query and reduces the ResultSet +using f, opening and closing the connection and/or transaction during the +reduction. For example:

;; our reducing function requires two arguments: we must provide initial val
+(reduce (fn [total {:keys [cost]}] (+ total cost))
+        0
+        (jdbc/reducible-query db-spec
+                              ["SELECT * FROM fruit WHERE cost < ?" 50]
+                              {:raw? true}))
+;; separating the key selection from the reducing function: we can omit val
+(transduce (map :cost)
+           + ; can be called with 0, 1, or 2 arguments!
+           (jdbc/reducible-query db-spec
+                                 ["SELECT * FROM fruit WHERE cost < ?" 50]
+                                 {:raw? true}))
+;; 437
+

Since reducible-query doesn't actually run the query until you reduce its result, +you can create it once and run it as many times as you want. This will avoid the +overhead of option and parameter validation and handling for repeated reductions, +since those are performed just once in the call to reducible-query. Note that +the SQL parameters are fixed by that call, so this only works for running the +identical query multiple times.

A reducible companion to result-set-seq also exists, in case you already have +a Java ResultSet and want to create a clojure.lang.IReduce. reducible-result-set +accept almost the same options as result-set-seq: identifiers, keywordize?, +qualifier, and read-columns. It does not accept as-arrays? (for the same +reason that reducible-query does not). Unlike result-set-seq, which produces +a lazy sequence that can be consumed multiple times (with the first pass realizing +it for subsequent passes), reducible-result-set is reducible just once: the +underlying ResultSet is mutable and is consumed during the first reduction!

It should go without saying that both reducible-query and +reducible-result-set respect reduced / reduced?.

Additional Options?

Note: some databases require additional options to be passed in to ensure that +result sets are chunked and lazy. In particular, you may need to pass +:auto-commit?, set appropriately, as an option to whichever function will open your database +connection (with-db-connection, with-db-transaction, or the query / reducible-query itself +if you are passing a bare database spec and expecting query / reducible-query to open and close +the connection directly). You may also need to specify :fetch-size, :result-type, +and possibly other options -- consult your database's documentation for the JDBC +driver you are using.

Processing each row lazily

As seen above, using reduce, transduce, etc with a reducible-query allow +you to easily and efficiently process each row as you process the entire +result set, but sometimes you just want a sequence of transformed rows.

We can process each row with the :row-fn option. Again, like with :result-set-fn, +we pass a function but this time it will be +invoked on each row, as the result set is realized.

(jdbc/query db-spec ["SELECT name FROM fruit WHERE cost < ?" 50]
+            {:row-fn :name})
+;; ("Apple" "Banana" ...)
+

The result is still a fully realized sequence, but each row has been +transformed by the :name function you passed in.

You can combine this with :result-set-fn to simplify processing of result +sets:

(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]
+            {:row-fn :cost
+             :result-set-fn (partial reduce +)})
+;; produces the total cost of all the cheap fruits
+

or:

(jdbc/query db-spec ["SELECT SUM(cost) AS total FROM fruit WHERE cost < ?" 50]
+            {:row-fn :total
+             :result-set-fn first})
+;; produces the same result, via SQL
+

Here is an example that manipulates rows to add computed columns:

(defn add-tax [row] (assoc row :tax (* 0.08 (:cost row))))
+
+(jdbc/query db-spec ["SELECT * FROM fruit"]
+            {:row-fn add-tax})
+;; produces all the rows with a new :tax column added
+

All of the above can be achieved via reducible-query and the appropriate +reducing function and/or transducer, but with those simple row/result set +functions, the result is often longer / uglier:

(into [] (map :name) (jdbc/reducible-query db-spec ["SELECT name FROM fruit WHERE cost < ?" 50]))
+(transduce (map :cost) + (jdbc/reducible-query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]))
+;; :row-fn :total :result-set-fn first left as an exercise for the reader!
+(into [] (map add-tax) (jdbc/reducible-query db-spec ["SELECT * FROM fruit"]))
+

If the result set is likely to be large and the reduction can use a :raw? true +result set, reducible-query may be worth the verbosity for the performance gain.

Inserting data

Rows (and partial rows) can be inserted easily using the insert! function. +You can insert a single row, or multiple rows. Depending on how you call +insert!, the insertion will be done either through multiple SQL statements or +through a single, batched SQL statement. That will also determine whether or +not you get back any generated keys.

If you need a more complex form of insertion, you can use execute! and, if +your database / driver supports it, you can pass :return-keys as an option +to get back the generated keys. As of java.jdbc 0.7.6, this can be a vector +of column names to return (for drivers that support that) or a simple Boolean.

Inserting a row

If you want to insert a single row (or partial row) and get back the generated +keys, you can use insert! and specify the columns and their values as a map. +This performs a single insert statement. A single-element sequence containing a +map of the generated keys will be returned.

(jdbc/insert! db-spec :fruit {:name "Pear" :appearance "green" :cost 99})
+;; returns a database-specific map as the only element of a sequence, e.g.,
+;; ({:generated_key 50}) might be returned for MySQL
+

Not all databases are able to return generated keys from an insert.

Inserting multiple rows

There are two ways to insert multiple rows: as a sequence of maps, or as a +sequence of vectors. In the former case, multiple inserts will be performed and +a map of the generated keys will be returned for each insert (as a sequence). +In the latter case, a single, batched insert will be performed and a sequence +of row insert counts will be returned (generally a sequence of ones). The latter +approach is likely to be substantially faster if you are inserting a large number +of rows.

If you use insert-multi! and specify each row as a map of columns and their values, +then you can specify a mixture of complete and partial rows, and you will get +back the generated keys for each row (assuming the database has that +capability).

(jdbc/insert-multi! db-spec :fruit
+                    [{:name "Pomegranate" :appearance "fresh" :cost 585}
+                     {:name "Kiwifruit" :grade 93}])
+;; returns a sequence of database-specific maps, e.g., for MySQL:
+;; ({generated_key 51} {generated_key 52})
+

If you use insert-multi! and specify the columns you wish to insert followed by +each row as a vector of column values, then you must specify the same columns +in each row, and you will not get generated keys back, just row counts. If you +wish to insert complete rows, you may omit the column name vector (passing +nil instead) but your rows must match the natural order of columns in your +table so be careful!

(jdbc/insert-multi! db-spec :fruit
+                    nil ; column names not supplied
+                    [[1 "Apple" "red" 59 87]
+                     [2 "Banana" "yellow" 29 92.2]
+                     [3 "Peach" "fuzzy" 139 90.0]
+                     [4 "Orange" "juicy" 89 88.6]])
+;; (1 1 1 1) - row counts modified
+

It is generally safer to specify the columns you wish to insert so you can +control the order, and choose to omit certain columns:

(jdbc/insert-multi! db-spec :fruit
+                    [:name :cost]
+                    [["Mango" 722]
+                     ["Feijoa" 441]])
+;; (1 1) - row counts modified
+

Updating rows

If you want to update simple column values in one or more rows based on a +simple SQL predicate, you can use update! with a map, representing the column +values to set, and a SQL predicate with parameters. If you need a more complex +form of update, you can use the execute! function with arbitrary SQL (and +parameters).

;; update fruit set cost = 49 where grade < ?
+(jdbc/update! db-spec :fruit
+              {:cost 49}
+              ["grade < ?" 75])
+;; produces a sequence of the number of rows updated, e.g., (2)
+

For a more complex update:

(jdbc/execute! db-spec
+               ["update fruit set cost = ( 2 * grade ) where grade > ?" 50.0])
+;; produces a sequence of the number of rows updated, e.g., (3)
+

Deleting rows

If you want to delete any rows from a table that match a simple predicate, the +delete! function can be used.

(jdbc/delete! db-spec :fruit ["grade < ?" 25.0])
+;; produces a sequence of the number of rows deleted, e.g., (1)
+

You can also use execute! for deleting rows:

(jdbc/execute! db-spec ["DELETE FROM fruit WHERE grade < ?" 25.0])
+;; produces a sequence of the number of rows deleted, e.g., (1)
+

Using transactions

You can write multiple operations in a transaction to ensure they are either +all performed, or all rolled back.

(jdbc/with-db-transaction [t-con db-spec]
+  (jdbc/update! t-con :fruit
+                {:cost 49}
+                ["grade < ?" 75])
+  (jdbc/execute! t-con
+                 ["update fruit set cost = ( 2 * grade ) where grade > ?" 50.0]))
+

The with-db-transaction macro creates a transaction-aware connection from the +database specification and that should be used in the body of the transaction +code.

You can specify the transaction isolation level as part of the +with-db-transction binding:

(jdbc/with-db-transaction [t-con db-spec {:isolation :serializable}]
+  ...)
+

Possible values for :isolation are :none, :read-committed, +:read-uncommitted, :repeatable-read, and :serializable. Be aware that not +all databases support all isolation levels. Inside a transaction, you can call +get-isolation-level to return the current level.

In addition, you can also set the current transaction-aware connection to +rollback, and reset that setting, as well as test whether the connection is +currently set to rollback, using the following functions:

(jdbc/db-set-rollback-only! t-con)   ; this transaction will rollback instead of commit
+(jdbc/db-unset-rollback-only! t-con) ; this transaction will commit if successful
+(jdbc/db-is-rollback-only t-con)     ; returns true if transaction is set to rollback
+

Updating or Inserting rows conditionally

java.jdbc does not provide a built-in function for updating existing rows or +inserting a new row (the older API supported this but the logic was too +simplistic to be generally useful). If you need that functionality, it can +sometimes be done like this:

(defn update-or-insert!
+  "Updates columns or inserts a new row in the specified table"
+  [db table row where-clause]
+  (jdbc/with-db-transaction [t-con db]
+    (let [result (jdbc/update! t-con table row where-clause)]
+      (if (zero? (first result))
+        (jdbc/insert! t-con table row)
+        result))))
+
+(update-or-insert! mysql-db :fruit
+                   {:name "Cactus" :appearance "Spiky" :cost 2000}
+                   ["name = ?" "Cactus"])
+;; inserts Cactus (assuming none exists)
+(update-or-insert! mysql-db :fruit
+                   {:name "Cactus" :appearance "Spiky" :cost 2500}
+                   ["name = ?" "Cactus"])
+;; updates the Cactus we just inserted
+

If the where-clause does not uniquely identify a single row, this will update +multiple rows which might not be what you want, so be careful!

Exception Handling and Transaction Rollback

Transactions are rolled back if an exception is thrown, as shown in these +examples.

(jdbc/with-db-transaction [t-con db-spec]
+  (jdbc/insert-multi! t-con :fruit
+                      [:name :appearance]
+                      [["Grape" "yummy"]
+                       ["Pear" "bruised"]])
+  ;; At this point the insert! call is complete, but the transaction is
+  ;; not. The exception will cause it to roll back leaving the database
+  ;; untouched.
+  (throw (Exception. "sql/test exception")))
+

As noted above, transactions can also be set explicitly to rollback instead of +commit:

(jdbc/with-db-transaction [t-con db-spec]
+  (prn "is-rollback-only" (jdbc/db-is-rollback-only t-con))
+  ;; is-rollback-only false
+  (jdbc/db-set-rollback-only! t-con)
+  ;; the following insert will be rolled back when the transaction ends:
+  (jdbc/insert!-multi t-con :fruit
+                      [:name :appearance]
+                      [["Grape" "yummy"]
+                       ["Pear" "bruised"]])
+  (prn "is-rollback-only" (jdbc/db-is-rollback-only t-con))
+  ;; is-rollback-only true
+  ;; the following will display the inserted rows:
+  (jdbc/query t-con ["SELECT * FROM fruit"]
+              :row-fn println))
+(prn)
+;; outside the transaction, the following will show the original rows
+;; without those two inserted inside the (rolled-back) transaction:
+(jdbc/query db-spec ["SELECT * FROM fruit"]
+            :row-fn println)
+

Clojure identifiers and SQL entities

As hinted at above, java.jdbc converts SQL entity names in result sets to +keywords in Clojure by making them lowercase, and converts strings and keywords +that specify table and column names (in maps) to SQL entities as-is by +default.

You can override this behavior by specifying an options map, containing +:identifiers, :keywordize? and/or :qualifier, on any function that +returns or transforms a result set, +and :entities, on any function that transforms Clojure data into SQL.

  • :identifiers is for converting ResultSet column names to keywords (or strings). It +defaults to clojure.string/lower-case.
  • :keywordize? controls whether to convert identifiers to keywords (the default) or not.
  • :qualifier optionally specifies a namespace to qualify keywords with (when +:keywordize? is not falsey).
  • :entities is for converting Clojure keywords/string to SQL entity names. It +defaults to identity (after calling name on the keyword or string).

If you want to prevent java.jdbc's conversion of SQL entity names to lowercase +in a query result, you can specify :identifiers identity:

(jdbc/query db-spec ["SELECT * FROM mixedTable"]
+            {:identifiers identity})
+;; produces result set with column names exactly as they appear in the DB
+

It you're working with a database that has underscores in column names, you +might want to specify a function that converts those to dashes in Clojure +keywords:

(jdbc/query db-spec ["SELECT * FROM mixedTable"]
+            {:identifiers #(.replace % \_ \-)})
+

For several databases, you will often want entities to be quoted in some way +(sometimes referred to as "stropping"). A utility function quoted is provided +that accepts either a single character, a vector pair of characters, or a keyword +as a symbolic name for the type of quoting you want (:ansi, :mysql, +:oracle, :sqlserver), and +returns a function suitable for use with the :entities option.

For example:

(jdbc/insert! db-spec :fruit
+              {:name "Apple" :appearance "Round" :cost 99}
+              {:entities (jdbc/quoted \`)}) ; or (jdbc/quoted :mysql)
+

will execute:

INSERT INTO `fruit` ( `name`, `appearance`, `cost` )
+    VALUES ( ?, ?, ? )
+

with the parameters "Apple", "Round", "99" whereas:

(jdbc/insert! db-spec :fruit
+              {:name "Apple" :appearance "Round" :cost 99}
+              {:entities (jdbc/quoted [\[ \]])}) ; or (jdbc/quoted :sqlserver)
+

will execute:

INSERT INTO [fruit] ( [name], [appearance], [cost] )
+    VALUES ( ?, ?, ? )
+

with the parameters "Apple", "Round", "99".

Protocol extensions for transforming values

By default, java.jdbc leaves it up to Java interop and the JDBC driver library +to perform the appropriate transformations of Clojure values to SQL values and +vice versa. When Clojure values are passed through to the JDBC driver, +java.jdbc uses PreparedStatement/setObject for all values by default. When +Clojure values are read from a ResultSet they are left untransformed, except +that Boolean values are coerced to canonical true / false values in +Clojure (some driver / data type combinations can produce (Boolean. false) +values otherwise, which do not behave like false in all situations).

java.jdbc provides three protocols that you can extend, in order to modify +these behaviors.

  • ISQLValue / sql-value - simple transformations of Clojure values to SQL +values
  • ISQLParameter / set-parameter - a more sophisticated transformation of +Clojure values to SQL values that lets you override how the value is stored +in the PreparedStatement
  • IResultSetReadColumn / result-set-read-column - simple transformations of +SQL values to Clojure values when processing a ResultSet object

If you are using a database that returns certain SQL types as custom Java types +(e.g., PostgreSQL), you can extend IResultSetReadColumn to that type and +define result-set-read-column to perform the necessary conversion to a usable +Clojure data structure. The result-set-read-column function is called with +three arguments:

  • The SQL value itself
  • The ResultSet metadata object
  • The index of the column in the row / metadata

By default result-set-read-column just returns its first argument (the +Boolean implementation ensure the result is either true or false).

If you are using a database that requires special treatment of null values, +e.g., TeraData, you can extend ISQLParameter to nil (and Object) and +define set-parameter to use .setNull instead of .setObject. The +set-parameter function is called with three arguments:

  • The Clojure value itself
  • The PreparedStatement object
  • The index of the parameter being set

By default set-parameter calls sql-value on the Clojure value and then +calls .setObject to store the result of that call into the specified +parameter in the SQL statement.

For general transformations of Clojure values to SQL values, extending +ISQLValue and defining sql-value may be sufficient. The sql-value +function is called with a single argument: the Clojure value. By default +sql-value just returns its argument.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql/index.html b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql/index.html new file mode 100644 index 00000000..c51cde3a --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/java_jdbc/using_sql/index.html @@ -0,0 +1,510 @@ + + + + + Clojure Guides: java.jdbc - Manipulating data with SQL + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Contents

Using SQL

Here are some examples of using java.jdbc to manipulate data with SQL. +These examples assume a simple table called fruit (see Using DDL and +Metadata). These examples all assume the following in your +ns declaration:

(:require [clojure.java.jdbc :as jdbc])
+

Reading and processing rows

java.jdbc provides a simple query function to allow you to read rows from +tables, as well as optionally performing processing on them at the same time.

Reading rows

To obtain a fully realized result set as a sequence of maps, you can use +query with a vector containing the SQL string and any parameters needed by +the SQL:

(jdbc/query db-spec ["SELECT * FROM fruit"])
+;; ({:id 1 :name "Apple" :appearance "red" :cost 59 :grade 87}
+;;  {:id 2 :name "Banana" :appearance "yellow" :cost 29 :grade 92.2}
+;;  ...)
+
+(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50])
+;; ({:id 2 :name "Banana" :appearance "yellow" :cost 29 :grade 92.2}
+;;  ...)
+

You can also return the result set as a sequence of vectors. The first vector +will contain the column names, and each subsequent vector will represent a row +of data with values in the same order as the columns.

(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]
+         {:as-arrays? true})
+;; ([:id :name :appearance :cost :grade]
+;;  [2 "Banana" "yellow" 29 92.2]
+;;  ...)
+

Processing a result set lazily

Since query returns a fully realized result set, it can be difficult to +process very large results. Fortunately, java.jdbc provides a number of ways to process a +large result set lazily while the connection is open, either by passing a function via +the :result-set-fn option or, since release 0.7.0, via reducible-query.

query and :result-set-fn

If you are using release 0.7.0 or later, consider using reducible-query instead -- see below.

For :result-set-fn, the function you pass must force +realization of the result to avoid the connection closing while the result set +is still being processed. A reduce-based function is a good choice.

(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]
+            {:result-set-fn (fn [rs]
+                              (reduce (fn [total row-map]
+                                        (+ total (:cost row-map)))
+                              0 rs))})
+;; produces the total cost of all the cheap fruits: 437
+

Of course, a simple sum like this could be computed directly in SQL instead:

(jdbc/query db-spec ["SELECT SUM(cost) FROM fruit WHERE cost < ?" 50]
+            {:result-set-fn first})
+;; {:sum(cost) 437}
+

We know we will only get one row back so passing first to :result-set-fn is +a quick way to get just that row.

Remember that if you also specify :as-arrays? true, your result set function +will be passed a sequence of vectors in which the first vector contains the +column names and subsequent vectors represent the values in the rows, matching +the order of the column names.

reducible-query

This is the recommended approach since release 0.7.0 but it does come with a few +restrictions:

You cannot use any of the following options that query accepts: +as-arrays?, :explain, :explain-fn, :result-set-fn, or :row-fn.

On the other hand, you have access to a much faster way to process result sets: +you can specify :raw? true and no conversion from Java's ResultSet to +Clojure's sequence of hash maps will be performed. In particular, it's as if you +specified :identifiers identity :keywordize? false :qualifier nil, and the +sequence representation of each row is not available. That means no keys, +no vals, no seq calls, just simple key lookup (for convenience, you can +still use keyword lookup for columns, but you can also call get with either a +string or a keyword).

So how does this work? reducible-query produces a clojure.lang.IReduce which, +when reduced with a function f, performs the query and reduces the ResultSet +using f, opening and closing the connection and/or transaction during the +reduction. For example:

;; our reducing function requires two arguments: we must provide initial val
+(reduce (fn [total {:keys [cost]}] (+ total cost))
+        0
+        (jdbc/reducible-query db-spec
+                              ["SELECT * FROM fruit WHERE cost < ?" 50]
+                              {:raw? true}))
+;; separating the key selection from the reducing function: we can omit val
+(transduce (map :cost)
+           + ; can be called with 0, 1, or 2 arguments!
+           (jdbc/reducible-query db-spec
+                                 ["SELECT * FROM fruit WHERE cost < ?" 50]
+                                 {:raw? true}))
+;; 437
+

Since reducible-query doesn't actually run the query until you reduce its result, +you can create it once and run it as many times as you want. This will avoid the +overhead of option and parameter validation and handling for repeated reductions, +since those are performed just once in the call to reducible-query. Note that +the SQL parameters are fixed by that call, so this only works for running the +identical query multiple times.

A reducible companion to result-set-seq also exists, in case you already have +a Java ResultSet and want to create a clojure.lang.IReduce. reducible-result-set +accept almost the same options as result-set-seq: identifiers, keywordize?, +qualifier, and read-columns. It does not accept as-arrays? (for the same +reason that reducible-query does not). Unlike result-set-seq, which produces +a lazy sequence that can be consumed multiple times (with the first pass realizing +it for subsequent passes), reducible-result-set is reducible just once: the +underlying ResultSet is mutable and is consumed during the first reduction!

It should go without saying that both reducible-query and +reducible-result-set respect reduced / reduced?.

Additional Options?

Note: some databases require additional options to be passed in to ensure that +result sets are chunked and lazy. In particular, you may need to pass +:auto-commit?, set appropriately, as an option to whichever function will open your database +connection (with-db-connection, with-db-transaction, or the query / reducible-query itself +if you are passing a bare database spec and expecting query / reducible-query to open and close +the connection directly). You may also need to specify :fetch-size, :result-type, +and possibly other options -- consult your database's documentation for the JDBC +driver you are using.

Processing each row lazily

As seen above, using reduce, transduce, etc with a reducible-query allow +you to easily and efficiently process each row as you process the entire +result set, but sometimes you just want a sequence of transformed rows.

We can process each row with the :row-fn option. Again, like with :result-set-fn, +we pass a function but this time it will be +invoked on each row, as the result set is realized.

(jdbc/query db-spec ["SELECT name FROM fruit WHERE cost < ?" 50]
+            {:row-fn :name})
+;; ("Apple" "Banana" ...)
+

The result is still a fully realized sequence, but each row has been +transformed by the :name function you passed in.

You can combine this with :result-set-fn to simplify processing of result +sets:

(jdbc/query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]
+            {:row-fn :cost
+             :result-set-fn (partial reduce +)})
+;; produces the total cost of all the cheap fruits
+

or:

(jdbc/query db-spec ["SELECT SUM(cost) AS total FROM fruit WHERE cost < ?" 50]
+            {:row-fn :total
+             :result-set-fn first})
+;; produces the same result, via SQL
+

Here is an example that manipulates rows to add computed columns:

(defn add-tax [row] (assoc row :tax (* 0.08 (:cost row))))
+
+(jdbc/query db-spec ["SELECT * FROM fruit"]
+            {:row-fn add-tax})
+;; produces all the rows with a new :tax column added
+

All of the above can be achieved via reducible-query and the appropriate +reducing function and/or transducer, but with those simple row/result set +functions, the result is often longer / uglier:

(into [] (map :name) (jdbc/reducible-query db-spec ["SELECT name FROM fruit WHERE cost < ?" 50]))
+(transduce (map :cost) + (jdbc/reducible-query db-spec ["SELECT * FROM fruit WHERE cost < ?" 50]))
+;; :row-fn :total :result-set-fn first left as an exercise for the reader!
+(into [] (map add-tax) (jdbc/reducible-query db-spec ["SELECT * FROM fruit"]))
+

If the result set is likely to be large and the reduction can use a :raw? true +result set, reducible-query may be worth the verbosity for the performance gain.

Inserting data

Rows (and partial rows) can be inserted easily using the insert! function. +You can insert a single row, or multiple rows. Depending on how you call +insert!, the insertion will be done either through multiple SQL statements or +through a single, batched SQL statement. That will also determine whether or +not you get back any generated keys.

If you need a more complex form of insertion, you can use execute! and, if +your database / driver supports it, you can pass :return-keys as an option +to get back the generated keys. As of java.jdbc 0.7.6, this can be a vector +of column names to return (for drivers that support that) or a simple Boolean.

Inserting a row

If you want to insert a single row (or partial row) and get back the generated +keys, you can use insert! and specify the columns and their values as a map. +This performs a single insert statement. A single-element sequence containing a +map of the generated keys will be returned.

(jdbc/insert! db-spec :fruit {:name "Pear" :appearance "green" :cost 99})
+;; returns a database-specific map as the only element of a sequence, e.g.,
+;; ({:generated_key 50}) might be returned for MySQL
+

Not all databases are able to return generated keys from an insert.

Inserting multiple rows

There are two ways to insert multiple rows: as a sequence of maps, or as a +sequence of vectors. In the former case, multiple inserts will be performed and +a map of the generated keys will be returned for each insert (as a sequence). +In the latter case, a single, batched insert will be performed and a sequence +of row insert counts will be returned (generally a sequence of ones). The latter +approach is likely to be substantially faster if you are inserting a large number +of rows.

If you use insert-multi! and specify each row as a map of columns and their values, +then you can specify a mixture of complete and partial rows, and you will get +back the generated keys for each row (assuming the database has that +capability).

(jdbc/insert-multi! db-spec :fruit
+                    [{:name "Pomegranate" :appearance "fresh" :cost 585}
+                     {:name "Kiwifruit" :grade 93}])
+;; returns a sequence of database-specific maps, e.g., for MySQL:
+;; ({generated_key 51} {generated_key 52})
+

If you use insert-multi! and specify the columns you wish to insert followed by +each row as a vector of column values, then you must specify the same columns +in each row, and you will not get generated keys back, just row counts. If you +wish to insert complete rows, you may omit the column name vector (passing +nil instead) but your rows must match the natural order of columns in your +table so be careful!

(jdbc/insert-multi! db-spec :fruit
+                    nil ; column names not supplied
+                    [[1 "Apple" "red" 59 87]
+                     [2 "Banana" "yellow" 29 92.2]
+                     [3 "Peach" "fuzzy" 139 90.0]
+                     [4 "Orange" "juicy" 89 88.6]])
+;; (1 1 1 1) - row counts modified
+

It is generally safer to specify the columns you wish to insert so you can +control the order, and choose to omit certain columns:

(jdbc/insert-multi! db-spec :fruit
+                    [:name :cost]
+                    [["Mango" 722]
+                     ["Feijoa" 441]])
+;; (1 1) - row counts modified
+

Updating rows

If you want to update simple column values in one or more rows based on a +simple SQL predicate, you can use update! with a map, representing the column +values to set, and a SQL predicate with parameters. If you need a more complex +form of update, you can use the execute! function with arbitrary SQL (and +parameters).

;; update fruit set cost = 49 where grade < ?
+(jdbc/update! db-spec :fruit
+              {:cost 49}
+              ["grade < ?" 75])
+;; produces a sequence of the number of rows updated, e.g., (2)
+

For a more complex update:

(jdbc/execute! db-spec
+               ["update fruit set cost = ( 2 * grade ) where grade > ?" 50.0])
+;; produces a sequence of the number of rows updated, e.g., (3)
+

Deleting rows

If you want to delete any rows from a table that match a simple predicate, the +delete! function can be used.

(jdbc/delete! db-spec :fruit ["grade < ?" 25.0])
+;; produces a sequence of the number of rows deleted, e.g., (1)
+

You can also use execute! for deleting rows:

(jdbc/execute! db-spec ["DELETE FROM fruit WHERE grade < ?" 25.0])
+;; produces a sequence of the number of rows deleted, e.g., (1)
+

Using transactions

You can write multiple operations in a transaction to ensure they are either +all performed, or all rolled back.

(jdbc/with-db-transaction [t-con db-spec]
+  (jdbc/update! t-con :fruit
+                {:cost 49}
+                ["grade < ?" 75])
+  (jdbc/execute! t-con
+                 ["update fruit set cost = ( 2 * grade ) where grade > ?" 50.0]))
+

The with-db-transaction macro creates a transaction-aware connection from the +database specification and that should be used in the body of the transaction +code.

You can specify the transaction isolation level as part of the +with-db-transction binding:

(jdbc/with-db-transaction [t-con db-spec {:isolation :serializable}]
+  ...)
+

Possible values for :isolation are :none, :read-committed, +:read-uncommitted, :repeatable-read, and :serializable. Be aware that not +all databases support all isolation levels. Inside a transaction, you can call +get-isolation-level to return the current level.

In addition, you can also set the current transaction-aware connection to +rollback, and reset that setting, as well as test whether the connection is +currently set to rollback, using the following functions:

(jdbc/db-set-rollback-only! t-con)   ; this transaction will rollback instead of commit
+(jdbc/db-unset-rollback-only! t-con) ; this transaction will commit if successful
+(jdbc/db-is-rollback-only t-con)     ; returns true if transaction is set to rollback
+

Updating or Inserting rows conditionally

java.jdbc does not provide a built-in function for updating existing rows or +inserting a new row (the older API supported this but the logic was too +simplistic to be generally useful). If you need that functionality, it can +sometimes be done like this:

(defn update-or-insert!
+  "Updates columns or inserts a new row in the specified table"
+  [db table row where-clause]
+  (jdbc/with-db-transaction [t-con db]
+    (let [result (jdbc/update! t-con table row where-clause)]
+      (if (zero? (first result))
+        (jdbc/insert! t-con table row)
+        result))))
+
+(update-or-insert! mysql-db :fruit
+                   {:name "Cactus" :appearance "Spiky" :cost 2000}
+                   ["name = ?" "Cactus"])
+;; inserts Cactus (assuming none exists)
+(update-or-insert! mysql-db :fruit
+                   {:name "Cactus" :appearance "Spiky" :cost 2500}
+                   ["name = ?" "Cactus"])
+;; updates the Cactus we just inserted
+

If the where-clause does not uniquely identify a single row, this will update +multiple rows which might not be what you want, so be careful!

Exception Handling and Transaction Rollback

Transactions are rolled back if an exception is thrown, as shown in these +examples.

(jdbc/with-db-transaction [t-con db-spec]
+  (jdbc/insert-multi! t-con :fruit
+                      [:name :appearance]
+                      [["Grape" "yummy"]
+                       ["Pear" "bruised"]])
+  ;; At this point the insert! call is complete, but the transaction is
+  ;; not. The exception will cause it to roll back leaving the database
+  ;; untouched.
+  (throw (Exception. "sql/test exception")))
+

As noted above, transactions can also be set explicitly to rollback instead of +commit:

(jdbc/with-db-transaction [t-con db-spec]
+  (prn "is-rollback-only" (jdbc/db-is-rollback-only t-con))
+  ;; is-rollback-only false
+  (jdbc/db-set-rollback-only! t-con)
+  ;; the following insert will be rolled back when the transaction ends:
+  (jdbc/insert!-multi t-con :fruit
+                      [:name :appearance]
+                      [["Grape" "yummy"]
+                       ["Pear" "bruised"]])
+  (prn "is-rollback-only" (jdbc/db-is-rollback-only t-con))
+  ;; is-rollback-only true
+  ;; the following will display the inserted rows:
+  (jdbc/query t-con ["SELECT * FROM fruit"]
+              :row-fn println))
+(prn)
+;; outside the transaction, the following will show the original rows
+;; without those two inserted inside the (rolled-back) transaction:
+(jdbc/query db-spec ["SELECT * FROM fruit"]
+            :row-fn println)
+

Clojure identifiers and SQL entities

As hinted at above, java.jdbc converts SQL entity names in result sets to +keywords in Clojure by making them lowercase, and converts strings and keywords +that specify table and column names (in maps) to SQL entities as-is by +default.

You can override this behavior by specifying an options map, containing +:identifiers, :keywordize? and/or :qualifier, on any function that +returns or transforms a result set, +and :entities, on any function that transforms Clojure data into SQL.

  • :identifiers is for converting ResultSet column names to keywords (or strings). It +defaults to clojure.string/lower-case.
  • :keywordize? controls whether to convert identifiers to keywords (the default) or not.
  • :qualifier optionally specifies a namespace to qualify keywords with (when +:keywordize? is not falsey).
  • :entities is for converting Clojure keywords/string to SQL entity names. It +defaults to identity (after calling name on the keyword or string).

If you want to prevent java.jdbc's conversion of SQL entity names to lowercase +in a query result, you can specify :identifiers identity:

(jdbc/query db-spec ["SELECT * FROM mixedTable"]
+            {:identifiers identity})
+;; produces result set with column names exactly as they appear in the DB
+

It you're working with a database that has underscores in column names, you +might want to specify a function that converts those to dashes in Clojure +keywords:

(jdbc/query db-spec ["SELECT * FROM mixedTable"]
+            {:identifiers #(.replace % \_ \-)})
+

For several databases, you will often want entities to be quoted in some way +(sometimes referred to as "stropping"). A utility function quoted is provided +that accepts either a single character, a vector pair of characters, or a keyword +as a symbolic name for the type of quoting you want (:ansi, :mysql, +:oracle, :sqlserver), and +returns a function suitable for use with the :entities option.

For example:

(jdbc/insert! db-spec :fruit
+              {:name "Apple" :appearance "Round" :cost 99}
+              {:entities (jdbc/quoted \`)}) ; or (jdbc/quoted :mysql)
+

will execute:

INSERT INTO `fruit` ( `name`, `appearance`, `cost` )
+    VALUES ( ?, ?, ? )
+

with the parameters "Apple", "Round", "99" whereas:

(jdbc/insert! db-spec :fruit
+              {:name "Apple" :appearance "Round" :cost 99}
+              {:entities (jdbc/quoted [\[ \]])}) ; or (jdbc/quoted :sqlserver)
+

will execute:

INSERT INTO [fruit] ( [name], [appearance], [cost] )
+    VALUES ( ?, ?, ? )
+

with the parameters "Apple", "Round", "99".

Protocol extensions for transforming values

By default, java.jdbc leaves it up to Java interop and the JDBC driver library +to perform the appropriate transformations of Clojure values to SQL values and +vice versa. When Clojure values are passed through to the JDBC driver, +java.jdbc uses PreparedStatement/setObject for all values by default. When +Clojure values are read from a ResultSet they are left untransformed, except +that Boolean values are coerced to canonical true / false values in +Clojure (some driver / data type combinations can produce (Boolean. false) +values otherwise, which do not behave like false in all situations).

java.jdbc provides three protocols that you can extend, in order to modify +these behaviors.

  • ISQLValue / sql-value - simple transformations of Clojure values to SQL +values
  • ISQLParameter / set-parameter - a more sophisticated transformation of +Clojure values to SQL values that lets you override how the value is stored +in the PreparedStatement
  • IResultSetReadColumn / result-set-read-column - simple transformations of +SQL values to Clojure values when processing a ResultSet object

If you are using a database that returns certain SQL types as custom Java types +(e.g., PostgreSQL), you can extend IResultSetReadColumn to that type and +define result-set-read-column to perform the necessary conversion to a usable +Clojure data structure. The result-set-read-column function is called with +three arguments:

  • The SQL value itself
  • The ResultSet metadata object
  • The index of the column in the row / metadata

By default result-set-read-column just returns its first argument (the +Boolean implementation ensure the result is either true or false).

If you are using a database that requires special treatment of null values, +e.g., TeraData, you can extend ISQLParameter to nil (and Object) and +define set-parameter to use .setNull instead of .setObject. The +set-parameter function is called with three arguments:

  • The Clojure value itself
  • The PreparedStatement object
  • The index of the parameter being set

By default set-parameter calls sql-value on the Clojure value and then +calls .setObject to store the result of that call into the specified +parameter in the SQL statement.

For general transformations of Clojure values to SQL values, extending +ISQLValue and defining sql-value may be sufficient. The sql-value +function is called with a single argument: the Clojure value. By default +sql-value just returns its argument.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/libraries_authoring/index.html b/clones/clojure-doc.org/articles/ecosystem/libraries_authoring/index.html new file mode 100644 index 00000000..7f2a1dac --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/libraries_authoring/index.html @@ -0,0 +1,343 @@ + + + + + Clojure Guides: Library Development and Distribution + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This short guide covers how to create your own typical pure Clojure +library and distribute it to the community via Clojars. It uses +Clojureย 1.4 and Leiningenย 2.0-previewX, and requires you have git +installed (though very little familiarity with git is required).

It's assumed that you're already somewhat familiar with Clojure. If +not, see the Getting Started and +Introduction guides.

For the purposes of this guide, the library we'll be making is named +"trivial-library-example".

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

Create the Project

Create your new library project. Names are usually hyphen-separated +lowercase words:

lein new trivial-library-example
+cd trivial-library-example
+

Typical lein usage is lein new <proj-type> <proj-name>, but if you +leave out <proj-type> (as we've done above), lein defaults to +creating a library project for you.

Our trivial library example project will have a dependency on +flatland's "useful" +library.

Open up our new project.clj file and make a few changes:

  1. Add our dependency ([org.flatland/useful "0.9.0"]) to the :dependencies vector.
  2. Remove "-SNAPSHOT" from version string.
  3. Write a short description.
  4. Add a url (if not a homepage, then where it's source is hosted online).
  5. If you're using a different license, change the value for :license.

Regarding your choice of license, probably the three most common for +Clojure libs (along with a grossly oversimplified blurb (by this +author) for each) are:

Whichever one you choose, update your project.clj (if necessary) to +reflect that choice and save the text of the license as a file named +"LICENSE" or "COPYING" in your project directory.

A Note Regarding Project Naming

The top line of your project.clj includes something like defproject my-project-name. This means that your project has an artifact-id +of "my-project-name", but it also implies a group-id of +"my-project-name" (group-id = artifact-id).

The artifact-id is the name of your project. The group-id is used for +namespacing (not the same thing as Clojure namespaces) --- it +identifies to which group/organization a project belongs. Some +examples of group-id's: clojurewerkz, sonian, and org.your-domain.

You may choose to explicitly use a group-id for your project, if you +like. For example:

(defproject org.my-domain/my-project-name ...
+...)
+

The maintainers of Clojars +require that new libs be published using verified groups, +such as org.my-domain.

Read more about groups at +https://github.com/clojars/clojars-web/wiki/Groups.

Update the README

Aside from providing a good overview, rationale, and introduction at +the top, you're encouraged to provide some usage examples as well. A +link to the lib's (future) Clojars page (which we'll get to below) +might also be appreciated. Add acknowledgements near the end, if +appropriate. Adjust the copyright and license info at the bottom of +the README as needed.

Lein provides you with a doc directory and a starter doc/intro.md +file. If you find that you have more to say than will comfortably fit +into the README.md, consider moving content into the doc dir.

Other goodies you might include in your README.md or doc/*.md files: +tutorial, news, bugs, limitations, alternatives, troubleshooting, +configuration.

Note that you generally won't add hand-written API documentation into +your readme or other docs, as there are tools for creating that +directly from your source (discussed later).

Create your project's local git repository

Before going much further, you probably want to get your project under +version control. Make sure you've got git installed and configured to +know your name and email address (i.e., that at some point you've run +git config --global user.name "Your Name" and git config --global user.email "your-email@somewhere.org").

Then, in your project dir, run:

git init
+git add .
+git commit -m "The initial commit."
+

At any time after you've made changes and want to inspect them and +commit them to the repository:

git diff
+git add -p
+git commit -m "The commit message."
+

Write Tests

In test/trivial_library_example/core_test.clj, add tests as needed. +An example is provided in there to get you started.

Write Code

Write code to make your tests pass.

Remember to add a note at the top of each file indicating copyright +and the license under which the code is distributed.

Run Tests

In your project dir:

lein test
+

Commit any remaining changes

Before continuing to the next step, make sure all tests pass and +you've committed all your changes. Check to see the status of your +repo at any time with git status and view changes with git diff.

Create github project and Upload there

This guide makes use of github to host your +project code. If you don't already have a github account, create one, +then log into it. Github provides good documentation on how to get +started and how to +create an SSH key +pair. If you +haven't already done so, get that set up before continuing.

Create a new repo there for your project using the icon/button/link +near the top-right.

You will have your local repository, and also a remote duplicate of +it at github.

For the repository name, use the same name as your project directory. +Provide a one-line description and hit "Create repository".

Once this remote repo has been created, follow the instructions on the +resulting page to "Push an existing repository from the command +line". You'll of course run the git commands from your project +directory:

git remote add origin git@github.com:uvtc/trivial-library-example.git
+git push -u origin master
+

You can now access your online repo. For this tutorial, it's +https://github.com/uvtc/trivial-library-example.

Any changes you commit to your local repository can now be pushed +to the remote one at github:

# work work work
+git add -p
+git commit -m "commit message here"
+git push
+

Create a GPG key for signing your releases

You'll need to create a gpg key pair, which +will be used by lein to sign any release you make to Clojars. Make +sure you've got gpg installed and kick the tires:

gpg --list-keys
+

(The first time that command is run, you'll see some notices about +it creating necessary files in your home dir.)

To create a key pair:

gpg --gen-key
+

Take the default key type (RSA and RSA), and default key size (2048). +When asked for how long the key should remain valid, choose a year or +two. Give it your real name and email address. When it prompts you for +a comment, you might add one as it can be helpful if you have multiple +keys to keep track of. When prompted for a passphrase, come up with one +that is different from the one used with your ssh key.

When gpg has completed generating your keypair, you can have it list +what keys it knows about:

gpg --list-keys
+

We'll use that public key in the next section.

Upload to Clojars

If you don't already have an account at https://clojars.org/, create +one. After doing so, you'll need to supply your ssh and gpg public +keys to Clojars. For the ssh public key, you can use the same one as +used with github. For the gpg public key, get it by running:

gpg --export -a <your-key-id>
+

where <your-key-id> is in the output of gpg --list-keys (the +8-character part following the forward slash on the line starting with +"pub"). Copy/paste that output (including the "-----BEGIN PGP PUBLIC +KEY BLOCK-----" and "-----END PGP PUBLIC KEY BLOCK-----") into the +form on your Clojars profile page.

For more info on working with Clojars, see the Clojars +wiki.

Once your Clojars account is all set up, and it has your public keys, +upload your library to Clojars like so:

lein deploy clojars
+

You will be asked for your (Clojars) username and password.

Then you'll be asked for your gpg passphrase. (You won't be asked for +your ssh passphrase because lein deploy clojars uses http rather +than scp --- though Clojars supports both.)

You should now be able to see your lib's Clojars page: for example, +https://clojars.org/trivial-library-example!

Generate API docs (optional)

For larger library projects, you may want to automatically generate +API docs (from your docstrings). See +codox. If your library project +is hosted at github, you can use github +pages to host the resulting docs.

Announce (optional)

You're welcome to announce the availability of your new library +on the Clojure Mailing List.

Make Updates to your library

Making updates to your lib follows the same pattern as described above:

# work test work test
+# update version string in project.clj
+git add -p
+git commit
+git push
+lein deploy clojars
+

And optionally announce the release on the ML.

Merging pull-requests

Note that if you receive a pull-request at github, you can easily +merge those changes into your project (right there, via the web page +describing the pull-request). Afterwards, update your local repo to +grab those changes as well:

git pull
+

See Also

For more detailed documentation on various aspects of the procedures +described here, see:

Contributors

John Gabriele jmg3000@gmail.com (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/libraries_directory/index.html b/clones/clojure-doc.org/articles/ecosystem/libraries_directory/index.html new file mode 100644 index 00000000..1dc8be4e --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/libraries_directory/index.html @@ -0,0 +1,239 @@ + + + + + Clojure Guides: A Directory of Clojure Libraries + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This is a categorized and annotated directory of available Clojure +libraries and tools. This directory is not comprehensive and is necessarily highly opinionated.

This directory is manually curated by the Clojure community. Please endeavor to keep it up-to-date, +consisting of high quality libraries with adequate documentation. There are many more libraries in the Clojure +ecosystem, but some lack documentation and/or are useful primarily to experienced developers and such projects +are not included in this document.

For more comprehensive overview of the Clojure library ecosystem, please see ClojureSphere.

Support Libraries

General

Applications & Environment

  • tools.cli: a command line argument parser for Clojure

  • environ: Manage environment settings from a number of different sources

  • carica (at clojars): +Flexible config file usage & management library.

Date and Time

  • clj-time: A date and time library for Clojure

Testing

Namespaces and Code-as-Data

Serialization

JSON

  • cheshire (at clojars): very efficient Clojure JSON and SMILE (binary JSON) encoding/decoding.

  • data.json: JSON parser/generator to/from Clojure data structures.

Protocol Buffers

Kryo

Clojure Reader

XML

  • data.xml: a library for reading and writing XML

Binary Formats

  • gloss (at clojars): turns complicated byte formats into Clojure data structures

File formats

  • clj-pdf: a library for easily generating PDFs from Clojure

  • Pantomime (at clojars): a tiny Clojure library that deals with Internet media types (MIME types) and content type detection

  • data.csv: a CSV parser

Templating

HTTP

Client/Server

Client

  • clj-http (at clojars): An idiomatic Clojure http client wrapping the apache client.

  • clj-http-lite (at clojars): A lightweight version of clj-http having almost same API, but without any Apache dependencies.

Logging

  • Timbre: +Simple, flexible, all-Clojure logging. No XML!

  • tools.logging: standard general-purpose logging.

  • clj-log: s-expression logger.

Web Development

Web Services

  • Ring (at clojars): foundational +web application library

  • Compojure (at clojars): +concise routing library for Ring

  • Pedestal (at clojars): +an open source tool set for building web applications in Clojure

  • Luminus: lein template for creating batteries-included +web applications using Ring, Compojure, lib-noir, and other libraries.

  • Liberator (at clojars): a Clojure library for building RESTful applications

  • friend (at clojars): Authentication and authorization library for Web apps

HTML Generation

  • hiccup: Generates HTML from Clojure data structures.

  • Stencil: Implements the Mustache templating language.

  • markdown-clj: Clojure based Markdown parsers for both Clojure and ClojureScript.

HTML Parsers

  • Crouton: A Clojure wrapper for the JSoup HTML and XML parser that handles real world inputs

  • Crawlista (at clojars): a support library for applications that crawl the Web

  • TagSoup: a tool for parsing html as it's found in the wild: poor, nasty, and brutish.

Data Validation

  • Validateur (at clojars): functional validations library inspired by Ruby's ActiveModel

  • Metis: another validations library inspired by Ruby's ActiveModel

  • Clj-Schema (at clojars): Schemas for Clojure Data: validation and test data generators

URIs, URLs

  • Urly (at clojars): unifies java.net.URL, java.net.URI and string URIs, provides parsing and manipulation helpers

  • Exploding Fish (at clojars): a URI library for Clojure

  • route-one (at clojars): a tiny Clojure library that generates HTTP resource routes (as in Ruby on Rails, Jersey, and so on)

Internationalization (i18n), Localization (l10n)

  • Tower (at clojars): a simple, idiomatic internationalization and localization story for Clojure

RSS

  • clj-rss: RSS feed generation library

Data Stores

Relational Databases, JDBC

CouchDB

MongoDB

Riak

  • Welle (at clojars): An expressive Clojure client for Riak with solid documentation

Redis

Graph Databases (Neo4J, Titan, etc)

ElasticSearch

Memcached, Couchbase, Kestrel

  • Spyglass (at clojars): Spyglass is a very fast Clojure client for Memcached and Couchbase with solid documentation

Apache Cassandra

Amazon DynamoDB

Tokyo Cabinet

Misc

  • masai (at clojars): a very simple interface to a number of key-value stores

  • jiraph (at clojars): a reasonably licensed embedded graph database with swappable backends

Networking

Application Servers

  • Immutant (at clojars): a feature rich and integrated application platform for Clojure from Red Hat

Messaging

RabbitMQ

  • Langohr (at clojars): a feature complete RabbitMQ client that embraces AMQP 0.9.1 model and learns from others

ZeroMQ

  • Jilch (at clojars): Clojure ZeroMQ Library using JeroMQ, no native dependencies

Beanstalk

Amazon SQS

  • Bandalore: a Clojure client library for Amazon's Simple Queue Service

HornetQ

Data Processing, Computation

Natural Language Processing

Parsers, Parser Combinators, Language Construction

Automation, Provisioning, DevOps Tools

Monitoring, metrics

I/O

Files, NIO, NIO2

File I/O is covered by the JDK and commonly used via clojure.java.io functions.

  • fs (at clojars): utilities for working with the file system
  • nio: Clojure library for working with for Java NIO classes

Standard Streams, Subprocesses

Standard streams I/O is covered by the JDK and commonly used via clojure.java.io functions.

  • clojure.java.shell (part of Clojure distribution): Conveniently launch a sub-process providing +its stdin and collecting its stdout.

  • conch: for shelling out to external programs. +An alternative to clojure.java.shell.

Property Files

REPL and Terminal

Concurrency and Parallelism

Mathematics

Email

Data Structures and Algorithms

Strings

  • clojure.string

Sets

  • clojure.set

Caching

  • core.cache: the Clojure API for various cache implementations

UUIDs

Monads

  • algo.monads: macros for defining monads, and definition of the most common monads

  • protocol-monads: A protocol based monad implementation for clojure

Memoization

Other

Scheduling

Graphics and GUI

  • Quil: For making drawings, animations, +and artwork (some examples). Wraps +the "Processing" graphics environment.

  • seesaw (at clojars): A Swing wrapper/DSL.

  • clisk: Clisk is a DSL-based library for procedural image generation that can be used from Clojure and Java.

Security and Sandboxing

Documentation

Literate Programming

Generating API Reference

Tooling

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/maven/index.html b/clones/clojure-doc.org/articles/ecosystem/maven/index.html new file mode 100644 index 00000000..e8e8132f --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/maven/index.html @@ -0,0 +1,395 @@ + + + + + Clojure Guides: How to use Maven to build Clojure projects + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide describes how to use Maven to build projects written in Clojure (or in Clojure, +and other languages, such as Java). Although Leiningen is more popular build tool in the +Clojure community, Maven is also used for some projects, such as Clojure Contrib +libraries, and may be useful when you need to perform some special tasks during build, +that aren't covered by Leiningen's plugins, or when you're integrating Clojure code into +an existing Maven project.

What is Maven?

Maven is a software project life cycle management tool. It implements dependencies +resolution (with automatic download of missing dependencies from repositories), building & +testing of code, deployment of software, etc. Maven's functionality is extensible with +plugins, so it's possible to use it not only for Java code (primary goal of this tool), +but also for code, written in other languages. You can read more about Maven in +following, freely available book.

Maven differs from other tools, such as Ant - it describes what we want to do, in +contrast with Ant, that describes how to it. Maven uses declarative style to +describe tasks that we want to execute, and all described tasks are performed by +the corresponding plugins.

Description of software lifecycle and information about project is stored in pom.xml, +a file that should exist in root directory of the project (and in root directories of +sub-projects, if your project is separated into several modules). Project's information +includes name, identifier and version of the project, and often includes more information: +URL of project's site, information about source code repository (so you can use mvn scm:update goal to update code, for example), etc.

Lifecycle Phases

Project Object Model (POM) defines set of stages for project's lifecycle - they are +called "lifecycle phases". Each phase can include several tasks (goals), that define what +will be performed on given stage. There are several common stages: compilation (compile), +testing (test), creation of package (package), and installation (install). Each of these +phases has dependencies on other phases, that should be executed before its invocation +(compilation should be executed before testing, testing before packaging, etc.).

Usually developer uses phase's name to start a process. For example, mvn package, or mvn install, etc. But developer can also execute concrete Maven's goal. To do this, he +should specify name of plugin, that implements concrete goal, and task name in given +plugin. For example, mvn clojure:run will start Clojure and execute script, specified in +configuration. We need to mention, that list of goals, that are executed for concrete +lifecycle phase isn't constant - you can change this list by modifying plugin's +configuration.

Maven and Clojure

Clojure's support in Maven is provided by +clojure-maven-plugin, that is available +in Maven's central repository, so it always available. (Besides clojure-maven-plugin, +there is also Zi plugin, that was developed as part of +Pallet project. In contrast to clojure-maven-plugin it's +written in Clojure, and more tightly integrated with Clojure-specific subsystems, such +Marginalia, Ritz, etc.)

As a base for your projects you can use pom.xml file from +clojure-maven-example project.

If you already have pom.xml in your project, then to enable this plugin, you will need to +add following code into <plugins> section of pom.xml:

  <plugin>
+    <groupId>com.theoryinpractise</groupId>
+    <artifactId>clojure-maven-plugin</artifactId>
+    <version>1.3.10</version>
+  </plugin>
+

Attention: version number could be changed as development continues. To find latest +plugin's version number you can use sites mvnrepository or Jarvana, that contains +information about packages, registered in Maven's repositories. Besides this, you can +omit plugin version - in this case, Maven will automatically use latest available version +(although this isn't always good idea).

Declaration of this plugin will give you all implemented functionality - compilation, +testing & running of code, written in Clojure, etc. Although, out of box you'll need to +use complete goals names, such as clojure:compile, clojure:test & clojure:run.

But you can make your life easier if you'll add these goals into list of goals for +concrete lifecycle phases (compile and test). To do this you need to add section +<executions> into plugin's description, as in following example:

 <plugin>
+   <groupId>com.theoryinpractise</groupId>
+   <artifactId>clojure-maven-plugin</artifactId>
+   <version>1.3.10</version>
+   <executions>
+     <execution>
+       <id>compile</id>
+       <phase>compile</phase>
+       <goals>
+         <goal>compile</goal>
+       </goals>
+     </execution>
+     <execution>
+       <id>test</id>
+       <phase>test</phase>
+       <goals>
+         <goal>test</goal>
+       </goals>
+     </execution>
+   </executions>
+ </plugin>
+

In this case, source code, written in Clojure will be compiled - this useful if you +implement gen-class, that will be used from Java, or if you don't want to provide source +code for your application. But sometimes it's much better just to pack source code into +jar, and it will compiled during loading of package (this is default behaviour when you're +declaring clojure packaging type) - this allows to avoid binary incompatibility between +different versions of Clojure. To put source code into jar, you need to add following +code into resources section (or change packaging type to clojure):

 <resource>
+   <directory>src/main/clojure</directory>
+ </resource>
+

By default, Clojure's source code is placed in the src/main/clojure directory of the +project's tree, while source code for tests is placed in the src/test/clojure directory. +These default values could be changed in plugin's configuration.

Goals in the Clojure Maven Plugin

clojure-maven-plugin implements several commands (goals) that could be divided into +following groups:

  • Goals that work with source code (usually they are linked with corresponding phases of +lifecycle, as it's shown above):

    • clojure:compile: compiles source code, written in Clojure;
    • clojure:test: executes tests, written in Clojure.
    • clojure:test-with-junit: executes tests using JUnit;
    • clojure:add-source: adds directory with source code to archive ...-sources.jar;
    • clojure:add-testsource: add directory with tests source code into archive +...-testsources.jar.
  • Goals for execution of project's code:

    • clojure:run: executes script (or scripts) defined by script and/or scripts +configuration directives. This goals is often used to run project with correct +dependencies;
    • clojure:repl: starts Clojure REPL with all dependencies, specified in project. If +necessary, it also executes script specified in configuration option replScript - for +example, you can put some initialization code into it. If the JLine library was +specified in dependencies, then it will be loaded automatically, making your work in +REPL more comfortable;
    • clojure:swank: starts Swank server, so you can connect to it from Emacs SLIME. By +default, this server is running on port 4005 (this value could be changed with system +option clojure.swank.port);
    • clojure:nailgun: starts Nailgun server, so you can connect to it from Vim with +vimclojure. By default, this server is running on port 2113 (this value could be +changed with system option clojure.nailgun.port).
  • Auxiliary tasks:

    • clojure:marginalia: generates documentation using Marginalia;
    • clojure:autodoc: generates documentation using autodoc;
    • clojure:gendoc: generates documentation using gendoc.

There are several Clojure-related repositories. All Clojure versions (stable & +development) are published at Sonatype repository that is periodically synchronized with +Maven Central. Clojars is repository that is used by Clojure community to publish their +projects.

To use repository you need to add following code into repositories section in pom.xml:

 <repository>
+   <id>clojars</id>
+   <url>http://clojars.org/repo/</url>
+ </repository>
+

Dependencies Management

Maven automatically downloads the all necessary dependencies from the default repository (known as +Maven Central), and +repositories, specified by user (as shown above). Downloaded packages are stored in +user's home directory and could be used by other projects without additional downloading. +Each package is uniquely identified by combination of three parameters - group's name +(the groupId tag), artifact's name (the artifactId tag), and version (the version tag).

To use Clojure in your project you need at least specify dependency on language itself. +Right now, the stable version of Clojure is 1.4.0. To declare this dependency, add +following code into dependencies section of pom.xml file:

 <dependency>
+   <groupId>org.clojure</groupId>
+   <artifactId>clojure</artifactId>
+   <version>1.4.0</version>
+ </dependency>
+

If you want to use the latest version of the language, then you need to add corresponding +repository (snapshots) and use version number like 1.5.0-master-SNAPSHOT instead of version +1.4.0.

To perform some tasks, implemented by clojure-maven-plugin, you need to specify additional +dependencies.

If you will use clojure:swank goal, then you need to specify dependency on swank-clojure package:

 <dependency>
+  <groupId>swank-clojure</groupId>
+  <artifactId>swank-clojure</artifactId>
+  <version>1.4.2</version>
+</dependency>
+

If you will use clojure:nailgun task, then you need to download distribution from +vimclojure's site, build it, as described in documentation, and install into local +Maven repository. And after this, you need to add following dependency on +vimclojure with following code:

<dependency>
+  <groupId>de.kotka</groupId>
+  <artifactId>vimclojure</artifactId>
+  <version>X.Y.Z</version>
+ </dependency>
+

The JLine library isn't required, but it could be useful if you plan to use the REPL - +this library implements support for command history and other nice things. Presence of this library is detected +automatically when mvn clojure:repl goal is executed. You can add dependency for this +library with following code:

 <dependency>
+  <groupId>jline</groupId>
+  <artifactId>jline</artifactId>
+  <version>0.9.94</version>
+ </dependency>
+

Plugin's Configuration

Developer can change plugin's configuration options, such as location of source code, +scripts names, etc. To change some parameter, you need to add its new value into +configuration section of the plugin's description. For example, you can specify name of +the script, that will be executed during testing, using following code:

<plugin>
+   <groupId>com.theoryinpractise</groupId>
+   <artifactId>clojure-maven-plugin</artifactId>
+   <version>1.3.10</version>
+   <configuration>
+     <testScript>src/test/clojure/test.clj</testScript>
+   </configuration>
+   .....
+ </plugin>
+

Following options are used to specify options related to source code & compilation:

  • sourceDirectories - this option defines list of directories (each of them should be +wrapped into sourceDirectory tag) that contains source code written in Clojure, and that +will be packed into resulting jar (and compiled, if corresponding option is specified);
  • testSourceDirectories - defines list of directories (each of them should be wrapped into +testSourceDirectory tag) with tests, written in Clojure;
  • warnOnReflection - option that enables (true) or disables (false) warnings about +reflection during compilation of source code.

Besides this, you can control which namespaces will be compiled and/or for which +namespaces testing of source code will be performed. To do this, you need to add +namespaces tag into configuration and list corresponding namespaces inside it (each of +item should be wrapped into namespace tag). You can use regular expressions to specify +all necessary namespaces, and you can also use ! to exclude namespaces from this list. In +addition to this option, you can use other two: compileDeclaredNamespaceOnly and +testDeclaredNamespaceOnly (with values true or false) - they control, will be these +namespace limitations applied during compilation and/or testing.

There are also several options that are used to specify parameters for execution of your +code and/or tests:

  • script and scripts - defines one (script tag) or several (scripts tag with nested script +tags) names of scripts with code, that will executed when you'll execute the +clojure:run task;
  • testScript: defines name of script that will executed when you'll execute clojure:test +task. If there was no value specified in plugin's configuration, then plugin will +automatically generate run script for all tests, that was found in project;
  • replScript - defines name of script, that will executed if you'll execute clojure:repl task +(it's also used by clojure:swank and clojure:nailgun tasks). This code will executed +before entering into REPL, so you can use it to specify initialization code for your +working environment;
  • runWithTests - enables (true) or disables (false) executions of tests if you run REPL or +your code via Maven. You can also change this value by using Maven's command-line +option. For example, using following command mvn clojure:repl -Dclojure.runwith.test=false;
  • clojureOptions - using this option you can specify command-line options that will be +passed to java process on every invocation.

Wrapping Up

I think, that this article provides enough information for you to start use Maven together +with Clojure. If you have Clojure-only project, and you don't plan to use all power of +Maven, then may be you can look to the Leiningen - this tool was created to build +projects, written mostly in Clojure. Another interesting project is Polyglot Maven, the +main goal of it is creation of special DSL (Domain Specificl Language) using different +languages (Clojure, Scala, Groovy) for description of Maven's configurations (for Clojure +this language is almost the same as language implemented in Leiningen).

Other examples of using Maven with Clojure you can find in different projects: Incanter +(as example of project, consisting from several modules), labrepl and +the clojure-maven-example.

Where To Learn More

More information on Clojure and Maven you can also find in +following blog posts:

Contributors

Alex Ott, 2012 (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/running_cljug/index.html b/clones/clojure-doc.org/articles/ecosystem/running_cljug/index.html new file mode 100644 index 00000000..ae1c0323 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/running_cljug/index.html @@ -0,0 +1,209 @@ + + + + + Clojure Guides: Running a Clojure User Group + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

About this tutorial

This guide covers:

  • Starting a user group
  • Tips for keeping it going
  • Meeting ideas

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

Starting a user group

Learning Clojure is easier (and more fun) if you can do it with others. Some of the essentials you will need to work out before your first meeting:

Meeting time

If you have a handful of interested parties, it's best to run a quick poll with some options for day of the week to find the most promising candidates and then unilaterally pick one. If evenings are challenging, consider a breakfast or lunch get together!

Location

Location can sometimes be the hardest part of creating a new group. Some ideas:

  • Ask a software, consulting, or recruiting company in the area. Hosting a group is a great way for potential hires to learn about a company.
  • Many libraries and public spaces can be reserved for meetings.
  • A get together at a local bar or coffee shop can be enough at the beginning.

Meeting format

Most Clojure user groups follow one of three models:

  • Talk with a speaker
  • Coding exercises (dojo, swarm coding, pairing, etc)
  • Informal chat

Speakers

If you have trouble getting speakers, try assigning a topic (a Clojure feature, library, etc) to someone to present at the next meeting.

Meeting organization

By far the two most popular ways to organize your group are Meetup (use discount code "clojure" for 50% off!) or Google group mailing lists. +Also consider creating a GitHub organization where attendees can find each others' code repos.

Keeping it going

Once you get the first meeting or two under your belt, you have to worry about how to keep it going. Consistency is one of the most important things in getting a group going - as much as possible try to stick to a stable meeting date and location.

When the group is young youโ€™ll need to spend some effort marketing to help it grow โ€” this is one of the reasons that Meetup.com shines. If there are local calendars, get your group listed.

Create a web site! Domain names and hosting are cheap โ€” itโ€™s totally worth creating a blog site dedicated to the group on your own domain name.

Create a Twitter account for the group and post info related to the group as well as specific to your topic. Ask all attendees to post about meetings on Twitter and blogs. Record your talks and put them on the net.

Consider using a private mailing list for those that attend the meetings. This is a somewhat unusual choice these days but having the limited membership means that you generally know the people that write on the mailing list and having it closed means that people can be a bit more free in asking newbie questions. Both factors contribute to a closer-knit feeling of local community.

Once you get to a certain size (or if you are fortunate to have good companies involved), you can find sponsors that provide food for your group.

Meeting ideas

Looking for meeting ideas? Here's some ideas....

  • Work through through the Clojure Koans
  • Work through problems from 4Clojure
  • Run a session on getting set up on Emacs with Clojure (or Vim, or ...)
  • Work through Project Euler problems
  • Work through a Code Kata
  • Implement a game (Tic-Tac-Toe, Rock-Paper-Scissors, Checkers, Othello, etc)
  • Build a web site for your group in Clojure and deploy it to Heroku!
  • Review and expand Clojure documentation guides
  • Look through the Clojure JIRA for bugs to work on

And some tips:

Troubleshooting

I can't find enough people for a group

You might think of broadening the scope to pull in people that are interested in something similar but not exactly the same. If you can't find enough +people for a Clojure user group, maybe a functional programming group would capture other people interested in Erlang, Scala, Haskell, F#, etc.

Contributors

Alex Miller alex@puredanger.com (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/user_groups/index.html b/clones/clojure-doc.org/articles/ecosystem/user_groups/index.html new file mode 100644 index 00000000..536eebe9 --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/user_groups/index.html @@ -0,0 +1,212 @@ + + + + + Clojure Guides: Clojure User Groups + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers Clojure User Groups (CLJUGs) around the world. If you want to add a new user group, +please see our How to Contribute guide.

If you are looking to start a new Clojure User Group (CLJUG), see How to run your own Clojure User Group +and feel free to submit a link to your CLJUG site or mailing list once you have it going.

North America

Europe

South America

TBD

Middle East, Asia & Pacific

Africa

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/ecosystem/web_development/index.html b/clones/clojure-doc.org/articles/ecosystem/web_development/index.html new file mode 100644 index 00000000..ff5a355c --- /dev/null +++ b/clones/clojure-doc.org/articles/ecosystem/web_development/index.html @@ -0,0 +1,239 @@ + + + + + Clojure Guides: Web Development (Overview) + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • popular tools and libraries for web development

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.4.

Some Options

Below are some of the various options available for web development +with Clojure, listed roughly by size.

Ring and Compojure

Perhaps the simplest and most minimal setup is to use only Ring and +Compojure. To get started, see the basic web development +tutorial.

lib-noir

In addition to Ring and Compojure, you might also make use of +lib-noir.

Luminus

Luminus is a lein +template for creating +batteries-included web applications. It makes use of Ring, Compojure, +lib-noir, and optionally (as described in its documentation) other +libraries.

Templating Libraries

Clojure has many options for building HTML.

Hiccup

Hiccup represents HTML as +Clojure data structures, allowing you to create and manipulate your +HTML easily.

Tinsel is a library that +extends Hiccup with selectors and transformers, so that you can write +a template separate from the insertion of your data into the template.

Mustache

Clostache implements the +Mustache templating language for +Clojure.

Stencil is another +implementation of Mustache.

Fleet

Fleet embeds Clojure inside HTML +templates, much like Java's JSPs, or Ruby's ERb.

Clabango

Clabango is modeled after the +Django templating system. It +embeds special tags and filters inside HTML templates to insert and +manipulate data.

Selmer

Selmer is also modeled after the Django +templating system with a primary goal of performance.

Enlive and Laser

Enlive and +Laser are similar libraries. They +both manipulate plain HTML, and can be used for screen scraping as +well as templating. They work with HTML templates with no special +embedded tags or code. They use selector functions to find pieces of +HTML and transformation function to change the HTML into the way you +want.

See the +Laser guide +to see if this style of templating works for you. It is powerful, but +different from most other languages' templating libraries.

See Also

Contributors

  • John Gabriele
  • Clinton Dreisbach
+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/collections_and_sequences/index.html b/clones/clojure-doc.org/articles/language/collections_and_sequences/index.html new file mode 100644 index 00000000..8cd5f166 --- /dev/null +++ b/clones/clojure-doc.org/articles/language/collections_and_sequences/index.html @@ -0,0 +1,648 @@ + + + + + Clojure Guides: Collections and Sequences in Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • Collections in Clojure
  • Sequences in Clojure
  • Core collection types
  • Key operations on collections and sequences
  • Other topics related to collections and sequences

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Overview

Clojure provides a number of powerful abstractions including collections and sequences. +When working with Clojure, +many operations are expressed as a series of operations on collections or sequences.

Most of Clojure's core library treats collections and sequences the same way, although +sometimes a distinction has to be made (e.g. with lazy infinite sequences).

clojure.core provides many fundamental operations on collections, such as: map, filter, +remove, take, and drop. Basic operations on collections and sequences are combined +to implement more complex operations.

Clojure Collections are Immutable (Persistent)

Clojure collections are immutable (persistent). The term "persistent data structures" has +nothing to do with durably storing them on disk. What it means is that collections are +mutated (updated) by producing new collections. To quote Wikipedia:

In computing, a persistent data structure is a data structure that always preserves +the previous version of itself when it is modified. Such data structures are effectively +immutable, as their operations do not (visibly) update the structure in-place, but instead +always yield a new updated structure.

Clojure's persistent data structures are implemented as trees and tries and +have O(log32 n) access complexity where n is the number of elements.

The Collection Abstraction

Clojure has a collection abstraction with several key operations supported for +all collection implementations. They are

  • =: checks value equality of a collection compared to other collections
  • count: returns number of elements in a collection
  • conj: adds an item to a collection in the most efficient way
  • empty: returns an empty collection of the same type as the argument
  • seq: gets a sequence of a collection

These functions work on all core Clojure collection types.

Core Collection Types

Clojure has several core collection types:

  • Maps (called hashes or dictionaries in some other languages)
  • Vectors
  • Lists
  • Sets

Maps

Maps associate keys with values. Boths keys and values can be of any type, but +keys must be comparable. There are several implementations of maps with +different guarantees about ordering. Hash maps are typically instantiated with literals:

{:language "Clojure" :creator "Rich Hickey"}
+

Commas can be used in map literals (Clojure compiler treats the comma as whitespace):

{:language "Clojure", :creator "Rich Hickey"}
+

clojure.core/sorted-map and clojure.core/array-map produce ordered maps:

(sorted-map :language "Clojure" :creator "Rich Hickey")
+;; โ‡’ {:creator "Rich Hickey", :language "Clojure"}
+
(array-map :language "Clojure" :creator "Rich Hickey")
+;; โ‡’ {:creator "Rich Hickey", :language "Clojure"}
+

Unsurprisingly, map literals must contain an even number of forms (as many keys as values). Otherwise +the code will not compile:

{:language "Clojure" :creator}
+

In general, the only major difference between Clojure maps and maps/hashes/dictionaries in some other languages +is that Clojure maps are immutable. When a Clojure map is modified, the result is a new map that internally +has structural sharing (for efficiency reasons) but semantically is a separate immutable value.

Maps As Functions

Maps in Clojure can be used as functions on their keys. See the Functions guide +for more information.

Keywords As Functions

Keywords in Clojure can be used as functions on maps. See the Functions guide +for more information.

Vectors

Vectors are collections that offer efficient random access (by index). They are typically instantiated with +literals:

[1 2 3 4]
+
+["clojure" "scala" "erlang" "f#" "haskell" "ocaml"]
+

Commas can be used to separate vector elements (Clojure compiler treats +the comma as whitespace):

["clojure", "scala", "erlang", "f#", "haskell", "ocaml"]
+

Unlike lists, vectors are not used for function invocation. They are, however, used to make certain +forms (e.g. the list of locals in let or parameters in defn) stand out visually. This was +an intentional decision in Clojure design.

Lists

Lists in Clojure are singly linked lists. Access or modifications of list head is efficient, random access +is not.

Lists in Clojure are special because they represent code forms, from function calls to macro calls to special forms. +Code is data in Clojure and it is represented primarily as lists:

(empty? [])
+

First item on the list is said to be in the calling position.

When used as "just" data structures, lists are typically instantiated with literals with quoting:

'(1 2 3 4)
+
'("clojure" "scala" "erlang" "f#" "haskell" "ocaml")
+

Or you can explicitly use the list form:

(list 1 2 3 4)
+;; โ‡’ (1 2 3 4)
+

Commas can be used to separate list elements (Clojure compiler treats +the comma as whitespace):

'("clojure", "scala", "erlang", "f#", "haskell", "ocaml")
+

Lists and Metaprogramming in Clojure

Metaprogramming in Clojure (and other Lisp dialects) is different from metaprogramming in, say, Ruby, because +in Ruby metaprogramming is primarily about producing strings while in Clojure it is about producing +data structures (mostly lists). For sophisticated DSLs, producing data structures directly lets +developers avoid a lot of incidental complexity that string generation brings along.

This topic is covered in detail in the Macros and Metaprogramming.

Sets

Sets are collections that offer efficient membership check operation and only allow each element to appear in the collection +once. They are typically instantiated with literals:

#{1 2 3 4}
+
#{"clojure" "scala" "erlang" "f#" "haskell" "ocaml"}
+

Commas can be used to separate set elements (Clojure compiler treats the as whitespace):

#{"clojure", "scala", "erlang", "f#", "haskell", "ocaml"}
+

Sets As Functions

Sets in Clojure can be used as functions on their elements. See the Functions guide +for more information.

Set Membership Checks

The most common way of checking if an element is in a set is by using set as a function:

(#{1 2 3 4} 1)
+;; โ‡’ 1
+
(#{1 2 3 4} 10)
+;; โ‡’ nil
+
(if (#{1 2 3 4} 1)
+  :hit
+  :miss)
+;; โ‡’ :hit
+

Sequences

The sequence abstraction represents a sequential view of a collection or collection-like +entity (computation result).

clojure.core/seq is a function that produces a sequence over the given argument. +Data types that clojure.core/seq can produce a sequence over are called seqable:

  • Clojure collections
  • Java maps
  • All iterable types (types that implement java.util.Iterable)
  • Java collections (java.util.Set, java.util.List, etc)
  • Java arrays
  • All types that implement java.lang.CharSequence interface, including Java strings
  • All types that implement clojure.lang.Seqable interface
  • nil

The sequence abstraction supports several operations:

  • first
  • rest
  • next

and there are two ways to produce a sequence:

  • seq produces a sequence over its argument (often a collection)
  • lazy-seq creates a lazy sequence (that is produced by performing computation)

seq, cons, list*

clojure.core/seq takes a single argument and returns a sequential view over it:

(seq [1 2 3])
+;; โ‡’ (1 2 3)
+

When given an empty collection or sequence, clojure.core/seq returns nil:

(seq [])
+;; โ‡’ nil
+

this is commonly used in the following pattern:

(if (seq xs)
+  (comment "Do something with this sequence")
+  (comment "Do something else"))
+

Another function that constructs sequences is clojure.core/cons. It prepends values to the head of +the given sequence:

(cons 0 (range 1 3))
+;; โ‡’ (0 1 2)
+

clojure.core/list* does the same for a number of values:

(list* 0 1 (range 2 5))
+;; โ‡’ (0 1 2 3 4)
+

clojure.core/cons and clojure.core/list* are primarily used to produce lazy sequences and in metaprogramming (when writing +macros). As far as metaprogramming goes, sequences and lists are the same and it is common to +add items in the beginning of the list (into the calling position).

Note that clojure.core/cons does not create cons cells and lists in Clojure are not implemented +as linked cons cells (like in many other dialects of Lisp).

first, rest, next

clojure.core/first returns the first item in the sequence. clojure.core/next and clojure.core/rest +return the rest:

(first (seq [1 2 3 4 5 6]))
+;; โ‡’ 1
+
+(rest (seq [1 2 3 4 5 6]))
+;; โ‡’ (2 3 4 5 6)
+

the difference between them is what they return on a single element sequence:

(rest (seq [:one]))
+;; โ‡’ ()
+
(next (seq [:one]))
+;; โ‡’ nil
+

Lazy Sequences in Clojure

Lazy sequences are produced by performing computation or I/O. They can be infinite +or not have exact length (e.g. a sequence of all powers of 2 or an audio stream).

Lazy sequences is an broad topic and covered in the Laziness guide.

Key Operations on Collections and Sequences

Below is an overview of clojure.core functions that work on collections and sequences. Most of them +work the same way for all types of collections, however, there are exception to this rule. For example, +functions like clojure.core/assoc, clojure.core/dissoc and clojure.core/get-in only really +make sense in the context of maps and other associative data structures (for example, records).

clojure.core/conj adds elements to a collection in the most efficient manner, which depends on +collection implementation details and won't be the same for vectors and lists.

In general, Clojure design emphasizes that operations on collections and sequences should be uniform and +follow the principle of least surprise. In real world projects, however, the difference between +algorithmic complexity and other runtime characteristics of various collection types often cannot +be ignored. Keep this in mind.

You can find more information in the clojure.core Overview and Clojure cheatsheet.

count

Returns a count of the number of items in a collection. An argument of nil returns 0.

(count "Hello")
+;; โ‡’ 5
+
(count [1 2 3 4 5 6 7])
+;; โ‡’ 7
+
(count nil)
+;; โ‡’ 0
+

Note that count does not return in constant time for all collections. This can be determined with counted?. +Keep in mind that lazy sequences must be realized to get a count of the items. This is often not intended and +can cause a variety of otherwise cryptic errors.

(counted? "Hello")
+;; โ‡’ false
+
;; will be fully realized when using (count (range 10))
+(counted? (range 10))
+;; โ‡’ false
+
;; Constant time return of (count)
+(counted? [1 2 3 4 5])
+;; โ‡’ true
+

conj

conj is short for "conjoin". As the name implies, conj takes a collection and argument(s) and returns the collection with those arguments added.

Adding items to a collection occurs at different places depending on the concrete type of collection.

List addition occurs at the beginning of the list. This is because accessing the head of the list is a constant time operation, and accessing +the tail requires traversal of the entire list.

(conj '(1 2) 3)
+;; โ‡’ (3 1 2)
+

Vectors have constant time access across the entire data structure. `'conj' thusly appends to the end of a vector.

(conj [1 2] 3)
+;; โ‡’ [1 2 3]
+

Maps do not have guaranteed ordering, so the location that items are added is irrelevant. conj requires vectors of [key value] pairs to be +added to the map.

(conj {:a 1 :b 2 :c 3} [:d 4])
+;; โ‡’ {:d 4, :a 1, :c 3, :b 2}
+
(conj {:cats 1 :dogs 2} [:ants 400] [:giraffes 13])
+;; โ‡’ {:giraffes 13, :ants 400, :cats 1, :dogs 2}
+

Sets also do not have guaranteed ordering. conj returns a set with the item added. As the concept of sets implies, added items will not duplicate equivalent items if they are present in the set.

(conj #{1 4} 5)
+;; โ‡’ #{1 4 5}
+
(conj #{:a :b :c} :b :c :d :e)
+;; โ‡’ #{:a :c :b :d :e}
+

get

get returns the value for the specified key in a map or record, index of a vector or value in a set. If the key is not present, +get returns nil or a supplied default value.

;; val of a key in a map
+(get {:a 1 :b 2 :c 3} :b)
+;; โ‡’ 2
+
;; index of a vector
+(get [10 15 20 25] 2)
+;; โ‡’ 20
+
;; in a set, returns the value itself if present
+(get #{1 10 100 2 20 200} 1)
+;; โ‡’ 1
+
+```klipse-clojure
+;; returns nil if key is not present
+(get {:a 1 :b 2} :c)
+;; โ‡’ nil
+
;; vector does not have an _index_ of 4. nil is returned
+(get [1 2 3 4] 4)
+;; โ‡’ nil
+
(defrecord Hand [index middle ring pinky thumb])
+(get (Hand. 3 4 3.5 2 2) :index)
+;; โ‡’ 3
+

get also supports a default return value supplied as the last argument.

;; index 4 does not exist. return default value
+(get [1 2 3 4] 4 "Not Found")
+;; โ‡’ "Not Found"
+
;; key :c does not exist, so return default value of 3
+(get {:a 1 :b 2} :c 3)
+;; โ‡’ 3
+

assoc

assoc takes a key and a value and returns a collection of the same type as the supplied collection with the key mapped to the new value.

assoc is similar to get in how it works with maps, records or vectors. When applied to a map or record, the same type is returned with the key/value pairs added or modified. When applied to a vector, a vector is returned with the key acting as an index and the index being replaced by the value.

Since maps and records can not contain multiple equivalent keys, supplying assoc with a key/value that exists in the one will cause assoc to return modify the key at that value in the result and not duplicate the key.

(assoc {:a 1} :b 2)
+;; โ‡’ {:b 2, :a 1}
+
(assoc {:a 1 :b 45 :c 3} :b 2)
+;; โ‡’ {:a 1, :c 3, :b 2}
+
(defrecord Hand [index middle ring pinky thumb])
+(assoc (Hand. 3 4 3.5 2 2) :index 3.75)
+;; โ‡’ #user.Hand{:index 3.75, :middle 4, :ring 3.5, :pinky 2, :thumb 2}
+

When using assoc with a vector, the key is the index and the value is the value to assign to that index in the returned vector. +The key must be <= (count vector) or an index out of bounds error will occur.

(assoc [1 2 76] 2 3) ; โ‡’ [1 2 3]
+
;; index 5 does not exist. valid indexes for this vector are: 0, 1, 2
+(assoc [1 2 3] 5 6)
+;; the error here is slightly different in Clojure/Script
+

When the key is equal to (count vector) assoc will add an item to the vector.

(assoc [1 2 3] 3 4) ; โ‡’ [1 2 3 4]
+

dissoc

dissoc returns a map with the supplied keys, and subsequently their values, removed. Unlike assoc, dissoc does not work on vectors. When a record is provided, dissoc returns a map. For similar functionality with vectors, see subvec and concat.

(dissoc {:a 1 :b 2 :c 3} :b)
+;; โ‡’ {:a 1, :c 3}
+
(dissoc {:a 1 :b 14 :c 390 :d 75 :e 2 :f 51} :b :c :e)
+;; โ‡’ {:a 1, :f 51, :d 75}
+
;; note that a map is returned, not a record.
+(defrecord Hand [index middle ring pinky thumb])
+;; always be careful with the bandsaw!
+(dissoc (Hand. 3 4 3.5 2 2) :ring)
+;; โ‡’ {:index 3, :middle 4, :pinky 2, :thumb 2}
+

first

first returns the first item in the collection. first returns nil if the argument is empty or is nil.

Note that for collections that do not guarantee order like some maps and sets, the behaviour of first should not be relied on.

(first (range 10))
+;; โ‡’ 0
+
(first [:floor :piano :seagull])
+;; โ‡’ :floor
+
(first [])
+;; โ‡’ nil
+

rest

rest returns a seq of items starting with the second element in the collection. rest returns an empty seq if the collection only contains a single item.

rest should also not be relied on when using maps and sets unless you are sure ordering is guaranteed.

(rest [13 1 16 -4])
+;; โ‡’ (1 16 -4)
+
(rest '(:french-fry))
+;; โ‡’ '()
+

The behaviour of rest should be contrasted with next. next returns nil if the collection only has a single item. This is important when considering "truthiness" of values since an empty seq is "true" but nil is not.

(if (rest '("stuff"))
+  (println "Does this print?"))
+;; yes, it prints.
+
;; NEVER FINISHES EXECUTION!!!
+;; "done" is never reached because (rest x) is always a "true" value
+(defn inf
+  [x]
+  (if (rest x)
+    (inf (rest x))
+    "done"))
+

empty?

empty? returns true if the collection has no items, or false if it has 1 or more items.

(empty? [])
+;; โ‡’ true
+
(empty? '(1 2 3))
+;; โ‡’ false
+

Do not confuse empty? with empty. This can be a source of great confusion:

(if (empty [1 2 3]) ;; empty returns an empty seq, which is true! use empty? here.
+  "It's empty"
+  "It's not empty")
+;; โ‡’ "It's empty"
+

empty

empty returns an empty collection of the same type as the collection provided.

(empty [1 2 3])
+;; โ‡’ []
+
(empty {:a 1 :b 2 :c 3})
+;; โ‡’ {}
+

not-empty

not-empty returns nil if the collection has no items. If the collection contains items, the collection is returned.

(not-empty '(:mice :elephants :children))
+;; โ‡’ (:mice :elephants :children)
+
(not-empty '())
+;; โ‡’ nil
+

contains?

contains returns true if the provided key is present in a collection. contains is similar to get in that vectors treat the key as an index. contains will always return false for lists.

(contains? {:a 1 :b 2 :c 3} :c)
+;; โ‡’ true
+
;; true if index 2 exists
+(contains? ["John" "Mary" "Paul"] 2)
+;; โ‡’ true
+
;; false if index 5 does not exist
+(contains? ["John" "Mary" "Paul"] 5)
+;; โ‡’ false
+
;; "Paul" does not exist as an index
+(contains? ["John" "Mary" "Paul"] "Paul")
+;; โ‡’ false
+
;; lists are not supported. contains? won't traverse a collection for a result.
+(contains? '(1 2 3) 0)
+;; โ‡’ java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.PersistentList
+

some

some will apply a predicate to each value in a collection until a non-false/nil result is returned then immediately return that result.

Since collections are "true" values, this makes it possible to return the first result itself rather than simply true.

(some even? [1 2 3 4 5])
+;; โ‡’ true
+
;; predicate returns the value rather than simply true
+(some #(if (even? %) %) [1 2 3 4 5])
+;; โ‡’ 2
+

Since maps can be used as functions, you can use a map as a predicate. This will return the value of the first key in the collection that is also in the map.

(some {:a 1 :b 5} [:h :k :d :b])
+;; โ‡’ 5
+

Sets can also be used as functions and will return the first item in the collection that is present in the set.

(some #{4} (range 20))
+;; โ‡’ 4
+

every?

every returns true if the predicate returns true for every item in the collection, otherwise it returns false.

(every? even? (range 0 10 2))
+;; โ‡’ true
+
;; set can be used to see if collection only contains items in the set.
+(every? #{2 3 4} [2 3 4 2 3 4])
+;; โ‡’ true
+

map

map is used to sequence of values and generate a new sequence of +values.

Essentially, you're creating a mapping from an old sequence of values +to a new sequence of values.

(def numbers
+  (range 1 10))
+;; โ‡’ (1 2 3 4 5 6 7 8 9)
+
(map (partial * 2) numbers)
+;; โ‡’ (2 4 6 8 10 12 14 16 18)
+
(def scores
+  {:clojure 10
+   :scala 9
+   :jruby 8})
+
+(map #(str "Team " (name (key %)) " has scored " (val %)) scores)
+;; โ‡’ ("Team scala has scored 9" "Team jruby has scored 8" "Team clojure has scored 10")
+

reduce

reduce takes a sequence of values and a function. It applies that +function repeatedly with the sequence of values to reduce it to a +single value.

(def numbers
+  (range 1 10))
+;; โ‡’ (1 2 3 4 5 6 7 8 9)
+
(reduce + numbers)
+;; โ‡’ 45
+
(def scores
+  {:clojure 10
+   :scala 9
+   :jruby 8})
+
+(reduce + (vals scores))
+;; โ‡’ 27
+
;; Provide an initial value for the calculation
+(reduce + 10 (vals scores))
+;; โ‡’ 37
+

filter

filter returns a lazy sequence of items that return true for the provided predicate. Contrast to remove.

(filter even? (range 10))
+;; โ‡’ (0 2 4 6 8)
+
(filter #(if (< (count %) 5) %) ["Paul" "Celery" "Computer" "Rudd" "Tayne"])
+;; โ‡’ ("Paul" "Rudd")
+

When using sets with filter, remember that if nil or false is in the set and in the collection, then the predicate will return itself: nil.

In this example, when nil and false are tested with the predicate, the predicate returns nil. This is because if the item is present in the set it is returned. This will cause that item to /not/ be included in the returned lazy-sequence.

(filter #{:nothing :something nil}
+       [:nothing :something :things :someone nil false :pigeons])
+;; โ‡’ (:nothing :something)
+

remove

remove returns a lazy sequence of items that return false or nil for the provided predicate. Contrast to filter.

(remove even? (range 10))
+;; โ‡’ (1 3 5 7 9)
+
;; relative complement. probably useless?
+(remove {:a 1 :b 2} [:h :k :z :b :s])
+;; โ‡’ (:h :k :z :s)
+

When using sets with remove, remember that if nil or false is in the set and in the collection, then the predicate will return itself: nil. +This will cause that item to be included in the returned lazy sequence.

In this example, when nil and false are tested with the predicate, the predicate returns nil. This is because if the item is present in the set it is returned.

(remove #{:nothing :something nil}
+        [:nothing :something :things :someone nil false :pigeons])
+;; โ‡’ (:things :someone nil false :pigeons)
+

iterate

iterate takes a function and an initial value, returns the result of +applying the function on that initial value, then applies the function +again on the resultant value, and repeats forever, lazily. Note that the +function iterates on the value.

(take 5 (iterate inc 1))
+;; โ‡’ (1 2 3 4 5)
+
(defn multiply-by-two
+  [value]
+  (* 2 value))
+
+(take 10 (iterate multiply-by-two 1))
+;; โ‡’ (1 2 4 8 16 32 64 128 256 512)
+

get-in

get-in is used to get a value that is deep inside a data +structure.

You have to provide the data structure and a sequence of keys, where a +key is valid at each subsequent level of the nested data structure.

If the sequence of keys does not lead to a valid path, nil is +returned.

(def family
+  {:dad {:shirt 5
+         :pants 6
+         :shoes 4}
+   :mom {:dress {:work 6
+                 :casual 7}
+         :book 3}
+   :son {:toy 5
+         :homework 1}})
+
(get-in family [:dad :shirt])
+;; โ‡’ 5
+
(get-in family [:mom :dress])
+;; โ‡’ {:work 6, :casual 7}
+
(get-in family [:mom :dress :casual])
+;; โ‡’ 7
+
(get-in family [:son :pants])
+;; โ‡’ nil
+
+```klipse-clojure
+(def locations
+  [:office :home :school])
+
+(get-in locations [1])
+;; โ‡’ :home
+

update-in

update-in is used to update a value deep inside a structure +in-place.

Note that since data structures are immutable, it only returns a +"modified" data structure, it does not actually alter the original +reference.

The "update" function takes the old value and returns a new value which +update-in uses in the new modified data structure.

(def family
+  {:dad {:shirt 5
+         :pants 6
+         :shoes 4}
+   :mom {:dress {:work 6
+                 :casual 7}
+         :book 3}
+   :son {:toy 5
+         :homework 1}})
+
(update-in family [:dad :pants] inc)
+
+;; โ‡’ {:son {:toy 5, :homework 1}, :mom {:dress {:work 6, :casual 7}, :book 3}, :dad {:shoes 4, :shirt 5, :pants 7}}
+

Notice that "pants" gets incremented

(def locations
+  [:office :home :school])
+
+(update-in locations [2] #(keyword (str "high-" (name %))))
+;; โ‡’ [:office :home :high-school]
+

assoc-in

assoc-in is used to associate a new value deep inside a structure +in-place.

Note that since data structures are immutable, it only returns a +"modified" data structure, it does not actually alter the original +reference.

Note the difference between update-in and assoc-in: update-in +takes a function that applies on the old value to return a new value, +whereas assoc-in takes a new value as-is.

(def family
+  {:dad {:shirt 5
+         :pants 6
+         :shoes 4}
+   :mom {:dress {:work 6
+                 :casual 7}
+         :book 3}
+   :son {:toy 5
+         :homework 1}})
+
(assoc-in family [:son :crayon] 3)
+;; โ‡’ {:son {:toy 5, :crayon 3, :homework 1}, :mom {:dress {:work 6, :casual 7}, :book 3}, :dad {:shoes 4, :shirt 5, :pants 6}}
+
(def locations
+  [:office :home :school])
+
+(assoc-in locations [3] :high-school)
+;; โ‡’ [:office :home :school :high-school]
+

keys

keys returns a sequence of the keys in a map or record.

(keys {1 "one" 2 "two" 3 "three"})
+;; โ‡’ (1 2 3)
+
(defrecord Hand [index middle ring pinky thumb])
+(keys (Hand. 2 4 3 1 2))
+;; โ‡’ (:index :middle :ring :pinky :thumb)
+

vals

vals returns a sequence of vals in a map or record.

(vals {:meows 20 :barks 2 :moos 5})
+;; โ‡’ (5 2 20)
+
(defrecord Hand [index middle ring pinky thumb])
+(vals (Hand. 1 2 3 4 5))
+;; โ‡’ (1 2 3 4 5)
+

select-keys

select-keys is used to extract a subset of a map:

(def family
+  {:dad {:shirt 5
+         :pant 6
+         :shoes 4}
+   :mom {:dress {:work 6
+                 :casual 7}
+         :book 3}
+   :son {:toy 5
+         :homework 1}})
+
(select-keys family [:dad])
+;; โ‡’ {:dad {:shoes 4, :shirt 5, :pant 6}}
+
(select-keys family [:mom :son])
+;; โ‡’ {:son {:toy 5, :homework 1}, :mom {:dress {:work 6, :casual 7}, :book 3}}
+

take

take returns a lazy sequence of the first n items of a collection coll.

(take 3 [1 3 5 7 9])
+;; โ‡’ (1 3 5)
+
(type (take 3 (range)))
+;; โ‡’ clojure.lang.LazySeq
+

If there are fewer than n items in coll, all items will be returned.

(take 5 [1 2 3])
+;; โ‡’ (1 2 3)
+
(take 3 nil)
+;; โ‡’ ()
+

drop

drop drops n items from a collection coll and returns a lazy sequence of the rest of it.

(drop 3 '(0 1 2 3 4 5 6))
+;; โ‡’ (3 4 5 6)
+
(drop 2 [1 2])
+;; โ‡’ ()
+
(drop 2 nil)
+;; โ‡’ ()
+

take-while

take-while returns a lazy sequence of items from a collection as long +as the predicate returns true for each item:

(take-while #(< % 5) (range))
+;; โ‡’ (0 1 2 3 4)
+

drop-while

drop-while drops items from a collection as long as the predicate +returns false for the item and when the first non-false item is found, +it returns a lazy sequence from that item onwards:

(drop-while #(< % 5) (range 10))
+;; โ‡’ (5 6 7 8 9)
+

Transients

Clojure data structures are immutable, they do not change. Mutating them produces +a new data structure that internally has structural sharing with the original +one. This makes a whole class of concurrency hazards go away but has some +performance penalty and additional GC pressure.

For cases when raw performance for a piece of code is more important than safety, +Clojure provides mutable versions of vectors and unsorted maps. They are known +as transients and should only be used for locals and as an optimization +technique after profiling.

Transients are produced from immutable data structures using the clojure.core/transient +function:

(let [m (transient {})]
+  (assoc! m :key "value") ;; mutates the transient in place!
+  (count m))
+;; โ‡’ 1
+

Note that clojure.core/transient does not affect nested collections, for +example, values in a map of keywords to vectors.

To mutate transients, use clojure.core/assoc!, clojure.core/dissoc! and +clojure.core/conj!. The exclamation point at the end hints that these +functions work on transients and modify data structures in place, which +is not safe of data structures are shared between threads.

To create an immutable data structure out of a transient, use clojure.core/persistent!:

(let [m (transient {})]
+        (assoc! m :key "value")
+        (persistent! m)) ;; โ‡’ {:key "value"}
+

In conclusion: use transients only as an optimization technique and only +after profiling and identifying hot spots in your code. Guessing is the +shortest way we know to blowing the performance.

Custom Collections and Sequences

It is possible to develop custom collection types in Clojure or Java and have +clojure.core functions work on them just like they do on builtin types.

TBD: How to Contribute

Wrapping Up

When working with Clojure, it is common to operate and transform collections and sequences. +Clojure's core library unify operations on collections and sequences where possible. +This extends to Java collections, arrays and iterable objects for seamless interoperability.

Most of the time, whenever you need a function that transforms sequences, chances are, there is +one already that does that in clojure.core or you can compose more than one clojure.core function +to achieve the same result.

Contributors

Michael Klishin michael@defprotocol.org +Robert Randolph audiolabs@gmail.com +satoru satorulogic@gmail.com

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/concurrency_and_parallelism/index.html b/clones/clojure-doc.org/articles/language/concurrency_and_parallelism/index.html new file mode 100644 index 00000000..df30fb7b --- /dev/null +++ b/clones/clojure-doc.org/articles/language/concurrency_and_parallelism/index.html @@ -0,0 +1,755 @@ + + + + + Clojure Guides: Concurrency and Parallelism in Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • Clojure's identity/value separation
  • Clojure reference types and their concurrency semantics: atoms, refs, agents, vars
  • Dereferencing
  • Delays, futures and promises
  • Watches and validators
  • How to use java.util.concurrent from Clojure
  • Other approaches to concurrency available on the JVM
  • Other topics related to concurrency

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Before You Read This Guide

This is one of the most hardcore guides of the entire Clojure documentation +project. It describes concepts that are simple but may seem foreign at first. +These concepts are some of the key points of Clojure +design. Understanding them may take some time for folks without +a concurrent programming background. Don't let this learning curve +discourage you.

If some parts are not clear, please ask for clarification on the +mailing +list or +file an issue on GitHub. +We will work hard on making this guide easy to follow with edits and +images to illustrate the concepts.

Introduction and Terminology

Before we get to the Clojure features related to concurrency, lets lay a foundation and briefly +cover some terminology.

TermDefinition This Guide Uses
ConcurrencyWhen multiple threads are making progress, whether it is via time-slicing or parallelism
ParallelismA condition that arises when at least two threads are executing simultaneously, e.g., on multiple cores or CPUs.
Shared StateWhen multiple threads of execution need to mutate (modify) one or more pieces of program state (e.g., variables, identities)
Mutable Data StructuresData structures that, when changed, are updated "in place"
Immutable Data StructuresData structures that, when changed, produce new data structures (copies), possibly with optimizations such as internal structural sharing
Concurrency HazardsConditions that occur in concurrent programs that prevent program from being correct (behaving the way its authors intended).
Shared Mutable StateWhen shared state is made of mutable data structures. A ripe ground for concurrency hazards.

There are many concurrency hazards, some of the most common and well known are:

Concurrency HazardBrief Description
Race ConditionA condition when the outcome is dependent on timing or relative ordering of events
DeadlockWhen two or more threads are waiting on each other to finish or release a shared resource, thus waiting forever and not making any progress
LivelockWhen two or more threads are technically performing computation but not doing any useful work (not making progress), for example, + because they endlessly pass a piece of data to each other but never actually process it
StarvationWhen a thread is not given regular access to a shared resource and cannot make progress.

These hazards are not exclusive to threads and can happen with OS +processes, runtime processes and any other execution processes. They +are also not specific to a particular runtime or VM (e.g., the JVM) or +programming language. Admittedly, some languages make it significantly +easier to write correct, safe concurrent programs, but none are +completely immune to concurrency hazards. More often than not, +concurrency hazards are algorithmic problems, languages just encourage +or discourage certain practices and techniques.

Thread-safe code is code that is always executed correctly and does +not suffer from concurrency hazards even when executed concurrently +from multiple threads.

Overview

One of Clojure design goals was to make concurrent programming +easier. The thinking is that as modern CPUs add more and more cores +and the number of CPUs is increasing as well, the biggest contributor +to application throughput will come from making use of those +resources.

The key design decision was making Clojure data structures immutable +(persistent) and separating the concepts of identity and +value. The importance of immutability cannot be over-emphasized: +immutable values can be safely shared between threads, eliminate many +concurrency hazards, and ultimately make it easier for developers to +reason about their programs.

However, a language that only has immutable data structures and no way +to change (mutate) program state is not very useful. The +identity/value separation makes state mutations (e.g., incrementing a +counter or adding an element to a list) possible in ways that +have known guarantees with respect to concurrency. This separation largely +eliminates the need for explicit use of locks, which is possible in Clojure +but typically not necessary.

To put it another way: "changing variables" in Clojure happens +differently from many other languages; in ways that are predictable +from the concurrency perspective and which eliminate many concurrency hazards.

Next lets take a closer look to the identity/value separation.

Identity/Value Separation ("on State and Identity")

In Clojure, values are immutable. They never change. For example, a number is a value. +A map {:language "Clojure"} is a value. A vector with 3 elements is a value.

When you attempt to modify a value (a data structure), a new value is produced instead. These +are known as persistent data structures (the word "persistent" has nothing to do with +storing data on disk).

An identity is a named entity (e.g., a list of active chat group +members or a counter) that changes over time and at any given moment references a value. +For example, the current value of a counter may be 42. After incrementing it, the value +is 43 but it is still the same counter --- the same identity. This is different from, say, Java +or Ruby, where variables serve as identities that (typically) point to a mutable value +and which are modified in place.

identity_value

Identities in Clojure can be of several types, known as reference types.

Clojure Reference Types

Overview

In Clojure's world view, concurrent operations can be roughly +classified as coordinated or uncoordinated, and synchronous or +asynchronous. Different reference types in Clojure have their own +concurrency semantics and cover different kind of operations:

CoordinatedUncoordinated
SynchronousRefsAtoms
Asynchronousโ€”Agents
Coordinated
An operation that depends on cooperation from other operations (possibly, other operations at least do not interfere with it) + in order to produce correct results. For example, a banking operation that involves more than one account. +
Uncoordinated
An operation that does not affect other operations in any way. For example, when downloading 100 Web pages concurrently, + each operation does not affect the others. +
Synchronous
When the caller's thread waits, blocks, or sleeps until it has access to a given resource or context.
Asynchronous
Operations that can be started or scheduled without blocking the caller's thread.

One more reference type, vars, supports dynamic scoping and thread-local storage.

Atoms

Atoms are references that change atomically (changes become immediately visible to all threads, +changes are guaranteed to be synchronized by the JVM). If you come from a Java background, +atoms are basically atomic references from java.util.concurrent with a functional twist +to them. Atoms are identities that implement synchronous, uncoordinated, atomic updates.

Lets jump right in and demonstrate how atoms work using an example. We know that Clojure data +structures are immutable by default. Adding an element to a collection really produces a new +collection. In such case, how does one keep a shared list (say, of active connections to a server +or recently crawled URLs) and mutate it in a thread-safe manner? We will demonstrate how to +accomplish this with an atom.

To create an atom, use the clojure.core/atom function. Its argument will serve as the atom's +initial value:

(def currently-connected (atom []))
+

The line above makes the atom currently-connected an empty vector. To access an atom's value, use +clojure.core/deref or the @atom reader form:

(def currently-connected (atom []))
+
+@currently-connected
+;; โ‡’ []
+(deref currently-connected)
+;; โ‡’ []
+currently-connected
+;; โ‡’ #<Atom@614b6b5d: []>
+

As the returned values demonstrate, the atom itself is a reference. To +access its current value, you dereference it. Dereferencing will be +covered in more detail later in this guide. For now, it is sufficient +to say that dereferencing returns the current value of an atom. (Other +Clojure reference types as well as a few specialized data structures +can be dereferenced as well.)

Locals can be atoms, too:

(let [xs (atom [])]
+  @xs)
+;; โ‡’ []
+

Now to the most interesting part: adding elements to the collection.

To mutate an atom, we can use clojure.core/swap!.

swap! takes an atom, a function and optionally some other args, swaps the current value of the atom to be the return value of calling the function with the current value of the atom and the args:

(swap! currently-connected conj "chatty-joe")
+;; โ‡’ ["chatty-joe"]
+currently-connected
+;; โ‡’ #<Atom@614b6b5d: ["chatty-joe"]>
+@currently-connected
+;; โ‡’ ["chatty-joe"]
+

To demonstrate this graphically, initial atom state looks like this:

Atom state 1

and then we mutated it with swap!:

Atom state 2

For the readers familiar with the atomic types from the java.util.concurrent.atomic package, +this should sound very familiar. The only difference is that instead of setting a value, atoms are mutated +with a function. This is both because Clojure is a functional language and because with this approach, +clojure.core/swap! can retry the operation safely. This implies that the function you provide to +swap! is pure (has no side effects).

Occasionally you will need to mutate the value of an atom the same way you would with atomic references in Java: +by setting them to a specific value. This is what clojure.core/reset! does. It takes an atom and the new value:

@currently-connected
+;; โ‡’ ["chatty-joe"]
+(reset! currently-connected [])
+;; โ‡’ []
+@currently-connected
+;; โ‡’ []
+

reset! may be useful in test suites to reset an atom's state between test executions, but it should be +used sparingly in your implementation code. Consider using swap! first.

TBD: demonstrate retries under high update rates

Summary and Use Cases

Atoms is the most commonly used concurrent feature in Clojure. It covers many cases and lets developers +avoid explicit locking. Atoms cover a lot of use cases and are very fast. It's fair to say that +when you need uncoordinated reference types (e.g., not Software Transactional Memory), the rule of +thumb is, "start with an atom, then see".

It is not uncommon to initialize an atom in a local and then return it from the function and share +a piece of state with other functions and/or threads.

Agents

Agents are references that are updated asynchronously: updates happen at a later, unknown point +in time, in a thread pool. Agents are identities that implement uncoordinated, asynchronous updates.

A small but useful example of using an agent is as a counter. For +example, suppose we want to track how often page downloads in a Web +crawler respond with 40x and 50x status codes. The simplest version +can look like this:

(def errors-counter (agent 0))
+;; โ‡’ #'user/errors-counter
+errors-counter
+;; โ‡’ #<Agent@6a6287b2: 0>
+@errors-counter
+;; โ‡’ 0
+(deref errors-counter)
+;; โ‡’ 0
+

One can immediately make several observations: just like atoms, agents are references. To get +the current value of an agent, we need to dereference it using clojure.core/deref or +the @agent reader macro.

To mutate an agent, we use clojure.core/send and clojure.core/send-off:

@errors-counter
+;; โ‡’ 0
+(send errors-counter inc)
+;; โ‡’ #<Agent@6a6287b2: 0>
+@errors-counter
+;; โ‡’ 1
+
+;; 10 is an additional parameter. The + function will be invoked as `(+ @errors-counter 10)`.
+(send errors-counter + 10)
+;; โ‡’ #<Agent@6a6287b2: 1>
+@errors-counter
+;; โ‡’ 11
+

send and send-off are largely similar. The difference is in how they are implemented. send uses a +fixed-size thread pool so using blocking operations with it won't yield good throughput. send-off +uses a growing thread-pool so blocking operations is not a problem for it as long as there are resources +available to the JVM to create and run all the threads. On a 4-8 GB machine with 4 cores and stock +OS settings you can expect up to a couple of thousand I/O-bound threads to work without running +the system out of kernel resources.

Using Custom Executors With Agents

Agents can be used (and abused) for arbitrary code execution in a thread pool. Because the default +thread pool Clojure maintains will not be a good fit for all use cases, Clojure 1.5 introduced +a function that lets you control what thread pool (executor) is used by clojure.core/send: +clojure.core/set-agent-send-executor!.

(import java.util.concurrent.Executors)
+
+(set-agent-send-executor! (Executors/newFixedThreadPool 32))
+;; clojure.core/send now will use the fixed size thread pool with 32 threads
+

The default thread pool size is number of available CPU cores + 2.

clojure.core/set-agent-send-off-executor! is a similar function that controls what +thread pool clojure.core/send-off will use.

Finally, another new function in 1.5 is clojure.core/send-via which is like `` but lets you specify +an executor to be used on a case-by-case basis:

(import java.util.concurrent.Executors)
+
+(def custom-pool (Executors/newFixedThreadPool 32))
+;; just like clojure.core/send but will use custom-pool instead
+;; of an internally maintained one
+(send-via custom-pool stream-agent inc)
+

Agents and Software Transactional Memory

We haven't introduced refs and the concept of Software Transactional Memory yet. It will be covered later in this +guide. Here it's sufficient to mention that agents are STM-aware and can be safely used inside transactions.

Agents and Error Handling

Functions that modify an agent's state will not always return successfully in the real world. Sometimes they +will fail. For example:

@errors-counter
+;; โ‡’ 11
+(send errors-counter / 0)
+;; Evaluation aborted.
+;; โ‡’ nil
+

This puts the agent into the failed state. Failed agents will re-raise the exception that caused them +to fail every time their state changed is attempted:

(send errors-counter / 0)
+;; โ‡’ #<Agent@6a6287b2: 10>
+(send errors-counter inc)
+;; Evaluation aborted.
+

To access the exception that occured during the agent's state mutation, use clojure.core/agent-error:

(send errors-counter / 0)
+;; Evaluation aborted.
+;; โ‡’ nil
+(agent-error errors-counter)
+;; โ‡’ #<ArithmeticException java.lang.ArithmeticException: Divide by zero>
+

It returns an exception. Agents can be restarted with clojure.core/restart-agent that takes an agent +and a new initial value:

(restart-agent errors-counter 0)
+;; โ‡’ 0
+(send errors-counter + 10)
+;; โ‡’ #<Agent@6a6287b2: 0>
+@errors-counter
+;; โ‡’ 10
+

If you'd prefer an agent to ignore exceptions instead of going into the failure mode, clojure.core/agent +takes an option that controls this behavior: :error-mode. Because completely ignoring errors is rarely a good +idea, when the error mode is set to :continue you must also pass an error handler function:

(def errors-counter (agent 0
+                           :error-mode    :continue
+                           :error-handler (fn [failed-agent ^Exception exception]
+                                            (println (.getMessage exception)))))
+;; โ‡’ #'user/errors-counter
+(send errors-counter inc)
+;; โ‡’ #<Agent@5620e147: 1>
+(send errors-counter inc)
+;; โ‡’ #<Agent@5620e147: 2>
+(send errors-counter / 0)
+;; output: "Divide by zero"
+;; โ‡’ #<Agent@5620e147: 2>
+(send errors-counter inc)
+;; โ‡’ #<Agent@5620e147: 3>
+@errors-counter
+;; โ‡’ 3
+

The handler function takes two arguments: an agent and the exception that occured.

Summary and Use Cases

Agents are asynchronously updated references. They can be used for anything that does +not require strict consistency for reads:

  • Counters (e.g. message rates in event processing)
  • Collections (e.g. recently processed events)

Agents can be used for offloading arbitrary computations to a thread pool, however, +only starting with Clojure 1.5 they can provide the same flexiblity as JDK executors +(thread pools).

Refs

Refs are the only coordinated reference type Clojure has. They help ensure that multiple +identities can be modified concurrently within a transaction:

  • Either all refs are modified or none are
  • No race conditions between involved refs
  • No possibility of deadlocks between involved refs

Refs provide ACI of ACID. Refs +are backed by Clojure's implementation of software transactional +memory (STM).

To instantiate a ref, use the clojure.core/ref function:

(def account-a (ref 0))
+;; โ‡’ #'user/account-a
+(def account-b (ref 0))
+;; โ‡’ #'user/account-b
+

Like atoms and agents covered earlier, to get the current value of a ref, use clojure.core/deref or the "@" +reader macro:

(deref account-a)
+;; โ‡’ 0
+@account-b
+;; โ‡’ 0
+

Refs are for coordinated concurrent operations and so it does not make much sense to use a single ref +(in that case, an atom would be sufficient). Refs are modified in a transaction in the clojure.core/dosync +body.

clojure.core/dosync starts a transaction, performs all modifications and commits changes. If a concurrently +running transaction modifies a ref in the current transaction before the current transaction commits, +the current transaction will be retried to make sure that the most recent value of the modified +ref is used.

TBD: a picture that visualizes retries and serializability.

alter

Refs are modified using clojure.core/alter which is very similar to +clojure.core/swap! in the arguments it takes: a ref, a function that +takes an old value and returns a new value of the ref, and any number +of optional arguments to pass to the function.

In the following example, two refs are initialized at 1000, +representing two bank accounts. Then 100 units are transferred from +one account to the other, atomically:

(def account-a (ref 1000))
+;; โ‡’ #'user/account-a
+(def account-b (ref 1000))
+;; โ‡’ #'user/account-b
+
+(dosync
+  ;; will be executed as (+ @account-a 100)
+  (alter account-a + 100)
+  ;; will be executed as (- @account-b 100)
+  (alter account-b - 100))
+;; โ‡’ 900
+@account-a
+;; โ‡’ 1100
+@account-b
+;; โ‡’ 900
+

Conflicts and Retries

TBD: explain transaction conflicts, demonstrate transaction retries

commute

With a high number of concurrently running transactions, retries +overhead can become noticeable. Some modifications, however, can be +applied in any order. Clojure's STM implementation acknowledges this +fact and provides an alternative way to modify refs: +clojure.core/commute. commute must only be used for operations +that commute in the mathematical +sense: +the order can be changed without affecting the result. For example, +addition is commutative (1 + 10 produces the same result as 10 + 1) +but substraction is not (1 โˆ’ 10 does not equal 10 โˆ’ 1).

clojure.core/commute has the same signature as clojure.core/alter:

@account-a
+;; โ‡’ 1100
+@account-b
+;; โ‡’ 900
+(dosync
+  (commute account-a + 300)
+  (commute account-b + 300))
+;; โ‡’ 1200
+@account-a
+;; โ‡’ 1400
+@account-b
+;; โ‡’ 1200
+

Note that a change made to a ref by commute will never cause a transaction +to retry. commute does not cause transaction conflicts.

Using Refs With Clojure Data Structures

TBD: demonstrate more complex changes, e.g., to game characters

Limitations of Refs

Software transactional memory is a powerful but highly specialized tool. Because transactions can be retried, +you must only use pure functions with STM. I/O operations cannot be undone by the runtime and very often are +not idempotent.

Structuring your application code as pure core and edge code that interacts with the user or other +services (performing I/O operations and other side-effects) helps with this. In that case, the pure core +can use STM without issues.

For example, in a Web or network server, incoming requests are the edge code: they do I/O. The pure core +is then called to modify server state, do any calculations necessary, return a result that is returned +back to the client by the edge code:

TBD: a picture to demonstrate

Unlike some other languages and runtimes (for example, Haskell), Clojure will not prevent you from +doing I/O in transactions. It is left as a matter of discipline on the programmer's part. It does provide +a helper function, though: clojure.core/io! will raise an exception if there is an STM transaction +running and has no effect otherwise.

First, an example with pure code:

(io!
+  ;; pure code, clojure.core/io! has no effect
+  (reduce + (range 0 100)))
+;; โ‡’ 4950
+

And an example that invokes functions that are guarded with clojure.core/io! in an STM +transaction:

(defn render-results
+  "Prints results to the standard output"
+  []
+  (io!
+    (println "Results:")
+    (comment ...)))
+;; โ‡’ #'user/render-results
+(dosync
+  (alter account-a + 100)
+  (alter account-b - 100)
+  (render-results))
+;; throws java.lang.IllegalStateException, "I/O in transaction!"
+

Summary and Use Cases

TBD

Vars

Vars are the reference type you are already familiar with. You define them via the def special form:

(def url "http://en.wikipedia.org/wiki/Margarita")
+

Functions defined via defn are also stored in vars. Vars can be dynamically scoped. They have +root bindings that are initially visible to all threads. When defining a var +with def, you define a var that only has root binding, so its value will be the same no matter +what thread you use it from:

(def url "http://en.wikipedia.org/wiki/Margarita")
+;; โ‡’ #'user/url
+(.start (Thread. (fn []
+                   (println (format "url is %s" url)))))
+;; outputs "url is http://en.wikipedia.org/wiki/Margarita"
+;; โ‡’ nil
+(.start (Thread. (fn []
+                   (println (format "url is %s" url)))))
+;; outputs "url is http://en.wikipedia.org/wiki/Margarita"
+;; โ‡’ nil
+

Dynamic Scoping and Thread-local Bindings

To temporarily change var value, we need to make the var dynamic by adding :dynamic true to its +metadata and then use clojure.core/binding:

(def ^:dynamic *url* "http://en.wikipedia.org/wiki/Margarita")
+;; โ‡’ #'user/*url*
+(println (format "*url* is now %s" *url*))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Margarita"
+
+(binding [*url* "http://en.wikipedia.org/wiki/Cointreau"]
+  (println (format "*url* is now %s" *url*)))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Cointreau"
+;; โ‡’ nil
+

Note that, by convention, vars which are supposed to or may be dynamically scoped are named with leading +and trailing asterisks * (often referred to as "earmuffs").

In the example above, binding temporarily changed the var's current value to a different URL. But that happened only +in the same thread as the var was originally defined in. What makes vars interesting from the concurrency +point of view is that their bindings can be thread-local (yes, if you are familiar with thread-local variables +in Java or Ruby, it is very similar and serves largely the same purpose). To demonstrate, let's change +the example to spin up 3 threads and alter the var's value from them:

(def ^:dynamic *url* "http://en.wikipedia.org/wiki/Margarita")
+;; โ‡’ #'user/*url*
+(println (format "*url* is now %s" *url*))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Margarita"
+;; โ‡’ nil
+(.start (Thread. (fn []
+          (binding [*url* "http://en.wikipedia.org/wiki/Cointreau"]
+            (println (format "*url* is now %s" *url*))))))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Cointreau"
+;; โ‡’ nil
+(.start (Thread. (fn []
+                   (binding [*url* "http://en.wikipedia.org/wiki/Guignolet"]
+                     (println (format "*url* is now %s" *url*))))))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Guignolet"
+;; โ‡’ nil
+(.start (Thread. (fn []
+                   (binding [*url* "http://en.wikipedia.org/wiki/Apรฉritif"]
+                     (println (format "*url* is now %s" *url*))))))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Apรฉritif"
+;; โ‡’ nil
+(println (format "*url* is now %s" *url*))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Margarita"
+;; โ‡’ nil
+

As you can see, var scoping in different threads did not modify the var's value in the thread it was +originally defined in (its root binding). In real-world cases, for example, it means that a multi-threaded +Web crawler can store some crawling state specific to a particular thread in a var and not +modify its initial (global) value.

How to Alter Var Root

Sometimes, however, modifying the root binding is necessary. This is done via clojure.core/alter-var-root +which takes a var (not its value) and a function that takes the old var value and returns a new one:

*url*
+;; โ‡’ "http://en.wikipedia.org/wiki/Margarita"
+(.start (Thread. (fn []
+                   (alter-var-root (var user/*url*) (fn [_] "http://en.wikipedia.org/wiki/Apรฉritif"))
+                   (println (format "*url* is now %s" *url*)))))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Apรฉritif"
+;; โ‡’ nil
+*url*
+;; โ‡’ "http://en.wikipedia.org/wiki/Apรฉritif"
+

clojure.core/var is used to locate the var (user/*url* in our example executed in the REPL). Note that it +finds the var itself (the reference, the "box"), not its value (what the var evalutes to).

In the example above the function we use to alter var root ignores the current value and simply returns a +predefined string:

(fn [_] "http://en.wikipedia.org/wiki/Apรฉritif")
+

Such functions are common enough for clojure.core to provide a convenience higher-order function called +clojure.core/constantly. It takes a value and returns a function that, when executed, ignores all its parameters +and returns that value. So, the function above would be more idiomatically written as

*url*
+;; โ‡’ "http://en.wikipedia.org/wiki/Margarita"
+(.start (Thread. (fn []
+                   (alter-var-root (var user/*url*) (constantly "http://en.wikipedia.org/wiki/Apรฉritif"))
+                   (println (format "*url* is now %s" *url*)))))
+;; outputs "*url* is now http://en.wikipedia.org/wiki/Apรฉritif"
+;; โ‡’ nil
+*url*
+;; โ‡’ "http://en.wikipedia.org/wiki/Apรฉritif"
+

When is alter-var-root used in real world scenarios? Some Clojure data store and API clients stores active connection +in a var, so initial connection requires root binding modification.

Summary and Use Cases

To summarize: vars can have dynamic scope. They have a root binding and can have thread-local bindings as well. +As such, vars are good for storing pieces of program state that vary between threads but cannot +be stored in a function local. alter-var-root is used to alter root binding of a var. It is done +the functional way: by providing a function that takes the old var value and returns a new one.

To alter var root to a specific known value, use clojure.core/constantly.

Dereferencing

Earlier sections demonstrated the concept of dereferencing. Dereferencing means retrieving the current +value of a reference (an atom, an agent, a ref, etc). To dereference a Clojure reference, use +clojure.core/deref or the @reference reader macro:

(let [xs (atom [])]
+  @xs)
+;; โ‡’ []
+

Besides atoms, agents, and refs, Clojure has several other concurrency-oriented data structures +that can be dereferenced: delays, futures, and promises. They will be covered later in this +guide.

Dereferencing Support For Data Types Implemented In Java

It is possible to make custom data types implemented in Java support dereferencing by +making them implement the clojure.lang. interface:

package clojure.lang;
+
+public interface IDeref{
+  Object deref();
+}
+

This can be done to make data types implemented in Java look and feel more like built-in +Clojure data types, or make it possible to pass said types to a function that expects +its arguments to be dereferenceable.

Delays

In Clojure, a delay is a data structure that is evaluated the first time it is dereferenced. +Subsequent dereferencing will use the cached value. Delays are instantiated with the clojure.core/delay +function.

In the following example a delay is used to calculate a timestamp that is later used +as a cached value:

(def d (delay (System/currentTimeMillis)))
+;; โ‡’ #'user/d
+d
+;; โ‡’ #<Delay@21ed22af: :pending>
+;; dereferencing causes the value to be realized, it happens only once
+@d
+;; โ‡’ 1350997814621
+@d
+;; โ‡’ 1350997814621
+@d
+;; โ‡’ 1350997814621
+

clojure.core/realized? can be used to check whether a delay instance has been realized +or not:

(def d (delay (System/currentTimeMillis)))
+;; โ‡’ #'user/d
+(realized? d)
+;; โ‡’ false
+@d
+;; โ‡’ 1350997967984
+(realized? d)
+;; โ‡’ true
+

Futures

A Clojure future evaluates a piece of code in another thread. To instantiate a future, +use clojure.core/future. The future function will return immediately (it never blocks +the current thread). To obtain the result of computation, dereference the future:

(def ft (future (+ 1 2 3 4 5 6)))
+;; โ‡’ #'user/ft
+ft
+;; โ‡’ #<core$future_call$reify__6110@effa25e: 21>
+@ft
+;; โ‡’ 21
+

Dereferencing a future blocks the current thread. Because some operations may take +a very long time or get blocked forever, futures support a timeout specified +when you dereference them:

;; will block the current thread for 10 seconds, returns :completed
+(def ft (future (Thread/sleep 10000) :completed))
+;; โ‡’ #'user/ft
+(deref ft 2000 :timed-out)
+;; โ‡’ :timed-out
+

Subsequent access to futures using deref will use the cached value, just like it +does for delays.

Just like delays, it is possible to check whether a future is realized or not +with clojure.core/realized?:

(def ft (future (reduce + (range 0 10000))))
+;; โ‡’ #'user/ft
+(realized? ft)
+;; โ‡’ true
+@ft
+;; โ‡’ 49995000
+

Clojure futures are evaluated in an unbounded, cached thread pool that is also used by agents +(updated via clojure.core/send-off). This works well in many cases but may result in +exhaustion of the heap or thrashing if too many futures are created.

Finally, Clojure futures implement java.util.concurrent.Future and can be used with Java APIs +that accept them.

Promises

Promises are yet another take on asynchronously realized values. They are similar to futures in +certain ways:

  • Can be dereferenced with a timeout
  • Caches the realized value
  • Supported by clojure.core/realized?

However, promises are realized not by evaluating a piece of code but by calling clojure.core/deliver +on a promise along with a value:

;; promises have no code body (no code to evaluate)
+(def p (promise))
+;; โ‡’ #'user/p
+p
+;; โ‡’ #<core$promise$reify__6153@306a0a21: :pending>
+(realized? p)
+;; โ‡’ false
+
+;; delivering a promise makes it realized
+(deliver p {:result 42})
+;; โ‡’ #<core$promise$reify__6153@306a0a21: {:result 42}>
+(realized? p)
+;; โ‡’ true
+@p
+;; โ‡’ {:result 42}
+

Promises combine many of the benefits of callback-oriented asynchronous programming +and the simpler blocking function calls model provided by dereferencing.

Watches and Validators

TBD

Using Intrinsic Locks ("synchronized") in Clojure

Explicit Locking

Every object on the JVM has an intrinsic lock (also referred to as monitor lock +or simply monitor). By convention, a thread that needs to modify a field of a +mutable object has to acquire the object's intrinsic lock and then release it. +As long as a thread owns an intrinsic lock, no other thread can acquire the same lock.

In Clojure, explicit synchronization like this is rarely necessary but may be +needed for interoperability with Java code. When you need to execute a piece +of code while holding an intrinsic lock of a mutable object, use +the clojure.core/locking macro:

(let [l (java.util.ArrayList.)]
+  (locking l
+    (.add l 10))
+  l)
+;; โ‡’ #<ArrayList [10]>
+

Note that for immutable Clojure data structures, explicit locking is effectively +not necessary.

Synchronization on Clojure Record Fields

TBD

Reducers (Clojure 1.5+)

TBD

java.util.concurrent

Overview

java.util.concurrent (sometimes abbreviated as j.u.c.) is a group of +concurrency utilities in the JDK. Originally introduced in JDK 5 in 2004, +they are developed and maintained by some of the experts in concurrency. +j.u.c. is a mature library that has been heavily battle tested for +almost a decade.

While Clojure provides a whole toolbelt of concurrency features of its own, +in certain cases the best solution is to use an existing j.u.c. class +or even build a new abstraction on top of j.u.c. building blocks.

j.u.c. consists of multiple parts that cover common concurrent programming +patterns and use cases: from thread pools (a.k.a. executors) to synchronization +classes, to atomic variables, to concurrent collections, to the Fork/Join +framework.

Executors (Thread Pools)

Overview

The Executor interface standardizes invocation, scheduling, execution, and control of asynchronous tasks. +Those tasks can be executed in the calling thread, in newly created threads, or (mostly typically) +in a thread pool. Thread pools also can have different implementations: for example, +be fixed size or growing dynamically, using different error handling strategies and so on.

Executors are most often instantiated using static methods of the java.util.concurrent.Executors class. To submit an operation to the pool, use the ExecutorService#submit method.

(import '[java.util.concurrent Executors ExecutorService Callable])
+
+(let [^ExecutorService pool (Executors/newFixedThreadPool 16)
+      ^Callable clbl        (cast Callable (fn []
+                                             (reduce + (range 0 10000))))]
+  (.submit pool clbl))
+;; โ‡’ #<FutureTask java.util.concurrent.FutureTask@19ca276f>
+

In the example above, we create a new fixed size thread pool with 16 threads +and submit a Clojure function for execution. Clojure functions implement Runnable and Callable +interfaces and can be submitted for execution, however, because ExecutorService#submit +is an overloaded method, to avoid reflection warnings, we cast the function +to java.util.concurrent.Callable.

java.util.concurrent.Future

Executor#submit will return an instance of java.util.concurrent.Future. It is much like Clojure +futures but cannot be dereferenced. To get the result, use the j.u.c.Future#get method:

(import '[java.util.concurrent Executors ExecutorService Callable])
+
+(let [^ExecutorService pool (Executors/newFixedThreadPool 16)
+      ^Callable clbl        (cast Callable (fn []
+                                             (reduce + (range 0 10000))))
+      task                  (.submit pool clbl)]
+  (.get task))
+;; โ‡’ 49995000
+

Scheduled Executors

TBD

Countdown Latches

Countdown latch is a thread synchronization data structure. More specifically, it handles +on group of concurrent workflows: "block the current thread until N other threads are +done with their work". For example, "make a POST request to N URLs and continue when all N operations +succeeded or failed".

Countdown latches are instances of java.util.concurrent.CountDownLatch and instantiated with +a positive integer:

(import java.util.concurrent.CountDownLatch)
+
+(CountDownLatch. n)
+

When the CountDownLatch#await method is executed, the calling thread blocks until the counter +gets to 0. Invoking the CountDownLatch#countDown method decreases the counter by 1. Count down +operations, of course, are supposed to be performed in other threads.

An example to demonstrate:

(let [cnt   (atom [])
+      n     5
+      latch (java.util.concurrent.CountDownLatch. n)]
+  (doseq [i (range 0 n)]
+    (.start (Thread. (fn []
+                       (swap! cnt conj i)
+                       (.countDown latch)))))
+  (.await latch)
+  @cnt)
+;; note the ordering: starting N threads in parallel leads to
+;; non-deterministic thread interleaving
+;; โ‡’ [0 1 2 4 3]
+

In the example above, we start multiple threads and block the current thread until all other +threads are done. In this example, those other threads simply add an integer to a vector +stored in an atom. More realistic scenarios will contact external services, the file system, +perform some computation and so on.

Because when threads are executed concurrently (or in parallel), the order of their execution is not +guaranteed, we see 4 being added to the vector before 3 in the result.

Countdown latches are commonly used with initial value of 1 to "block and wait until this operation in +a different thread is done".

Concurrent Collections

Most of the Java collections are mutable and were not designed for concurrency. java.util.concurrent includes a number of collections that +are thread safe and can be used for passing data structures between threads.

Atomic Variables

The java.util.concurrent.atomic package provides +a number of data structures that support lock-free thread-safe programming on a single variable (identity). They support +conditional atomic update operation (compared-and-swap aka CAS).

Some of the more popular atomic types in the j.u.c.atomic package are AtomicBoolean, +AtomicLong and AtomicReference.

Atomic references are pretty well covered in Clojure with atoms but ocassionally may be used by +other libraries. An example to demonstrate how to use an atomic long for a thread-safe counter:

(let [l (AtomicLong.)]
+  (dotimes [i 50]
+    (.start (Thread. (fn []
+                       (.incrementAndGet l)))))
+  (.get l))
+;; โ‡’ 49
+

Fork/Join Framework

TBD

Other Approaches to Concurrency

There are also other approaches to concurrency that neither Clojure nor Java cover. The growing +adoption of message passing concurrency (the Actor model and CSP) +lead to the creation of several JVM-based frameworks for message passing. Some of the most popular ones +include:

Akka's Java API can be used from Clojure either directly or via a library called Okku.

In LMAX Disruptor, event instances passed around are assumed to be mutable, so the framework is of limited use with Clojure.

Runtime Parallelism

Clojure was designed to be a hosted language. Its primary target, the +JVM, provides runtime parallelism support. JVM threads map 1:1 to +kernel threads. Those will be executed in parallel given that enough +cores are available for OS scheduler to use.

In Clojure, many concurrency features are built on top of JVM threads +and thus benefit from runtime parallelism if the program is running on +a multi-core machine.

Books

Concurrency is a broad topic and it would be silly to think that we +can cover it well in just one guide. To get a better understanding of +the subject, one can refer to a few excellent books:

Wrapping Up

One of Clojure design goals was to make concurrent programming easier.

The key design decision was making Clojure data structures immutable +(persistent) and separating the concepts of identity (references) +and value. Immutable values eliminate many concurrency hazards, and +ultimately make it easier for developers to reason about their +programs.

Atoms are arguably the most commonly used reference type when working +with concurrency (vars are used much more often but not for their +concurrency semantics). Software Transactional Memory is a more +specialized feature and has certain limitations (e.g., I/O operations +must not be performed inside transactions). Finally, agents, futures, +and promises provide an array of tools for working with asynchronous +operations.

Concurrency is a hard fundamental problem. There is no single "best" +solution or approach to it. On the JVM, Clojure offers several +concurrency-related features of its own but also provides easy access +to the java.util.concurrent primitives and libraries such as +Akka or +Jetlang.

Contributors

Michael Klishin michael@defprotocol.org, 2012 (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/core_overview/index.html b/clones/clojure-doc.org/articles/language/core_overview/index.html new file mode 100644 index 00000000..70e7fa6d --- /dev/null +++ b/clones/clojure-doc.org/articles/language/core_overview/index.html @@ -0,0 +1,745 @@ + + + + + Clojure Guides: Overview of clojure.core, the standard Clojure library + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • Key functions of clojure.core
  • Key macros of clojure.core
  • Key vars of clojure.core
  • Essential special forms

This guide is by no means comprehensive and does not try to explain each function/macro/form in depth. It is an overview, +the goal is to briefly explain the purpose of each item and provide links to other articles with more information.

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Binding

let

(let [bindings*] exprs*)
+

let takes a vector of symbol value pairs followed by a variable number of expressions.

let allows binding of locals (roughly equivalent to variables in many other languages) and defines an explicit scope for those bindings.

The body of a let statement also provides an implicit do that allows for multiple statements in the body of let.

A basic example:

(let [x 1 y 2]
+  (println x y))
+

Let can be nested, and the scope is lexically determined. This means that a binding's value is determined by the nearest binding form for that symbol.

This example basically demonstrates the lexical scoping of the let form.

(let [x 1]
+  (println x) ; prints 1
+  (let [x 2]
+    (println x))) ; prints 2
+

Let bindings are immutable and can be destructured.

See: Sections about destructuring in +Introduction and +Functions +pages.

def

(def symbol doc-string? init?)
+

def takes a symbol and an optional init value.

If an init value is supplied, the root binding of the var is assigned to that value. Redefining a var with an init value will re-assign the root binding.

A root binding is a value that is shared across all threads.

The let form is the preferred method of creating local bindings. It is strongly suggested to prefer it where possible, and never use def within another form.

;; TBD - reference to var documentation, basic example
+;; TBD - metadata
+

declare

([& names])
+

declare takes a variable number of symbols.

declare provides a simple way of creating 'forward declarations'. declare defs the supplied symbols with no init values. This allows for referencing of a var before it has been supplied a value.

There are much better methods of value-based dispatch or code architecture in general, but this presents a simple situation forward declarations would be necessary.

(declare func<10 func<20)
+
+;; without declare you will receive an error similar to:
+;; "Unable to resolve symbol: func10 in this context"
+
+(defn func<10 [x]
+  (cond
+   (< x 10) (func<10 (inc x))
+   (< x 20) (func<20 x)
+   :else "too far!"))
+
+(defn func<20 [x]
+  (cond
+   (< x 10) (func<10 x)
+   (< x 20) "More than 10, less than 20"
+   :else "too far!"))
+

No matter which order you put func<10 and func<20 in, there will be a reference to a var that does not yet exist when the compiler does the initial evaluation of top-level forms.

declare defines the var with no binding so that the the var exists when it is referenced later in the code.

defn

([name doc-string? attr-map? [params*] prepost-map? body] [name doc-string? attr-map? ([params*] prepost-map? body) + attr-map?])
+

defn takes a symbol, an optional doc string, an optional meta-data +map, a vector of arguments and a variable number of expressions.

defn is the primary way of defining functions. It allows for +convenient definition of metadata about its argslist and documentation +(docstrings). defn inherently allows for quick documentation of +functions that can be retrieved with doc. This feature should be +used almost universally.

Without defn, a var would be directly bound to a function definition +and explicit metadata about the doc string and argslits would be added +manually.

(def func (fn [x] x))
+
+;; same as:
+(defn func [x]
+  x)
+
+;; with metadata added by defn
+(def ^{:doc "documentation!"} ^{:arglists '([x])} func (fn [x] x))
+
+;;same as
+(defn func
+  "documentation!"
+  [x]
+  x)
+
;; TBD - link to doc and metadata
+

Branching

if

(if test then else?)
+

if takes 2 expressions, and an optional third.

if is the primary method of conditional execution and other conditionals are built upon if.

If the return value of the first expression is anything except nil or false, the second expression is evaluated and the result returned..

If a third expression is provided, when the first expression returns nil or false the third expression is evaluated and returned.

(if 0 "second") ; 0 is a 'true' value. Only false or nil are 'false'
+
(if nil "second" "third")
+
(if (< 10 9) "second" "third") ; (< 9 10) returns false
+
(if (seq '()) "second") ; seq returns nil for an empty sequence
+
(if (nil? (= 1 2)) "second" "third") ; differentiate between nil and false if needed
+

when

([test & body])
+

when takes 2 expressions.

when provides an implicit do form that is evaluated if an expression returns true, otherwise nil is returned. when does not provide an 'else'.

(when (= 1 2) (print "hey") 10)
+
(when (< 10 11) (print "hey") 10)
+

for

See: for

doseq

See: doseq

Looping

recur

(recur exprs*)
+

recur allows for self-recursion without consuming stack space proportional to the number of recursive calls made. Due to the lack of tail-call optimization on the JVM currently, this is the only method of recursion that does not consume excess stack space.

recur takes a number of arguments identical to the point of recursion. recur will evaluate those arguments, rebind them at the point of recursion and resume execution at that point.

The point of recursion is the nearest fn or loop form determined lexically.

recur must be in the tail position of the recursion point expression. The tail position is the point in the expression where a return value would otherwise be determined and.

recur does not bind & in variadic functions and in these situations an empty seq must be passed by recur.

(defn count-up
+  [result x y]
+  (if (= x y)
+    result
+    (recur (conj result x) (inc x) y)))
+
+(count-up [] 0 10)
+

Example: getting factorial of a positive integer:

(defn factorial
+  ([n]
+     (factorial n 1))
+  ([n acc]
+     (if (zero? n)
+       acc
+       (recur (dec n) (* n acc)))))
+
+(factorial 10)
+;; โ‡’ 3628800
+

TBD: more examples

loop

(loop [bindings*] exprs*)
+

loop takes a vector of symbol value pairs followed by a variable number of expressions.

loop establishes a recursion point for a recur expression inside its body. loop provides an implicit let for bindings.

The implicit let that loop provides binds each symbol to the init-expression. recur then binds new values when returning the execution point to loop.

(defn count-up
+  [start total]
+  (loop [result []
+         x start
+         y total]
+    (if (= x y)
+      result
+      (recur (conj result x) (inc x) y))))
+
+(count-up 0 10)
+;; โ‡’ [0 1 2 3 4 5 6 7 8 9]
+

Example: getting factorial of a positive integer:

(defn factorial
+  [n]
+  (loop [n n
+         acc 1]
+    (if (zero? n)
+      acc
+      (recur (dec n) (* acc n)))))
+
+(factorial 10)
+;; โ‡’ 3628800
+

TBD: more examples

trampoline

([f])
+([f & args])
+

trampoline takes a function and a variable number of arguments to pass to that function.

trampoline allows for mutual recursion without consuming stack space proportional to the number of recursive calls made.

If the return value of that function is a function, trampoline calls that function with no arguments. If the return value is not a function, trampoline simply returns that value.

Since trampoline calls the returned functions with no arguments, you must supply an anonymous function that takes no arguments and calls the function you wish to recur to. This is usually done with anonymous function literals #()

(declare count-up1 count-up2) ;; see `declare` for why this is needed
+
+(defn count-up1
+  [result start total]
+  (if (= start total)
+    result
+    #(count-up2 (conj result start) (inc start) total))) ;; returns an anonymous function
+
+(defn count-up2 [result start total]
+  (if (= start total)
+    result
+    #(count-up1 (conj result start) (inc start) total))) ;; returns an anonymous function
+
+    #_(trampoline count-up1 [] 0 10)
+;; โ‡’ [0 1 2 3 4 5 6 7 8 9]
+

TBD: a trivial example that would not be easily solved with self-recursion

for

([seq-exprs body-expr])
+

for takes a vector of pairs of [binding collection].

for allows for list comprehensions. for assigns each sequential value in the collection to the binding form and evaluates them rightmost first. The results are returned in a lazy sequence.

for allows for explicit let, when and while through use of ":let []" ":when (expression)" ":while (expression)" in the binding vector.

(for [x [1 2 3] y [4 5 6]]
+  [x y])
+;; โ‡’ ([1 4] [1 5] [1 6] [2 4] [2 5] [2 6] [3 4] [3 5] [3 6])
+

:when only evaluates the body when a true value is returned by the expression provided

(for [x [1 2 3] y [4 5 6]
+      :when (and
+             (even? x)
+             (odd? y))]
+  [x y])
+;; โ‡’ ([2 5])
+

:while evaluates the body until a non-true value is reached. Note that the rightmost collection is fully bound to y before a non-true value of (< x 2) is reached. This demonstrates the order of the comprehension.

(for [x [1 2 3] y [4 5 6]
+      :while (< x 2)]
+  [x y])
+;; โ‡’ ([1 4] [1 5] [1 6])
+

doseq

([seq-exprs & body])
+

doseq takes a vector of pairs of [binding collection].

doseq is similar to for except it does not return a sequence of results. doseq is generally intended for execution of side-effects in the body, and thusly returns nil.

doseq supports the same bindings as for - :let :when :while. For examples of these, see for.

(doseq [x [1 2 3] y [4 5 6]]
+  (println [x y]))
+
+;; [1 4][1 5][1 6][2 4][2 5][2 6][3 4][3 5][3 6]
+;; โ‡’ nil
+

iterate

([f x])
+

iterate takes a function and an argument to the function.

A lazy sequence is returned consisting of the argument then each subsequent entry is the function evaluated with the previous entry in the lazy sequence.

TBD: Examples
+

TBD: Simple image accompaniment.

reduce

([f coll])
+([f val coll])
+

reduce takes a function, an optional initial value and a collection.

reduce takes the first item of the collection and either the second +item of the collection or the provided initial value, then evaluates +the function with those arguments. The function is then evaluated with +that result and the next item in the collection. This is repeated +until the collection is exhausted and the value of the final function +call is returned.

TBD: examples
+

TBD: Simple image accompaniment.

reductions

([f coll])
+([f val coll])
+

reductions takes a function, an optional initial value and a collection.

reductions returns a lazy sequence consisting of the first item in +the collection, or the provided initial value followed by the result +of the function evaluated with the previous result and the next item +in the collection.

TBD: examples
+

TBD: Simple image accompaniment.

map

([f coll])
+([f c1 c2])
+([f c1 c2 c3])
+([f c1 c2 c3 & colls])
+

map takes a function and one or more collections. map passes an +item from each collection, in order, to the function and returns a +lazy sequence of the results.

The function provided to map must support an arity matching the +number of collections passed. Due to this, when using more than one +collection, map stops processing items when any collection runs out of +items.

TBD: Examples
+

TBD: Simple image accompaniment.

Collection and Sequence Modification

conj

([coll x])
+([coll x & xs])
+

conj takes a collection and a variable number of arguments.

conj is short for "conjoin". As the name implies, conj returns the +collection with those arguments added.

Adding items to a collection occurs at different places depending on +the concrete type of collection.

List addition occurs at the beginning of the list. This is because +accessing the head of the list is a constant time operation, and +accessing the tail requires traversal of the entire list.

(conj '(1 2) 3)
+;; โ‡’ (3 1 2)
+

Vectors have constant time access across the entire data +structure. `'conj' thusly appends to the end of a vector.

(conj [1 2] 3)
+;; โ‡’ [1 2 3]
+

Maps do not have guaranteed ordering, so the location that items are +added is irrelevant. conj requires vectors of [key value] pairs to +be added to the map.

(conj {:a 1 :b 2 :c 3} [:d 4])
+;; โ‡’ {:d 4, :a 1, :c 3, :b 2}
+
(conj {:cats 1 :dogs 2} [:ants 400] [:giraffes 13])
+;; โ‡’ {:giraffes 13, :ants 400, :cats 1, :dogs 2}
+

Sets also do not have guaranteed ordering. conj returns a set with +the item added. As the concept of sets implies, added items will not +duplicate equivalent items if they are present in the set.

(conj #{1 4} 5)
+;; โ‡’ #{1 4 5}
+
(conj #{:a :b :c} :b :c :d :e)
+;; โ‡’ #{:a :c :b :d :e}
+

empty

([coll])
+

empty takes a collection

empty returns an empty collection of the same type as the collection +provided.

(empty [1 2 3])
+;; โ‡’ []
+
(empty {:a 1 :b 2 :c 3})
+;; โ‡’ {}
+

assoc

([map key val])
+([map key val & kvs])
+

assoc takes a key and a value and returns a collection of the same +type as the supplied collection with the key mapped to the new value.

assoc is similar to get in how it works with maps, records or +vectors. When applied to a map or record, the same type is returned +with the key/value pairs added or modified. When applied to a vector, +a vector is returned with the key acting as an index and the index +being replaced by the value.

Since maps and records can not contain multiple equivalent keys, +supplying assoc with a key/value that exists in the one will cause +assoc to return modify the key at that value in the result and not +duplicate the key.

(assoc {:a 1} :b 2)
+;; โ‡’ {:b 2, :a 1}
+
(assoc {:a 1 :b 45 :c 3} :b 2)
+;; โ‡’ {:a 1, :c 3, :b 2}
+
(defrecord Hand [index middle ring pinky thumb])
+(assoc (Hand. 3 4 3.5 2 2) :index 3.75)
+;; โ‡’ #user.Hand{:index 3.75, :middle 4, :ring 3.5, :pinky 2, :thumb 2}
+

When using assoc with a vector, the key is +the index and the value is the value to assign to that index in the +returned vector. The key must be <= (count vector) or a +"IndexOutOfBoundsException" will occur. assoc can not be used to add +an item to a vector.

(assoc [1 2 76] 2 3) ;= [1 2 3]
+
;; index 5 does not exist. valid indexes for this vector are: 0, 1, 2
+(assoc [1 2 3] 5 6) 
+;; IndexOutOfBoundsException   clojure.lang.PersistentVector.assocN (PersistentVector.java:136)
+

dissoc

([map])
+([map key])
+([map key & ks])
+

dissoc takes a map and a variable number of keys.

dissoc returns a map with the supplied keys, and subsequently their +values, removed. Unlike assoc, dissoc does not work on +vectors. When a record is provided, dissoc returns a map. For +similar functionality with vectors, see subvec and concat.

(dissoc {:a 1 :b 2 :c 3} :b)
+;; โ‡’ {:a 1, :c 3}
+
(dissoc {:a 1 :b 14 :c 390 :d 75 :e 2 :f 51} :b :c :e)
+;; โ‡’ {:a 1, :f 51, :d 75}
+
;; note that a map is returned, not a record.
+(defrecord Hand [index middle ring pinky thumb])
+;; always be careful with the bandsaw!
+(dissoc (Hand. 3 4 3.5 2 2) :ring)
+;; โ‡’ {:index 3, :middle 4, :pinky 2, :thumb 2}
+

Information about a Collection or Sequence

count

([coll])
+

count takes a collection.

Returns a count of the number of items in a collection. An argument of nil returns 0.

(count "Hello")
+;; โ‡’ 5
+
(count [1 2 3 4 5 6 7])
+;; โ‡’ 7
+
(count nil)
+;; โ‡’ 0
+

Note that count does not return in constant time for all +collections. This can be determined with counted?. Keep in mind +that lazy sequences must be realized to get a count of the items. This +is often not intended and can cause a variety of otherwise cryptic +errors.

(counted? "Hello")
+;; โ‡’ false
+
;; will be fully realized when using (count (range 10))
+(counted? (range 10))
+;; โ‡’ false
+
;; Constant time return of (count)
+(counted? [1 2 3 4 5])
+;; โ‡’ true
+

empty?

([coll])
+

empty takes a collection.

empty? returns true if the collection has no items, or false if it has 1 or more items.

(empty? [])
+;; โ‡’ true
+
(empty? '(1 2 3))
+;; โ‡’ false
+

Do not confuse empty? with empty. This can be a source of great confusion:

(if (empty [1 2 3]) ;; empty returns an empty seq, which is true! use empty? here.
+  "It's empty"
+  "It's not empty")
+;; โ‡’ "It's empty"
+

not-empty

([coll])
+

not-empty takes a collection.

not-empty returns nil if the collection has no items. If the collection contains items, the collection is returned.

(not-empty '(:mice :elephants :children))
+;; โ‡’ (:mice :elephants :children)
+
(not-empty '())
+;; โ‡’ nil
+

Items in a Collection or Sequence

first

([coll])
+

first takes a collection.

first returns the first item in the collection. first returns nil +if the argument is empty or is nil.

Note that for collections that do not guarantee order like some maps +and sets, the behaviour of first should not be relied on.

(first (range 10))
+;; โ‡’ 0
+
(first [:floor :piano :seagull])
+;; โ‡’ :floor
+
(first [])
+;; โ‡’ nil
+

rest

([coll])
+

rest takes a collection.

rest returns a seq of items starting with the second element in the +collection. rest returns an empty seq if the collection only +contains a single item.

rest should also not be relied on when using maps and sets unless +you are sure ordering is guaranteed.

(rest [13 1 16 -4])
+;; โ‡’ (1 16 -4)
+
(rest '(:french-fry))
+;; โ‡’ '()
+

The behaviour of rest should be contrasted with next. next +returns nil if the collection only has a single item. This is +important when considering "truthiness" of values since an empty seq +is "true" but nil is not.

(if (rest '("stuff"))
+  (print "Does this print?")) ;; yes, it prints.
+
;; NEVER FINISHES EXECUTION!
+;; "done" is never reached because (rest x) is always a "true" value
+(defn inf
+  [x]
+  (if (rest x)
+    (inf (rest x))
+    "done"))
+

get

([map key])
+([map key not-found])
+

get takes an associative collection, a sequence of keys and an optional default value.

get returns the value for the specified key in a map or record, +index of a vector or value in a set. If the key is not present, get +returns nil or a supplied default value.

;; val of a key in a map
+(get {:a 1 :b 2 :c 3} :b)
+;; โ‡’ 2
+
;; index of a vector
+(get [10 15 20 25] 2)
+;; โ‡’ 20
+
;; in a set, returns the value itself if present
+(get #{1 10 100 2 20 200} 1)
+;; โ‡’ 1
+
;; returns nil if key is not present
+(get {:a 1 :b 2} :c)
+;; โ‡’ nil
+
;; vector does not have an _index_ of 4. nil is returned
+(get [1 2 3 4] 4)
+;; โ‡’ nil
+
(defrecord Hand [index middle ring pinky thumb])
+(get (Hand. 3 4 3.5 2 2) :index)
+;; โ‡’ 3
+

get also supports a default return value supplied as the last argument.

;; index 4 does not exist. return default value
+(get [1 2 3 4] 4 "Not Found")
+;; โ‡’ "Not Found"
+
;; key :c does not exist, so return default value of 3
+(get {:a 1 :b 2} :c 3)
+;; โ‡’ 3
+

contains?

([coll key])
+

contains? takes a map and a key.

contains returns true if the provided key is present in a +collection. contains is similar to get in that vectors treat the +key as an index. contains will always return false for lists.

(contains? {:a 1 :b 2 :c 3} :c)
+;; โ‡’ true
+
;; true if index 2 exists
+(contains? ["John" "Mary" "Paul"] 2)
+;; โ‡’ true
+
;; false if index 5 does not exist
+(contains? ["John" "Mary" "Paul"] 5)
+;; โ‡’ false
+
;; "Paul" does not exist as an index
+(contains? ["John" "Mary" "Paul"] "Paul")
+;; โ‡’ false
+
;; lists are not supported. contains? won't traverse a collection for a result.
+(contains? '(1 2 3) 0)
+;; โ‡’ java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.PersistentList
+

keys

([map])
+

keys takes a map or record.

keys returns a sequence of the keys in a map or record.

(keys {1 "one" 2 "two" 3 "three"})
+;; โ‡’ (1 2 3)
+
(defrecord Hand [index middle ring pinky thumb])
+(keys (Hand. 2 4 3 1 2))
+;; โ‡’ (:index :middle :ring :pinky :thumb)
+

vals

([map])
+

vals takes a map or record.

vals returns a sequence of vals in a map or record.

(vals {:meows 20 :barks 2 :moos 5})
+;; โ‡’ (5 2 20)
+
(defrecord Hand [index middle ring pinky thumb])
+(vals (Hand. 1 2 3 4 5))
+;; โ‡’ (1 2 3 4 5)
+

take

([n coll])
+

take takes a number and a collection.

take returns a lazy sequence starting with the first value of the +collection and n sequential items after that.

If the number of items in the collection is less than the provided +number, the entire collection is returned lazily.

TBD: example
+

drop

([n coll])
+

drop takes a number and a collection.

drop returns a lazy sequence starting at the nth item of the collection.

TBD: example
+

take-while

([pred coll])
+

take-while takes a function that accepts a single-argument and a +collection.

take-while returns a lazy sequence of sequential items until the +function returns nil/false value for that item.

TBD: example
+

drop-while

([pred coll])
+

'drop-while` takes a function that accepts a single-argument and a +collection.

drop-while returns a lazy sequence starting at the first item in the +collection that the function returns nil/false.

filter

([pred coll])
+

filter takes a function that accepts a single argument and a +collection.

filters returns a lazy sequence of items that return true for the +provided predicate. Contrast to remove.

(filter even? (range 10))
+;; โ‡’ (0 2 4 6 8)
+
(filter #(if (< (count %) 5) %) ["Paul" "Celery" "Computer" "Rudd" "Tayne"])
+;; โ‡’ ("Paul" "Rudd")
+

When using sets with filter, remember that if nil or false is in the +set and in the collection, then the predicate will return itself: +nil.

In this example, when nil and false are tested with the predicate, the +predicate returns nil. This is because if the item is present in the +set it is returned. This will cause that item to /not/ be included in +the returned lazy-sequence.

(filter #{:nothing :something nil} [:nothing :something :things :someone nil false :pigeons])
+;; โ‡’ (:nothing :something)
+

keep

(keep f coll)

keep takes a function that accepts a single argument and a +collection.

keep returns a lazy sequence of non-nil results of the function +applied to each item in the collection in sequence.

TBD: examples
+

remove

([pred coll])
+

remove takes a function that accepts a single argument and a +collection.

remove returns a lazy sequence of items that return false or nil +for the provided predicate. Contrast to filter.

(remove even? (range 10))
+;; โ‡’ (1 3 5 7 9)
+
;; relative complement. probably useless?
+(remove {:a 1 :b 2} [:h :k :z :b :s])
+;; โ‡’ (:h :k :z :s)
+

When using sets with remove, remember that if nil or false is in the +set and in the collection, then the predicate will return itself: +nil. This will cause that item to be included in the returned lazy +sequence.

In this example, when nil and false are tested with the predicate, the +predicate returns nil. This is because if the item is present in the +set it is returned.

(remove #{:nothing :something nil} [:nothing :something :things :someone nil false :pigeons])
+;; โ‡’ (:things :someone nil false :pigeons)
+

some

([pred coll])
+

some takes a function that accepts a single argument and a collection.

some will apply a predicate to each value in a collection until a +non-false/nil result is returned then immediately return that result.

Since collections are "true" values, this makes it possible to return +the first result itself rather than simply true.

(some even? [1 2 3 4 5])
+;; โ‡’ true
+
;; predicate returns the value rather than simply true
+(some #(if (even? %) %) [1 2 3 4 5])
+;; โ‡’ 2
+

Since maps can be used as functions, you can use a map as a +predicate. This will return the value of the first key in the +collection that is also in the map.

(some {:a 1 :b 5} [:h :k :d :b])
+;; โ‡’ 5
+

Sets can also be used as functions and will return the first item in +the collection that is present in the set.

(some #{4} (range 20))
+;; โ‡’ 4
+

every?

([pred coll])
+

every takes a function that accepts a single argument and a collection.

every returns true if the predicate returns true for every item in +the collection, otherwise it returns false.

(every? even? (range 0 10 2))
+;; โ‡’ true
+
;; set can be used to see if collection only contains items in the set.
+(every? #{2 3 4} [2 3 4 2 3 4])
+;; โ‡’ true
+

Processing Collections and Sequences

partition

([n coll])
+([n step coll])
+([n step pad coll])
+

partition takes a number, an optional step, an optional padding +collection and a collection. If the padding collection is provided, a +step must be provided.

partition sequentially takes a provided number of items from the +collection in sequence and puts them into lists. This lazy sequence of +lists is returned.

If a step is provided, the lists in the returned lazy sequence start +at offsets in the provided collection of that number items in the +list.

If a padding collection is provided, the last item in the returned +lazy sequence will be padded with the padding collection to achieve +the desired partitioning size.

If there is no padding collection provided and there is not enough +items to fill the last list in the returned lazy sequence, those items +will be not used.

TBD: example
+

partition-all

([n coll])
+([n step coll])
+

partition-all takes a number, an optional step and a collection.

partition-all sequentially takes a provided number of items from the +collection in sequence and puts them into lists. This lazy sequence of +lists is returned.

If a step is provided, the lists in the returned lazy sequence start +at offsets in the provided collection of that number items in the +list.

If there are not enough items to fill the last list in the returned +lazy sequence, the remaining items will be used in the last list.

TBD: example
+

filter

See: filter

remove

See: remove

for

See: for

map

See: map

remove

See: remove

empty?

See: empty

not-empty

See: not-empty

Function Composition and Application

juxt

([])
+([f])
+([f g])
+([f g h])
+([f1 f2 f3 & fs])
+

juxt takes a variable number of functions.

juxt returns a function that will return a vector consisting of the +result of each of those functions to a provided argument.

TBD: examples
+

TBD: Simple image accompaniment.

comp

([])
+([f])
+([f g])
+([f g h])
+([f1 f2 f3 & fs])
+

comp takes a variable number of functions.

comp returns a function that will return the result of applying the +rightmost function to the provided argument, then the second rightmost +function to the result of that etc.

TBD: examples
+

TBD: Simple image accompaniment.

fnil

([f x])
+([f x y])
+([f x y z])
+

fnil takes a function and one to three arguments.

fnil returns a function that replaces any nil arguments with the +provided values. fnil only supports supports patching 3 arguments, +but will pass any arguments beyond that un-patched.

(defn say-info [name location hobby]
+  (println name "is from" location "and enjoys" hobby))
+
+(def say-info-patched (fnil say-info "Someone" "an unknown location" "Clojure"))
+
+(say-info-patched nil nil nil)
+;; โ‡’ Someone is from an unknown location and enjoys Clojure
+
(say-info-patched "Robert" nil "giraffe migrations")
+;; โ‡’ Robert is from an unknown location and enjoys giraffe migrations
+

apply

([f args] [f x args] [f x y args] [f x y z args] [f a b c d & args])
+

apply takes a variable number of arguments and a collection.

apply effectively unrolls the supplied args and a collection into a +list of arguments to the supplied function.

(str ["Hel" "lo"])
+;; โ‡’ "[\"Hel\" \"lo\"]" ;; not what we want, str is operating on the vector
+
(apply str ["Hel" "lo"]) ;; same as (str "Hel" "lo")
+;; โ‡’ "Hello"
+

apply prepends any supplied arguments to the form as well.

(map + [[1 2 3] [1 2 3]]) ;; This attempts to add 2 vectors with +
+;; ClassCastException   java.lang.Class.cast (Class.java:2990)
+
(apply map + [[1 2 3] [1 2 3]]) ;; same as (map + [1 2 3] [1 2 3])
+;; โ‡’ (2 4 6)
+
(apply + 1 2 3 [4 5 6]) ;; same as  (+ 1 2 3 4 5 6)
+;; โ‡’ 21
+

Note that apply can not be used with macros.

->

([x])
+([x form])
+([x form & more])
+

-> takes a value and optionally one or more expressions.

-> takes the first argument and inserts it as the second item in the +next form, or creates a list with the first argument as the second +item. The return value of that expression is inserted as the second +item in the next form, making a list if necessary. This continues +until all expressions are evaluated and the final value is returned.

TBD: example
+

TBD: Simple image accompaniment.

->>

([x])
+([x form])
+([x form & more])
+

->> takes a value and optionally one or more expressions.

->> takes the first argument and inserts it as the last item in the +next form, or creates a list with the first argument as the last +item. The return value of that expression is inserted as the last item +in the next form, making a list if necessary. This continues until +all expressions are evaluated and the final value is returned.

TBD: Simple image accompaniment.

Associative Collections

get-in

([m ks] [m ks not-found])
+

get-in takes an associative collection, a sequence of keys and an optional default value.

get-in takes the first value in the sequence of keys and retrieves +the value, then applies each subsequent key to to the most recently +returned value and returns the final result. If any key is not present +when evaluated then either nil, or a provided default value is +returned.

(get-in {:profile {:personal {:age 28}}} [:profile :personal :age])
+;= 28
+

TBD: Simple image accompaniment.

update-in

([m [k & ks] f & args])
+

update-in takes an associative collection, a sequence of keys, a +function and optional arguments to supply to that function.

update-in takes the first value in the sequence of keys and +retrieves the value, then applies each subsequent key to to the most +recently returned value. The function and optional arguments are +applied to the value and a new nested collection is returned with the +key having the result of that function.

update-in will create new hash-maps if a key in the sequence of keys +does not exist. The returned collection will have a nested structure +correlating to the provided sequence along with the result of the +function and optional arguments as the value of the final key.

(update-in {:profile {:personal {:age 28}}} [:profile :personal :age] inc)
+;= {:profile {:personal {:age 29}}}
+

TBD: Simple image accompaniment.

assoc-in

([m [k & ks] v])
+

assoc-in takes an associative collection, a sequence of keys and a value.

assoc-in takes the first value in the sequence of keys and retrieves +the value, then applies each subsequent key to to the most recently +returned value. The final key is assigned the provided value and a new +nested collection is returned.

update-in will create new hash-maps if a key in the sequence of keys +does not exist. The returned collection will have a nested structure +correlating to the provided sequence along with the provided value as +the value of the final key.

(assoc-in {:profile {:personal {:age 28}}} [:profile :personal :location] "Vancouver, BC")
+;= {:profile {:personal {:location "Vancouver, BC", :age 28}}}
+

TBD: Simple image accompaniment.

select-keys

([map keyseq])
+

select-keys takes an associative collection and a sequence of keys.

select-keys returns a map containing only the entries that have a +key which is also present in the sequence of keys.

(select-keys {:a 1 :b 2 :c 3} [:a :b])
+;= {:b 2, :a 1}
+

keys

See: keys

vals

See: vals

get

See: get

assoc

See: assoc

dissoc

See: dissoc

Namespace Functions

ns, require, use, import, refer

Please see the Namespace guide

Reference Types

ref, atom, var, agent

Please see the Concurrency and Parallelism Guide

deref, swap!, reset!, dosync, alter, commute, binding

Please see the Concurrency and Parallelism Guide

Contributors

Robert Randolph audiolabs@gmail.com (original author) +Michael Klishin michael@defprotocol.org +Nguyแป…n Hร  Dฦฐฦกng cmpitg@gmail.com

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/functions/index.html b/clones/clojure-doc.org/articles/language/functions/index.html new file mode 100644 index 00000000..7e56284f --- /dev/null +++ b/clones/clojure-doc.org/articles/language/functions/index.html @@ -0,0 +1,398 @@ + + + + + Clojure Guides: Functions in Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • How to define functions
  • How to invoke functions
  • Multi-arity functions
  • Variadic functions
  • Higher order functions
  • Other topics related to functions

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Overview

Clojure is a functional programming language. Naturally, functions are very important part of Clojure.

How To Define Functions

Functions are typically defined using the defn macro:

(defn round
+  [d precision]
+  (let [factor (Math/pow 10 precision)]
+    (/ (Math/floor (* d factor)) factor)))
+

Functions can have doc strings (documentation strings) and it is a good idea to document functions that +are part of the public API:

(defn round
+  "Round down a double to the given precision (number of significant digits)"
+  [d precision]
+  (let [factor (Math/pow 10 precision)]
+    (/ (Math/floor (* d factor)) factor)))
+

In Clojure, function arguments may have optional type hints:

(defn round
+  [^double d ^long precision]
+  (let [factor (Math/pow 10 precision)]
+    (/ (Math/floor (* d factor)) factor)))
+

Type hints sometimes allow the compiler to avoid reflective method calls and/or produce significantly more efficient bytecode. +However, as a rule of thumb, it is usually not necessary to use type hints. Start writing your code without them. The compiler +is also free to ignore provided hints.

Functions can also define preconditions and postconditions that put restrictions on argument values and +the value function returns:

(defn round
+  "Round down a double to the given precision (number of significant digits)"
+  [^double d ^long precision]
+  {:pre [(not-nil? d) (not-nil? precision)]}
+  (let [factor (Math/pow 10 precision)]
+    (/ (Math/floor (* d factor)) factor)))
+

In the example above, we use preconditions to check that both arguments are not nil. The not-nil? macro (or function) is not +demonstrated in this example and assumed to be implemented elsewhere.

Anonymous Functions

Anonymous functions are defined using the fn special form:

(fn [x]
+  (* 2 x))
+

Anonymous functions can be assigned to locals, passed between functions (higher order functions are covered later in this document) +and returned from functions:

(let [f (fn [x]
+          (* 2 x))]
+  (map f (range 0 10)))
+

There is also a reader macro for anonymous functions:

(let [f #(* 2 %)]
+  (map f (range 0 10)))
+

The % in the example above means "the first argument". To refer to more than one argument, use %1, %2 and so on:

;; an anonymous function that takes 3 arguments and adds them together
+(let [f #(+ %1 %2 %3)]
+  (f 1 2 3))
+

Please use this reader macro sparingly; excessive use may lead to unreadable code.

How To Invoke Functions

Functions are invoked by placing a function to the leading position (the calling position) of a list:


+(import '(goog.string format))
+
(format "Hello, %s" "world")
+

This works also if you have a function stored in a local, a var or passed as an argument:

(let [f format]
+  (f "Hello, %s" "world"))
+

Alternatively, you can call a function using clojure.core/apply

(apply format "Hello, %s" ["world"])
+
(apply format "Hello, %s %s" ["Clojure" "world"])
+

clojure.core/apply is usually only necessary when calling variadic functions or having the list of arguments passed in +as a collection.

Multi-arity Functions

Functions in Clojure can have multiple arities, or sets of arguments:

(defn tax-amount
+  ([amount]
+     (tax-amount amount 35))
+  ([amount rate]
+     (Math/round (double (* amount (/ rate 100))))))
+

In the example above, the version of the function that takes only one argument (so called one-arity or 1-arity function) +calls another version (2-arity) with a default parameter. This is a common use case for multiple arities: to have default +argument values. Clojure is a hosted language and JVM (and JavaScript VMs, for that matter) does not support default argument +values, however, it does support method overloading and Clojure takes advantage of this.

Arities in Clojure can only differ by the number of arguments, not types. This is because Clojure is strongly dynamically typed language and type information about +parameters may or may not be available to the compiler.

A larger example:

(defn range
+  ([]
+    (range 0 Double/POSITIVE_INFINITY 1))
+  ([end]
+    (range 0 end 1))
+  ([start end]
+    (range start end 1))
+  ([start end step]
+    (comment Omitted for clarity)))
+

Destructuring of Function Arguments

Sometimes function arguments are data structures: vectors, sequences, maps. To access parts of such +data structure, you may do something like this:

(defn currency-of
+  [m]
+  (let [currency (get m :currency)]
+    currency))
+

For vector arguments:

(defn currency-of
+  [pair]
+  (let [amount   (first  pair)
+        currency (second pair)]
+    currency))
+

However, this is boilerplate code that has little to do with what the function really does. Clojure +lets developer destructure parts of arguments, for both maps and sequences.

Positional Destructuring

Destructuring over vectors (positional destructuring) works like this: you replace the argument +with a vector that has "placeholders" (symbols) in positions you want to bind. For example, if the +argument is known to be a pair and you need second argument, it would look like this:

(defn currency-of
+  [[amount currency]]
+  currency)
+

In the example above the first element in the pair is bound to amount and the second one is bound to +currency. So far so good. However, notice that we do not use the amount local. In that case, we can +ignore it by replacing it with an underscore:

(defn currency-of
+  [[_ currency]]
+  currency)
+

Destructuring can nest (destructure deeper than one level):

(defn first-first
+  [[[i _] _]]
+  i)
+

While this article does not cover let and locals, it is worth demonstrating that positional destructuring works +exactly the same way for let bindings:

(let [pair         [10 :gbp]
+      [_ currency] pair]
+  currency)
+

Map Destructuring

Destructuring over maps and records (map destructuring) works slightly differently:

(defn currency-of
+  [{currency :currency}]
+  currency)
+

In this case example, we want to bind the value for key :currency to currency. Keys don't have to be +keywords:

(defn currency-of
+  [{currency "currency"}]
+  currency)
+
(defn currency-of
+  [{currency 'currency}]
+  currency)
+

When destructuring multiple keys at once, it is more convenient to use a slightly different syntax:

(defn currency-of
+  [{:keys [currency amount]}]
+  currency)
+

The example above assumes that map keys will be keywords and we are interested in two values: currency +and amount. The same can be done for strings:

(defn currency-of
+  [{:strs [currency amount]}]
+  currency)
+

and symbols:

(defn currency-of
+  [{:syms [currency amount]}]
+  currency)
+

In practice, keywords are very commonly used for map keys so destructuring with {:keys [...]} is very common +as well.

Map destructuring also lets us specify default values for keys that may be missing:

(defn currency-of
+  [{:keys [currency amount] :or {currency :gbp}}]
+  currency)
+

This is very commonly used for implementing functions that take "extra options" (faking named arguments support).

Just like with positional destructuring, map destructuring works exactly the same way for let bindings:

(let [money               {:currency :gbp :amount 10}
+     {currency :currency} money]
+  currency)
+

Variadic Functions

Variadic functions are functions that take varying number of arguments (some arguments are optional). Two examples +of such function in clojure.core are clojure.core/str and clojure.core/format:

(str "a" "b")
+; โ‡’ "ab"
+
(str "a" "b" "c")
+; โ‡’ "abc"
+
(format "Hello, %s" "world")
+; โ‡’ "Hello, world"
+
(format "Hello, %s %s" "Clojure" "world")
+; โ‡’ "Hello, Clojure world"
+

To define a variadic function, prefix optional arguments with an ampersand (&):

(defn log
+  [message & args]
+  (comment ...))
+

In the example above, one argument is required and the rest is optional. Variadic functions +are invoked as usual:

(defn log
+  [message & args]
+  (println "args: " args))
+
+(log "message from " "192.0.0.76")
+
(log "message from " "192.0.0.76" "service:xyz")
+

As you can see, optional arguments (args) are packed into a list.

Extra Arguments (aka Named Parameters)

Named parameters are achieved through the use of destructuring a variadic function.

Approaching named parameters from the standpoint of destructuring a variadic function allows for more clearly readable function invocations. This is an example of named parameters:

(defn job-info
+  [& {:keys [name job income] :or {job "unemployed" income "$0.00"}}]
+  (if name
+    [name job income]
+    (println "No name specified")))
+

Using the function looks like this:

(job-info :name "Robert" :job "Engineer")
+;; ["Robert" "Engineer" "$0.00"]
+
(job-info :job "Engineer")
+;; No name specified
+

Without the use of a variadic argument list, you would have to call the function with a single map argument such as {:name "Robert" :job "Engineer}.

Keyword default values are assigned by use of the :or keyword followed by a map of keywords to their default value. +Keywords not present and not given a default will be nil.

Higher Order Functions

Higher-order functions (HOFs) are functions that take other functions as arguments. HOFs +are an important functional programming technique and are quite commonly used in Clojure. One example +of an HOF is a function that takes a function and a collection and returns a collection of elements +that satisfy a condition (a predicate). In Clojure, this function is called clojure.core/filter:

(filter even? (range 0 10))  ; โ‡’ (0 2 4 6 8)
+

In the example above, clojure.core/filter takes clojure.core/even? as an argument.

clojure.core has dozens of other higher-order functions. The most commonly used ones are covered in clojure.core Overview.

Private Functions

Functions in Clojure can be private to their namespace.

They are covered in more detail in the Namespaces guide.

Keywords as Functions

In Clojure, keywords can be used as functions. They take a map or record and look themselves up in it:

(:age {:age 27 :name "Michael"}) 
+; โ‡’ 27
+

This is commonly used with higher order functions:

(map :age [{:age 45 :name "Joe"}
+           {:age 42 :name "Jill"}
+           {:age 17 :name "Matt"}]) 
+;; โ‡’ (45 42 17)
+

and the -> macro:

(-> [{:age 45 :name "Joe"} {:age 42 :name "Jill"}]
+     first 
+     :name)
+;; โ‡’ "Joe"
+

Maps as Functions

Clojure maps are also functions that take keys and look up values for them:

({:age 42 :name "Joe"} :name)
+; โ‡’ "Joe"
+
({:age 42 :name "Joe"} :age)
+; โ‡’ 42
+
({:age 42 :name "Joe"} :unknown)
+; โ‡’ nil
+

Note that this is not true for Clojure records, which are almost identical to maps in other +cases.

Sets as Functions

(#{1 2 3} 1)
+; โ‡’ 1
+
(#{1 2 3} 10)
+; โ‡’ nil
+
(#{:us :au :ru :uk} :uk)
+; โ‡’ :uk
+
(#{:us :au :ru :uk} :cn)
+; โ‡’ nil
+

This is often used to check if a value is in a set:

(when (countries :in)
+  (comment ...))
+
+(if (countries :in)
+  (comment Implement positive case)
+  (comment Implement negative case))
+

because everything but false and nil evaluates to true in Clojure.

Clojure Functions As Comparators

Clojure functions implement the java.util.Comparator +interface and can be used as comparators.

Wrapping Up

Functions are at the heart of Clojure. They are defined using the defn macro, can have multiple arities, +be variadic and support parameter destructuring. Function arguments and return value can optionally be +type hinted.

Functions are first class values and can be passed to other functions (called Higher Order Functions or HOFs). +This is fundamental to functional programming techniques.

Several core data types behave like functions. When used reasonably, this can lead to more concise, readable +code.

Contributors

Michael Klishin michael@defprotocol.org, 2012 (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/glossary/index.html b/clones/clojure-doc.org/articles/language/glossary/index.html new file mode 100644 index 00000000..71a5a264 --- /dev/null +++ b/clones/clojure-doc.org/articles/language/glossary/index.html @@ -0,0 +1,344 @@ + + + + + Clojure Guides: Clojure Terminology Guide + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

A glossary of terminology specific to Clojure. Terms +are listed in alphabetical order.

Terms

arity

The number of arguments a function takes is its arity. If it's +written to take a variable number of args, it's referred to as +variadic.

Functions can have multiple arity (for example, a function might have +2 different bodies: one for when 2 args are passed, and another when 3 +args are passed).

binding-form

Could mean one of two things:

  1. the expression you're binding to in a +let-binding. It might be a simple name, or it +might be a data structure used for +destructuring.

  2. Clojure provides the binding macro, used for setting the +thread-local value of a dynamic var. The whole expression (form) +is sometimes referred to as the "binding form".

classpath

The search path used by the JVM to locate classes which are not +part of the Java standard class library. May include jar files.

comparator

A function that takes two args and compares them. Returns -1, 0, or 1 +depending whether the first arg is less than, equal to or greater than +the second. The stock comparator that Clojure.core comes with is +compare.

coordinates

The "group-id/artifact-id version-string" identifier used in your +project.clj to indicate a particular dependency.

See also libspec.

destructuring

The handy trick used in a let-binding to "unpack" the +values from a data structure into the locals you're going to use. See +also binding-form and the destructuring section in +the functions +guide.

dereference

To get the value of a reference type. You can use the deref function +for this, or else some syntactic sugar: @some-ref-type.

entry

A key/value pair in a map. Try (type (first {:a 1 :b 2})) and see +that it returns clojure.lang.MapEntry.

evaluator

todo

form

A valid s-expression. For example: (+ 1 1) and (defn foo [x] (* x x)).

head retention

Lazy sequences are still persistent. If you +make another data structure using one, the original lazy sequence +will be kept around and not garbage-collected. If the lazy sequence in +infinite, and grows very large, it can cause performance problems or +even an out-of-memory error. Accidentally keeping around a lazy +sequence like this is referred to as "head retention".

homoiconicity

Where the code and the data is represented by the same structure. +This allows the code to be treated as data, and the data to be treated +as code. This feature of Clojure, and other Lisps, allows for +macros in the language, since they can operate on code as a data +structure, and to return a transformation of that structure to +be the representation of new code.

idempotent

An operation that when given the same inputs will produce the same +result when called one or more times. An idempotent function may +produce a side effect, such a updating a ref or an atom, but will +only produce the side effect once. An idempotent function is +different than a pure function, in that a pure function will +produce no side effects.

identity

A logical entity in your program that may change over time --- it may +take on different states at different times, but it still means the +same logical entity. Clojure uses reference types +to represent identities. This is not to be confused with the identity function that just returns the argument given to it.

implicit do

The bodies of some expressions act like do in that you can include +multiple expressions in them, and the expressions will be evaluated in +the order they appear, with the resulting value of the body being the +last expression evaluated. Forms that do this include: when, +when-let, fn, defn, let, loop, and try.

intern

A method of storing values or immutable data structures as a single +copy of the item, allowing for more space-efficiency, and possibly +time-efficiency, with the trade off of requiring more time being +required when interning the item. When the string "clojure" is interned, +all instances of the string "clojure" will reference the exact same +instance, instead of having multiple string objects with the same value +of "clojure".

keyword

A Clojure scalar data type whose literal syntax looks :like :this. +They are like numbers and strings in that they evaluate to themselves, +and are most often seen being used as keys in hash-maps.

See also namespaced keyword

The term is also used when talking about functions that take "keyword +arguments", for example, something like: (my-func :speed 42 :mass 2) +(as opposed to (my-func {:speed 42 :mass 2})).

lazy

Clojure can (and often does) create sequences for you that aren't +fully computed. Upon casual inspection they look just like a regular +list, but particular values in them are only computed the moment you +ask for them --- not sooner.

This has the added benefit that you can easily create infinite +sequences that don't consume infinite memory.

Many of the built-in Clojure functions return lazy sequences.

See also realize.

let-binding

AKA, "binding vector", or just "bindings": in a let (and expressions +that work like let, for example, defn, loop, loop, & fn), the +vector that comes first where you specify lexical bindings.

See also binding form

libspec

todo

macro

A special type of function which is transforms a S-Expression read in +and applies a transformation to the S-Expression resulting in a new +form. This process is called macro-expansion, and is done as part +of the Clojure reader.

map

Either refers to the built in map function, or else means "a +hash-map object".

memoization

The ability to cache a result of a function call by given arguments, +and return the result without having to do the calculation again. +Memoization is a time-space trade off in that more memory is used +to store the results of a function call to be able to return the +value instead of having to keep spending time doing the calculation +involved in the function.

metadata

An extra map that you can attach to a collection value (or a symbol), +which contains data about the data you're attaching it to. Use meta +to see the metadata of a given value.

namespaced keyword

When you put two colons in front of a keyword's name --- for example +::foo --- it is a so-called "namespaced keyword", and is expanded by +the reader to become :current-namespace/foo.

nullipotent

An operation with no side effects. The result of calling the function +one or more times is the same as if it was never called. Queries are +typically good examples of functions that are nullipotent, as they +do not modify the state of the object or structure they are queried +against.

persistence

See the relevant section of the +introduction.

predicate

A function taking one or more args and returning a boolean (true or +false). Its name typically ends with a question mark. Some examples: +nil?, zero?, string?.

pure function

A function that given the same inputs will always produce the same +result. A pure function also does not have any observable side effects +and cannot depend on any outside state, other than that which was given +as arguments to the function. A pure function's result also cannot change +during the execution of the program or between executions of the program, +as the dependency on outside state can lead to changes in the result of +the function. Pure functions are also +referentially transparent.

reader

todo

reader macro

Syntax that the Clojure reader recognizes as special syntactic sugar, +for example, #"", #{}, quoting, etc.

realize

When the next value in a lazy sequence is accessed for the +first time, and is computed so as to made available, it is said to +have been "realized". This term is also used to refer to the status of promises, futures, and delays. That is, if a promise (for example) is realized then that means its value has been delivered and is accessible via dereferencing.

reference types

Vars, atoms, refs, and agents are all reference types. They are +mutable in the sense that you can change to what value they refer, and +Clojure provides thread-safe mechanisms for doing so.

referential transparency

An expression that will always return the same result for the values +given, and can be substituted for the resulting value, without +effecting the program. The advantage of referential transparent +expressions is that they can be memoized, and be the subject of +various compilier optimizations.

reify

todo

REPL

Short for: "Read, Eval, Print, Loop". The REPL reads in text through +the reader transforming it into a Clojure data structure, +evaluates the data structure as code, prints the result +of the evaluation, and loops back waiting to read the next input string.

rest args

The extra args passed to a variadic function, for example +if my-func were defined like (defn my-func [a b & more] ...), then +called like (my-func 1 2 3 4 5), then 3, 4, & 5 are the "rest args".

s-expression

Short for Symbolic Expression. A S-Expression is a data structure able +to represent both simple datastructes such as literals, or complex data +structures such as nested expressions. Due to their versatile nature, +S-Expressions are able to represent both data in Clojure, as well as +the Clojure code itself, allowing Clojure to be a +homoiconic language.

state

The value that a given identity may have at a +given time. When you change the state of an identity, you're changing +to which value it refers. Clojure uses values to represent states.

STM (Software Transactional Memory)

Software Transactional Memory (STM) is a concurrency control method to +coordinate and control access to shared storage as an alternative to +lock-based synchronization. Clojure's STM uses multiversion concurrency +control (MVCC) as an alternative to lock-based transactions, as well as +ensuring changes are made atomically, consistently, and in +isolation. It does this by taking a snapshot of the ref, making the +changes in isolation to the snapshot, and apply the result. If the STM +detects that another transaction has made an update to the ref, the +current transaction will be forced to retry.

symbol

An identifier that refers to vars or local values.

tagged literals

(Formerly called "reader literals".)

Some literals begin with a hash mark "#" (so-called "dispatch +macros"); for example, #{} for sets and #"" for regex +literals. Starting with Clojure 1.4, you can create your own +#-prefixed literal which causes the reader to parse the form +following it using a function or macro of your own +choosing/devising. It's in this way that you can tag a literal to be +handled specially by the reader.

For more info, see the "Tagged Literals" section of the reader +doc.

threading macros

The thread-first (->) and thread-last (->>) macros. "Threading" +refers to how they pass values to each subsequent argument in the +macro, not concurrency.

thrush

A combinator. Not the same thing as the thread-first +macro. More info at +http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/ if you're +curious.

transaction

todo

type erasure

Java-related: Java generics allow you to specify a type for a +collection. This way you don't have to cast every object you pull out +of an ArrayList like in the old days. This is a courtesy of the java +compiler. The java runtime doesn't know about generics --- the +compiler does all the checking for you, then the type information is +discarded at runtime. In Clojure, this discarding is referred to as +type erasure.

value

An immutable object, such as the number 1, the character \a, the +string "hello", or the vector [1 2 3]. In Clojure, all scalars and +built-in core data structures are values.

variadic

A function that can take a variable number of arguments. +See also rest args.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/interop/index.html b/clones/clojure-doc.org/articles/language/interop/index.html new file mode 100644 index 00000000..891281b5 --- /dev/null +++ b/clones/clojure-doc.org/articles/language/interop/index.html @@ -0,0 +1,617 @@ + + + + + Clojure Guides: Clojure interoperability with Java + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • How to instantiate Java classes
  • How to invoke Java methods
  • How to extend Java classes with proxy
  • How to implement Java interfaces with reify
  • How to generate Java classes with gen-class
  • Other topics related to interop

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Overview

Clojure was designed to be a hosted language that directly interoperates with its host platform (JVM, CLR and so on). +Clojure code is compiled to JVM bytecode. For method calls on Java objects, Clojure compiler +will try to emit the same bytecode javac would produce.

It is possible to implement interfaces, extend and generate Java classes in Clojure.

Clojure also provides convenient functions and macros that make consuming of Java libraries +easier and often more concise than it would be in Java code.

Imports

Java classes can be referenced either using their fully-qualified names (FQNs) such as +java.util.Date or be imported in the current Clojure namespace using clojure.core/import and +referenced by short names:

java.util.Date  ; โ‡’ java.util.Date
+
(import java.util.Date)
+
+Date  ; โ‡’ java.util.Date
+

ns macro supports imports, too:

(ns myservice.main
+  (:import java.util.Date))
+

More about the ns macro can be found in the article on Clojure namespaces.

Dynamic (at runtime) imports are usually only used in the REPL and cases when there are multiple implementations of a particular +protocol/service/feature and it is not possible to tell which one should be used until run time.

Automatic Imports For java.lang.*

Classes from the java.lang package are automatically imported. For example, you can use String or Math +without explicitly importing them:

(defn http-uri?
+  [^String uri]
+  (.startsWith (.toLowerCase uri) "http"))
+
+(Math/round 0.7886)
+

Inner (Nested) Classes

In Java, classes can be nested inside other classes. They are called inner classes and by convention, +separated from their outer class by a dollar sign ($):

(import java.util.Map$Entry)
+
+Map$Entry  ; โ‡’ java.util.Map$Entry
+
+;; this example assumes RabbitMQ Java client is on classpath
+(import com.rabbitmq.client.AMQP$BasicProperties)
+
+AMQP$BasicProperties  ; โ‡’ com.rabbitmq.client.AMQP$BasicProperties
+

Note that if you need to use both a class and one or more of its inner classes, they all need to be imported separately. +As far as JVM is concerned, they are all separate classes, there is no "imports hierarchy".

How to Instantiate Java Classes

Java classes are instantiated using the new special form:

(new java.util.Date)  ; โ‡’ #inst "2012-10-09T21:23:57.278-00:00"
+

However, the Clojure reader provides a bit of syntactic sugar and you are much more likely +to see this:

(java.util.Date.)     ; โ‡’ #inst "2012-10-09T21:24:43.878-00:00"
+

It is possible to use fully qualified names (e.g. java.util.Date) or short names with imports:

(import java.util.Date)
+
+(Date.)  ; โ‡’ #inst "2012-10-09T21:24:27.229-00:00"
+

An example with constructor arguments:

(java.net.URI. "http://clojure.org")  ; โ‡’ #<URI http://clojure.org>
+

How to Invoke Java Methods

Instance Methods

Instance methods are invoked using the . special form:

(let [d (java.util.Date.)]
+  (. d getTime))  ; โ‡’ 1349819873183
+

Just like with object instantiation, it is much more common to see an alternative version:

(let [d (java.util.Date.)]
+  (.getTime d))  ; โ‡’ 1349819873183
+

Static Methods

Static methods can be invoked with the same . special form:

(. Math floor 5.677)  ; โ‡’ 5.0
+

or (typically) to sugared version, ClassName/methodName:

(Math/floor 5.677)  ; โ‡’ 5.0
+
+(Boolean/valueOf "false")  ; โ‡’ false
+(Boolean/valueOf "true")   ; โ‡’ true
+

Chained Calls With The Double Dot Form

It is possible to chain method calls using the .. special form:

(.. (java.util.Date.) getTime toString)  ; โ‡’ "1349821993809"
+

Multiple Calls On the Same Object

If you need to call a bunch of methods on a mutable object, you +can use the doto macro:

(doto (java.util.Stack.)
+  (.push 42)
+  (.push 13)
+  (.push 7))  ; โ‡’ #<Stack [42, 13, 7]>
+
+(let [pt (Point. 0 0)]
+  (doto pt
+    (.move  10 0)))  ; โ‡’ #<Point java.awt.Point[x=10, y=0]
+
+(let [pt (Point. 0 0)]
+  (doto pt
+    (.move  10 0)
+    (.translate  0 10)))  ; โ‡’ #<Point java.awt.point[x=10,y=10]
+

The doto macro returns its first argument as a result.

How to Access Java Fields

Public mutable fields are not common in Java libraries but sometimes you need to access them. +It's done with the same dot special form:

(import java.awt.Point)
+
+(let [pt (Point. 0 10)]
+  (. pt x))  ; โ‡’ 0
+
+(let [pt (Point. 0 10)]
+  (. pt y))  ; โ‡’ 10
+

and just like with instance methods, it is much more common to see the following version:

(import java.awt.Point)
+
+(let [pt (Point. 0 10)]
+  (.x pt))  ; โ‡’ 0
+
+(let [pt (Point. 0 10)]
+  (.y pt))  ; โ‡’ 10
+

How to Set Java Fields

To set a public mutable field, use clojure.core/set! that takes a field in the dot notation +demonstrated earlier and a new value:

(import java.awt.Point)
+
+(let [pt (Point. 0 10)]
+  (set! (.y pt) 100)
+  (.y pt))  ; โ‡’ 100
+

Fortunately, mutable public fields are rare to meet in the JVM ecosystem so you won't need +to do this often.

How To Work With Enums

Enums (enumeration) type values are accessed +the same way as fields, except on enum classes and not objects:

java.util.concurrent.TimeUnit/MILLISECONDS  ; โ‡’ #< MILLISECONDS>
+

Determining Classes of Java Objects

To get class of a particular value, pass it to clojure.core/class:

(class 1)       ; โ‡’ java.lang.Long
+(class 1.0)     ; โ‡’ java.lang.Double
+(class "docs")  ; โ‡’ java.lang.String
+(class (java.net.URI. "https://github.com"))  ; โ‡’ java.net.URI
+

As this example demonstrates, Clojure strings are JVM strings, integer literals are compiled +as longs and floating point literals are compiled as doubles.

You can also use clojure.core/type to return either the class of the +Java object, or the :type metadata if it exists:

(def foo (with-meta [1 2 3] {:type :bar}))
+(type foo)
+;; โ‡’ :bar
+(type [1 2 3])
+;; โ‡’ clojure.lang.PersistentVector
+

How To Get a Java Class Reference By Name

To obtain a class reference by its string name (fully qualified), use Class/forName via Java interop:

(Class/forName "java.util.Date")  ; โ‡’ java.util.Date
+

Array Types, Primitives

JVM has what is called primitive types (numerics, chars, booleans) that are not "real" objects. +In addition, array types have pretty obscure internal names. If you need to obtain a reference to +an array of longs, for example, pass "[[J" to Class/forName. Below is the full table:

Internal JVM class nameArray of ? (type)
"[[S"
short
"[[I"
integer
"[[J"
long
"[[F"
float
"[[D"
double
"[[B"
byte
"[[C"
char
"[[Z"
boolean

If this does not make much sense, don't worry. Just remember to come +back to this guide when you need to extend a protocol for an array of +primitives.

Implementing Java Interfaces With reify

It is possible to implement Java interfaces in Clojure. It is +typically needed to interact with Java libraries that take arguments +implementing a particular interface.

Interfaces are implemented using the reify special form.

Given the following Java interface:

public
+interface FilenameFilter {
+    /**
+     * Tests if a specified file should be included in a file list.
+     *
+     * @param   dir    the directory in which the file was found.
+     * @param   name   the name of the file.
+     * @return  <code>true</code> if and only if the name should be
+     * included in the file list; <code>false</code> otherwise.
+     */
+    boolean accept(File dir, String name);
+}
+

here is how to implement it in Clojure:

;; a FileFilter implementation that accepts everything
+(reify java.io.FilenameFilter
+  (accept [this dir name]
+    true))
+

reify takes an interface (fully-qualified name or short name) and one or more +method implementations that mimic function definitions without the defn and with +this (as in Java, JavaScript or self in Ruby, Python) reference being the first argument:

(accept [this dir name]
+  true)
+

With reify, generally there is no need to add type hints on arguments: Clojure +compiler typically will detect the best matching method (by name and number of arguments).

reify returns a Java class instance. Clojure compiler will generate a class that implements +the interface and instantiate it. To demonstrate that reified objects indeed implement +the interface:

(let [ff (reify java.io.FilenameFilter
+           (accept [this dir name]
+             true))]
+  (instance? java.io.FileFilter ff))  ; โ‡’ true
+

reify can be used to implement multiple interfaces at once:

(let [ff (reify java.io.FilenameFilter
+           (accept [this dir name]
+             true)
+
+           java.io.FileFilter
+           (accept [this dir]
+             true))]
+  (instance? java.io.FileFilter ff))  ; โ‡’ true
+

reify, Parameter Destructuring and Varargs

reify does not support destructuring or variadic number of arguments in method signatures. +For example, the following will not work and won't even compile in Clojure 1.5:

(reify com.megacorp.api.AnInterface
+  (aMethod [a [b c]]
+    (comment ...))
+  (anotherMethod [a & rest]
+    (comment ...)))
+

Example 1

The following example demonstrates how instances created with reify are passed around +as regular Java objects:

(import java.io.File)
+
+;; a file filter implementation that keeps only .clj files
+(let [ff (reify java.io.FilenameFilter
+           (accept [this dir name]
+             (.endsWith name ".clj")))
+    dir  (File. "/Users/antares/Development/ClojureWerkz/neocons.git/")]
+  (into [] (.listFiles dir ff)))
+;; โ‡’ [#<File /Users/antares/Development/ClojureWerkz/neocons.git/project.clj>]
+

reify forms a closure: it will capture locals in its scope. This can be used to make implemented +methods delegate to Clojure functions. The same example, rewritten with delegation:

user> (import java.io.File)
+
+;; a file filter implementation that keeps only .clj files
+(let [f  (fn [^File dir ^String name]
+           (.endsWith name ".clj"))
+      ff (reify java.io.FilenameFilter
+           (accept [this dir name]
+             (f dir name)))
+    dir  (File. "/Users/antares/Development/ClojureWerkz/neocons.git/")]
+  (into [] (.listFiles dir ff)))
+;; โ‡’ [#<File /Users/antares/Development/ClojureWerkz/neocons.git/project.clj>]
+

Note that unlike in the "inline" implementation, Clojure compiler cannot infer types of +dir and name parameters in the function that does the filtering, so we added type hints +to avoid reflective calls. When methods are implemented "inline", types can be inferred from +method signatures in the interface.

Extending Java Classes With proxy

proxy is one of two ways to generate instances of anonymous classes in Clojure. +proxy takes two vectors: one listing its superclass and (optional) interfaces, another constructor signatures, as well as +method implementations. Method implementations are basically identical to reify except that the this argument is +not necessary.

A very minimalistic example, we instantiate an anonymous class that extends java.lang.Object, implements no +interfaces, has no explictly defined constructors and overrides #toString:

(proxy [Object] []
+        (toString []
+          "I am an instance of an anonymous class generated via proxy"))
+;; โ‡’ #<Object$0 I am an instance of an anonymous class generated via proxy>
+

Clojure compiler will generate an anonymous class for this proxy and at runtime, the cost of +a proxy call is the cost of instantiating this class (the class is not generated anew on every single call).

A slightly more complex example where the generated class also implements java.lang.Runnable (runnable objects +are commonly used with threads and java.util.concurrent classes) which defines one method, #run:

;; extends java.lang.Object, implements java.lang.Runnable
+(let [runnable (proxy [Object Runnable] []
+                       (toString []
+                         "I am an instance of an anonymous class generated via proxy")
+                       (run []
+                         (println "Run, proxy, run")))]
+        (.run runnable))  ; โ‡’ nil
+;; outputs "Run, proxy, run"
+

proxy forms a closure: it will capture locals in its scope. This is very often used to create an instance +that delegates to a Clojure function:

(let [f   (fn [] (println "Executed from a function"))
+      obj (proxy [Object Runnable] []
+            (run []
+              (f)))]
+        (.run obj))  ; โ‡’ nil
+;; outputs "Executed from a function"
+

TBD: more realistic examples | How to Contribute

Clojure Functions Implement Runnable and Callable

Note that Clojure functions implement java.lang.Runnable and +java.util.concurrent.Callable directly so you can pass functions to +methods found in various classes from the java.util.concurrent package.

For example, to run a function in a new thread:

(let [t (Thread. (fn []
+                   (println "I am running in a separate thread")))]
+  (.start t))
+

Or submit a function for execution to a thread pool (in JDK terms: an execution service):

(import '[java.util.concurrent Executors ExecutorService Callable])
+
+(let [^ExecutorService pool (Executors/newFixedThreadPool 16)
+      ^Callable  clbl       (cast Callable (fn []
+                                             (reduce + (range 0 10000))))
+      task                  (.submit pool clbl)]
+  (.get task))
+;; โ‡’ 49995000
+

Note that without the cast, Clojure compiler would not be able to determine +which exact version of the method we intend to invoke, because java.util.concurrent.ExecutionService/submit +has two versions, one for Runnable and one for Callable. They work very much the same but return +slightly different results (Callable produces a value while Runnable always returns nil when +executed).

The exception we would get without the cast is

CompilerException java.lang.IllegalArgumentException: More than one matching method found: submit, compiling:(NO_SOURCE_PATH:2)
+

gen-class and How to Implement Java Classes in Clojure

Overview

gen-class is a Clojure feature for implementing Java classes in Clojure. It is relatively +rarely used compared to proxy and reify but is needed to implement executable classes +(that java runner and IDEs can as program entry points).

Unlike proxy and reify, gen-class defines named classes. They can be passed to Java +APIs that expect class references. Classes defined with gen-class can extend +base classes, implement any number of Java interfaces, define any number of constructors +and define both instance and static methods.

AOT

gen-class requires ahead-of-time (AOT) compilation. It means that +before using the classes defined with gen-class, the Clojure +compiler needs to produce .class files from gen-class definitions.

Class Definition With clojure.core/gen-class

clojure.core/gen-class is a macro that uses a DSL for defining class +methods, base class, implemented interfaces and so on.

It takes a number of options:

  • :name (a symbol): defines generated class name
  • :extends (a symbol): name of the base class
  • :implements (a collection): interfaces the class implements
  • :constructors (a map): constructor signatures
  • :methods (a collection): lists methods that will be implemented
  • :init (symbol): defines a function that will be invoked with constructor arguments
  • :post-init (symbol): defines a function that will be called with a constructed instance as its first argument
  • :state (symbol): if supplied, a public final instance field with the given name will be created. Only makes sense when +used with :init. State field value should be an atom or other ref type to allow state mutation.
  • :prefix (string, default: "-"): methods will call functions named as (str prefix method-name), e.g. -getName for getName.
  • :main (boolean): if true, a public static main method will be generated for the class. It will delegate +to a function named main with the prefix ((str prefix "main")), -main by default
  • :exposes: TBD
  • :exposes-methods: TBD
  • :factory: TBD
  • :load-impl-ns: TBD
  • :impl-ns: TBD

The :name Option

TBD

The :extends Option

TBD

The :implements Option

TBD

The :constructors Option

TBD

The :methods Option

TBD

The :init Option

TBD

The :post-init Option

TBD

The :state Option

TBD

The :prefix Option

TBD

The :main Option

TBD

The :exposes Option

TBD

The :exposes-methods Option

TBD

The :factory Option

TBD

The :load-impl-ns Option

TBD

The :impl-ns Option

TBD

gen-class In The ns Macro

gen-class can be used with existing namespaces by adding (:gen-class) to the +ns macro. Here is a "hello, world" example command line app that uses gen-class +to generate a class that JVM launcher (java) can run:

(ns genclassy.core
+  (:gen-class))
+
+(defn -main
+  [& args]
+  (println "Hello, World!"))
+

This will use the name of the namespace for class name and use the namespace for method +implementation (see the :impl-ns option above).

Examples

A medium size example taken from an open source library:

(ns clojurewerkz.quartzite.listeners.amqp.PublishingSchedulerListener
+  (:gen-class :implements   [org.quartz.SchedulerListener]
+              :init         init
+              :state        state
+              :constructors {[com.rabbitmq.client.Channel String String] []})
+  (:require [langohr.basic     :as lhb]
+            [clojure.data.json :as json])
+  (:use [clojurewerkz.quartzite.conversion])
+  (:import [org.quartz SchedulerListener SchedulerException Trigger TriggerKey JobDetail JobKey]
+           [com.rabbitmq.client Channel]
+           [java.util Date]
+           [clojurewerkz.quartzite.listeners.amqp PublishingSchedulerListener]))
+
+
+
+(defn publish
+  [^PublishingSchedulerListener this payload ^String type]
+  (let [{ :keys [channel exchange routing-key] } @(.state this)
+        payload (json/json-str payload)]
+    (lhb/publish channel exchange routing-key payload :type type)))
+
+
+(defn -init
+  [^Channel ch ^String exchange ^String routing-key]
+  [[] (atom { :channel ch :exchange exchange :routing-key routing-key })])
+
+
+(defmacro payloadless-publisher
+  [method-name message-type]
+  `(defn ~method-name
+     [this#]
+     (publish this# (json/json-str {}) ~message-type)))
+
+(payloadless-publisher -schedulerStarted       "quartz.scheduler.started")
+(payloadless-publisher -schedulerInStandbyMode "quartz.scheduler.standby")
+(payloadless-publisher -schedulingDataCleared  "quartz.scheduler.cleared")
+(payloadless-publisher -schedulerShuttingDown  "quartz.scheduler.shutdown")
+
+
+(defn -schedulerError
+  [this ^String msg ^SchedulerException cause]
+  (publish this (json/json-str { :message msg :cause (str cause) }) "quartz.scheduler.error"))
+
+
+(defn -jobScheduled
+  [this ^Trigger trigger]
+  (publish this (json/json-str { :group (-> trigger .getKey .getGroup) :key (-> trigger .getKey .getName) :description (.getDescription trigger) }) "quartz.scheduler.job-scheduled"))
+
+(defn -jobUnscheduled
+  [this ^TriggerKey key]
+  (publish this (json/json-str { :group (.getGroup key) :key (.getName key) }) "quartz.scheduler.job-unscheduled"))
+
+(defn -triggerFinalized
+  [this ^Trigger trigger]
+  (publish this (json/json-str { :group (-> trigger .getKey .getGroup) :key (-> trigger .getKey .getName) :description (.getDescription trigger) }) "quartz.scheduler.trigger-finalized"))
+
+(defn -triggerPaused
+  [this ^TriggerKey key]
+  (publish this (json/json-str { :group (.getGroup key) :key (.getName key) }) "quartz.scheduler.trigger-paused"))
+
+(defn -triggersPaused
+  [this ^String trigger-group]
+  (publish this (json/json-str { :group trigger-group }) "quartz.scheduler.triggers-paused"))
+
+(defn -triggerResumed
+  [this ^TriggerKey key]
+  (publish this (json/json-str { :group (.getGroup key) :key (.getName key) }) "quartz.scheduler.trigger-resumed"))
+
+(defn -triggersResumed
+  [this ^String trigger-group]
+  (publish this (json/json-str { :group trigger-group }) "quartz.scheduler.triggers-resumed"))
+
+
+
+(defn -jobAdded
+  [this ^JobDetail detail]
+  (publish this (json/json-str { :job-detail (from-job-data (.getJobDataMap detail)) :description (.getDescription detail) }) "quartz.scheduler.job-added"))
+
+(defn -jobDeleted
+  [this ^JobKey key]
+  (publish this (json/json-str { :group (.getGroup key) :key (.getName key) }) "quartz.scheduler.job-deleted"))
+
+(defn -jobPaused
+  [this ^JobKey key]
+  (publish this (json/json-str { :group (.getGroup key) :key (.getName key) }) "quartz.scheduler.job-paused"))
+
+(defn -jobsPaused
+  [this ^String job-group]
+  (publish this (json/json-str { :group job-group }) "quartz.scheduler.jobs-paused"))
+
+(defn -jobResumed
+  [this ^JobKey key]
+  (publish this (json/json-str { :group (.getGroup key) :key (.getName key) }) "quartz.scheduler.job-resumed"))
+
+(defn -jobsResumed
+  [this ^String job-group]
+  (publish this (json/json-str { :group job-group }) "quartz.scheduler.jobs-resumed"))
+

Inspecting Class Signatures

When using gen-class for interoperability purposes, sometimes it is necessary to inspect the API +of the class generated by gen-class.

It can be inspected +using javap. Given the +following Clojure namespace:

(ns genclassy.core
+  (:gen-class))
+
+(defn -main
+  [& args]
+  (println "Hello, World!"))
+

We can inspect the produced class like so:

# from target/classes, default .class files location used by Leiningen
+javap genclassy.core
+

will output

public class genclassy.core {
+  public static {};
+  public genclassy.core();
+  public java.lang.Object clone();
+  public int hashCode();
+  public java.lang.String toString();
+  public boolean equals(java.lang.Object);
+  public static void main(java.lang.String[]);
+}
+

How To Extend Protocols to Java Classes

Clojure protocols can be extended to any java class (including +Clojure's internal types) very easily using extend:

Using the example of a json library, we can define our goal as getting +to the point where the following works:

(json-encode (java.util.UUID/randomUUID))
+

First, let's start with the protocol for json encoding an object:

(defprotocol JSONable
+  (json-encode [obj]))
+

So, everything that is "JSONable" implements a json-encode method.

Next, let's define a dummy method to do the "encoding" (in this +example, it just prints to standard out instead, it doesn't actually +do any json encoding):

(defn encode-fn
+  [x]
+  (prn x))
+

Now, define a method that will encode java objects by calling bean +on them, then making each value of the bean map a string:

(defn encode-java-thing
+  [obj]
+  (encode-fn
+   (into {}
+         (map (fn [m]
+                [(key m) (str (val m))])
+              (bean obj)))))
+

Let's try it on an example object, a UUID:

(encode-java-thing (java.util.UUID/randomUUID))
+;; โ‡’ {:mostSignificantBits "-6060053801408705927",
+;;    :leastSignificantBits "-7978739947533933755",
+;;    :class "class java.util.UUID"}
+

The next step is to extend the protocol to the java type, telling +clojure which java type to extend, the protocol to implement and the +method to use for the json-encode method:

(extend java.util.UUID
+  JSONable
+  {:json-encode encode-java-thing})
+

Alternatively, you could use the extend-type macro, which actually +expands into calls to extend:

(extend-type java.util.UUID
+  JSONable
+  (json-encode [obj] (encode-java-thing obj)))
+

Now we can use json-encode for the object we've extended:

(json-encode (java.util.UUID/randomUUID))
+;; โ‡’  {:mostSignificantBits "3097485598740136901",
+;;     :leastSignificantBits "-9000234678473924364",
+;;     :class "class java.util.UUID"}
+

You could also write the function inline in the extend block, for +example, extending nil to return a warning string:

(extend nil
+  JSONable
+  {:json-encode (fn [x] "x is nil!")})
+
+(json-encode nil)
+;; โ‡’  "x is nil!"
+

The encode-java-thing method can also be reused for other Java types +we may want to encode:

(extend java.net.URL
+  JSONable
+  {:json-encode encode-java-thing})
+
+(json-encode (java.net.URL. "http://aoeu.com"))
+;; โ‡’  {:path "",
+;;     :protocol "http",
+;;     :authority "aoeu.com",
+;;     :host "aoeu.com",
+;;     :ref "",
+;;     :content "sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@4ecac02f",
+;;     :class "class java.net.URL",
+;;     :defaultPort "80",
+;;     :port "-1",
+;;     :query "",
+;;     :file "",
+;;     :userInfo ""}
+

Using Intrinsic Locks ("synchronized") in Clojure

Every object on the JVM has an intrinsic lock (also referred to as monitor lock +or simply monitor). While very rarely necessary, Clojure provides support for +operations that acquire intrinsic lock of a mutable Java object.

This is covered in the Concurrency and Parallelism guide.

Wrapping Up

TBD: How to Contribute

Contributors

Michael Klishin michael@defprotocol.org (original author) +Lee Hinman lee@writequit.org +gsnewmark gsnewmark@meta.ua

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/laziness/index.html b/clones/clojure-doc.org/articles/language/laziness/index.html new file mode 100644 index 00000000..b0c068da --- /dev/null +++ b/clones/clojure-doc.org/articles/language/laziness/index.html @@ -0,0 +1,264 @@ + + + + + Clojure Guides: Laziness in Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • What are lazy sequences
  • Pitfalls with lazy sequences
  • How to create functions that produce lazy sequences
  • How to force evaluation

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Overview

Clojure is not a lazy language.

However, Clojure supports lazily evaluated sequences. This means that sequence elements are not +available ahead of time and produced as the result of a computation. The computation +is performed as needed. Evaluation of lazy sequences is known as realization.

Lazy sequences can be infinite (e.g. the sequence of Fibonacci numbers, a sequence of +dates with a particular interval between them, and so on). If a lazy sequence is finite, +when its computation is completed, it becomes fully realized.

When it is necessary to fully realize a lazy sequence, Clojure provides a way to +force evaluation (force realization).

Benefits of Lazy Sequences

Lazy sequences have two main benefits:

  • They can be infinite
  • Full realization of interim results can be avoided

Producing Lazy Sequences

Lazy sequences are produced by functions. Such functions either use the clojure.core/lazy-seq macro +or other functions that produce lazy sequences.

clojure.core/lazy-seq accepts one or more forms that produce a sequence of nil (when the sequence +is fully realized) and returns a seqable data structure that invokes the body the first time +the value is needed and then caches the result.

For example, the following function produces a lazy sequence of random UUIDs strings:

(defn uuid-seq
+  []
+  (lazy-seq
+   (cons (str (random-uuid))
+         (uuid-seq))))
+

Note: the random-uuid function is available in ClojureScript and was introduced into Clojure +in version 1.11 Alpha 3. Prior to that, you needed to use Java interop:

(defn uuid-seq
+  []
+  (lazy-seq
+   (cons (str (java.util.UUID/randomUUID))
+         (uuid-seq))))
+

Another example:

(defn fib-seq
+  "Returns a lazy sequence of Fibonacci numbers"
+  ([]
+     (fib-seq 0 1))
+  ([a b]
+     (lazy-seq
+      (cons b (fib-seq b (+ a b))))))
+

Both examples use clojure.core/cons which prepends an element to a sequence. The sequence +can in turn be lazy, which both of the examples rely on.

Even though both of these sequences are infinite, taking first N elements from each does +return successfully:

(take 3 (uuid-seq))
+
(take 10 (fib-seq))
+
(take 20 (fib-seq))
+

Realizing Lazy Sequences (Forcing Evaluation)

Lazy sequences can be forcefully realized with clojure.core/dorun and +clojure.core/doall. The difference between the two is that dorun +throws away all results and is supposed to be used for side effects, +while doall returns computed values:

(dorun (map inc [1 2 3 4]))
+
(doall (map inc [1 2 3 4]))
+

Commonly Used Functions That Produce Lazy Sequences

Multiple frequently used clojure.core functions return lazy sequences, +most notably:

  • map
  • filter
  • remove
  • range
  • take
  • take-while
  • drop
  • drop-while

The following example uses several of these functions to return 10 first +even numbers in the range of [0, n):

(take 10 (filter even? (range 0 100)))
+

Several functions in clojure.core are designed to produce lazy +sequences:

  • repeat
  • iterate
  • cycle

For example:

(take 3 (repeat "ha"))
+
(take 5 (repeat "ha"))
+
(take 3 (cycle [1 2 3 4 5]))
+
(take 10 (cycle [1 2 3 4 5]))
+
(take 3 (iterate (partial + 1) 1))
+
(take 5 (iterate (partial + 1) 1))
+

Lazy Sequences Chunking

There are two fundamental strategies for implementing lazy sequences:

  • Realize elements one-by-one
  • Realize elements in groups (chunks, batches)

In Clojure 1.1+, lazy sequences are chunked (realized in chunks).

For example, in the following code

(take 10 (range 1 1000000000000))
+

one-by-one realization would realize one element 10 times. With chunked sequences, +elements are realized ahead of time in chunks (32 elements at a time).

This reduces the number of realizations and, for many common workloads, improves +efficiency of lazy sequences.

Contributors

Michael Klishin michael@defprotocol.org, 2013 (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/macros/index.html b/clones/clojure-doc.org/articles/language/macros/index.html new file mode 100644 index 00000000..d3c7d8c4 --- /dev/null +++ b/clones/clojure-doc.org/articles/language/macros/index.html @@ -0,0 +1,382 @@ + + + + + Clojure Guides: Clojure Macros and Metaprogramming + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • Clojure macros
  • the Clojure compilation process

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Before You Read This Guide

This is one of the most hardcore guides of the entire Clojure documentation +project. It describes concepts that are relatively unique to the Lisp family of languages +that Clojure belongs to. Understanding them may take some time for folks without +a metaprogramming background. Don't let this learning curve +discourage you.

If some parts are not clear, please ask for clarification on the +mailing +list or +file an issue on GitHub. +We will work hard on making this guide easy to follow with edits and +images to illustrate the concepts.

Overview

Clojure is a dialect of Lisp and while it departs with some features of "traditional" Lisps, +the fundamentals are there. One very powerful feature that comes with it is macros, +a way to do metaprogramming using the language itself. This is pretty different from +other languages known for good metaprogramming capabilities (e.g. Ruby) in that +in Clojure, metaprogramming does not mean string generation. Instead, it means +constructing a tree [of S-expressions, or lists]. This enables very powerful +DSLs (domain-specific languages).

Compile Time and Run Time

Clojure is a compiled language. The compiler reads source files or strings, +produces data structures (aka the AST) and performs macroexpansion. Macros are evaluated at +compile time and produce modified data structures that are compiled to the JVM +bytecode. That bytecode is executed at run time.

Clojure code is compiled when it is loaded with clojure.core/load or clojure.core/require +or can be ahead of time (AOT compilation) using tools such as Leiningen +or the Clojure Maven plugin.

Clojure Reader

Reader is another name for parser. Unlike many other languages, reader in Clojure +can be extended in the language itself. It is also exposed to the language +with clojure.core/read and clojure.core/read-string functions that +return data structures:


+(require '[cljs.reader :refer [read-string]])
+
(read-string "(if true :truth :false)")
+;= (if true :truth :false)
+

Here we got back a list that is not evaluated.

The Reader produces data structures (in part that's why "code is data" in homoiconic +languages) that are then evaluated:

  • Literals (e.g., strings, integers, vectors) evaluate to themselves
  • Lists evaluate to invocations (calls) of functions and so on
  • Symbols are resolved to a var value

Expressions that can be evaluated (invoked) are known as forms. Forms consist of:

  • Functions
  • Macros
  • Special forms

Special Forms

The reader parses some forms in special ways that are not consistent +with the rest of Clojure's syntax.

Such forms are called special forms. They consist of

  • . (the dot special form)
  • new
  • set!
  • def
  • var
  • fn* (fn without destructuring)
  • if
  • case* (internal implementation of case)
  • do
  • let* (let without destructuring)
  • letfn* (letfn without destructuring)
  • clojure.core/import* (import)
  • quote
  • loop* (loop without destructuring)
  • recur
  • throw, try, catch, finally
  • deftype* (internals of deftype)
  • reify* (internals of reify)
  • monitor-enter, monitor-exit

Some special forms are used directly in user code (like do and if), while others +are only used to build more user friendly interfaces (like using deftype over the special form deftype*).

First Taste of Macros

Some programming languages include an unless expression (or statement) that is +the opposite of if. Clojure is not one of them but it can be added by using +a macro:


+(require '[chivorcam.core :refer [defmacro defmacfn]])
+
(defmacro unless
+  "Similar to if but negates the condition"
+  [condition & forms]
+  `(if (not ~condition)
+     ~@forms))
+

Macros are defined using the clojure.core/defmacro function that takes +macro name as a symbol, an optional documentation string, a vector +of arguments and the macro body.

This macro can be used like similarly to the if form:

(unless (= 1 2)
+  "one does not equal two"
+  "one equals two. How come?")
+

Just like the if special form, this macro produces an expression that +returns a value:

(unless (= 1 2)
+  "one does not equal two"
+  "one equals two. How come?")
+

in fact, this is because the macro piggybacks on the if form. +To see what the macro expands to, we can use clojure.core/macroexpand-1:

(macroexpand-1 '(unless (= 1 2) true false))
+;= (if (clojure.core/not (= 1 2)) true false)
+

This simplistic macro and the way we expanded it with macroexpand-1 +demonstrates three features of the Clojure reader that are used when +writing macros:

  • Quote (')
  • Syntax quote (`)
  • Unquote (~)
  • Unquote splicing (~@)

Quote

Quote supresses evaluation of the form that follows it. In other words, +instead of being treated as an invocation, it will be treated as a list.

Compare:

;; this form is evaluated by calling the clojure.core/+ function
+(+ 1 2 3)
+;= 6
+
;; quote supresses evaluation so the + is treated as a regular
+;; list element
+'(+ 1 2 3)
+;= (+ 1 2 3)
+

The syntax quote supresses evaluation of the form that follows it and +all nested forms. It is similar to templating languages where parts +of the template are "fixed" and parts are "inserted" (evaluated). +The syntax quote makes the form that follows it "a template".

Unquote

Unquote then is how parts of the template are forced to be evaluated +(act similarly to variables in templates in templating languages).

Let's take another look at the same unless macro:

(defmacro unless
+  [condition & forms]
+  `(if (not ~condition)
+     ~@forms))
+

and how we invoke it:

(unless (= 1 2)
+  "one does not equal two"
+  "one equals two. How come?")
+

When the macro is expanded, the condition local in this example has the value +of (= 1 2) (a list). We want unless to perform boolean evaluation on it, +and that's what unquote (~) does as can be seen from macroexpansion:

(macroexpand-1 '(unless (= 1 2) true false))
+;= (if (clojure.core/not (= 1 2)) true false)
+

Compare this with what the macro expands to when the unquote is removed:

;; incorrect, missing unquote!
+(defmacro unless
+  [condition & forms]
+  `(if (not condition)
+     ~@forms))
+
+(macroexpand-1 '(unless (= 1 2) true false))
+;= (if (clojure.core/not user/condition) true false)
+

Implementation Details

The unquote operator is replaced by the reader with a call to a core +Clojure function, clojure.core/unquote.

Unquote-splicing

Some macros take multiple forms. This is common in DSLs, for example. +Each of those forms is often need to be quoted and concatenated.

The unquote-splicing operator (~@) is a convenient way to do it:

(defmacro unsplice
+        [& coll]
+        `(do ~@coll))
+
(macroexpand-1 '(unsplice (def a 1) (def b 2)))
+;= (do (def a 1) (def b 2))
+
(unsplice (def a 1) (def b 2))
+;= #'user/b
+
a
+;= 1
+
b
+;= 2
+

Implementation Details

The unquote-splicing operator is replaced by the reader with a call to a core +Clojure function, clojure.core/unquote-splicing.

Macro Hygiene and gensym

When writing a macro, there is a possibility that the macro will interact with +vars or locals outside of it in unexpected ways, for example, by shadowing them. +Such macros are known as unhygienic macros.

Clojure does not implement a full solution to hygienic macros but +provides solutions to the biggest pitfalls of unhygienic macros by enforcing several restrictions:

  • Symbols within a syntax quoted form are namespace-qualified
  • Unique symbol name generation (aka gensyms)

Namespace Qualification Within Syntax Quote

To demonstrate this behavior of syntax quote, consider the following example +that replaces values "yes" and "no" with true and false, respectively, at compile +time:

(defmacro yes-no->boolean
+  [val]
+  `(let [b (= ~val "yes")]
+    b))
+;= #'user/yes-no->boolean
+
(macroexpand-1 '(yes-no->boolean "yes"))
+;= (clojure.core/let [user/b (clojure.core/= "yes" "yes")] user/b)
+

Macroexpansion demonstrates that the Clojure compiler makes the b symbol namespace-qualified +(user is the default namespace in the Clojure REPL). This helps avoid var and local +shadowing.

Note: Special forms are not necessarily qualified. See section 'Special Forms in Detail'.

Generated Symbols (gensyms)

Automatic namespace generation is fine in some cases, but not every time. Sometimes +a symbol name that is unique in the macro scope is necessary.

Unique symbols names can be generated with the clojure.core/gensym function that +take an optional base string:

(gensym)
+;= G__54
+
(gensym "base")
+;= base57
+

There is a shortcut: if a symbol ends in # within a syntax quote form, it will be +expanded by the compiler into a gensym (aka. an auto-gensym):

(defmacro yes-no->boolean
+  [val]
+  `(let [b# (= ~val "yes")]
+     b#))
+;= #'user/yes-no->boolean
+
(macroexpand-1 '(yes-no->boolean "yes"))
+;= (clojure.core/let [b__148__auto__ (clojure.core/= "yes" "yes")] b__148__auto__)
+

The name that replaced b# was generated by the compiler to make unwanted variable +capture very unlikely in practice, and impossible if all bindings are named with auto-gensym.

Theoretically, Clojure's approach to generating uncaptured gensyms (incrementing a global counter) can be circumvented +via a mischievous macro or very bad luck.

Tip: +Avoid code with __ in local binding names. This ensures +auto-gensyms are never captured in unwanted ways.

Macroexpansions

During macro development, it is important to be able to test the macro +and see what data structures the macro expands to. This can be done +with two functions in the core Clojure library:

  • clojure.core/macroexpand-1
  • clojure.core/macroexpand
  • clojure.walk/macroexpand-all

The difference between the two is that macroexpand-1 will expand the macro +only once. If the result contains calls to other macros, those won't be expanded. +macroexpand, however, will continue expanding all macros until the top level form +is no longer a macro.

Both macroexpansion functions take quoted forms.

Macro expansion functions can be used to find out that when is a macro implemented on top of +the if special form, for example:

(macroexpand '(when true 1 42))
+

Full Macroexpansion

Neither macroexpand-1 nor macroexpand expand nested +forms. To fully expand macros including those in nested forms, there is clojure.walk/macroexpand-all, +which, however, is not part of Clojure core and does not behave exactly the same way +the compiler does.

Difference Between Quote and Syntax Quote

The key difference between quote and syntax quote is that +symbols within a syntax quoted form are automatically namespace-qualified.

Security Considerations

clojure.core/read-string can execute arbitrary code and must not be used +on inputs coming from untrusted sources. This behavior is controlled by the clojure.core/*read-eval* +var. Starting with Clojure 1.5, the default value of *read-eval* is false.

*read-eval* can be disabled via a property when starting the JVM:

-Dclojure.read.eval=false
+

When reading Clojure forms from untrusted sources, use clojure.edn/read-string, which is +does not perform arbitrary code execution and is safer. clojure.edn/read-string implements +the EDN format, a subset of Clojure syntax for data +structures. clojure.edn was introduced in Clojure 1.5.

Special Forms in Detail

Special forms are restrictive in their use and do not interact cleanly with several area of Clojure.

  • Special forms must be a list with a special name as the first element.

    A special name in a higher-order context is not a special form.

    do
    +;; CompilerException java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(NO_SOURCE_PATH:0:0)
    +

    Macros have a similar restriction, but notice: the macro's var is identified in the error while +special names have no meaning at all outside the first element of a list.

    dosync
    +;; CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/dosync, compiling:(NO_SOURCE_PATH:0:0)
    +
  • Special form names are not namespace-qualified.

    Most special forms (all except clojure.core/import*) are not namespace +qualified. The reader must circumvent syntax quote's policy of namespace-qualifying +all symbols.

    `a
    +;; user/a
    +
    `do
    +;; do
    +
    user=> `if
    +if
    +user=> `import*
    +user/import*
    +
  • Special forms conflict with local scope.

    Never use special names as local binding or global variable names.

    (let [do 1] do)
    +;;; nil
    +

    Ouch!

    This includes destructuring:

    user=> (let [{:keys [do]} {:do 1}] do)
    +nil
    +

    Note: Be wary of maps with keyword keys with special names, they are more +likely to be destructured this way.

Keep these special cases in mind as you work through the tutorial.

Contributors

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/namespaces/index.html b/clones/clojure-doc.org/articles/language/namespaces/index.html new file mode 100644 index 00000000..f28a4588 --- /dev/null +++ b/clones/clojure-doc.org/articles/language/namespaces/index.html @@ -0,0 +1,375 @@ + + + + + Clojure Guides: Clojure Namespaces and Vars + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • An overview of Clojure namespaces and vars
  • How to define namespaces
  • How to use functions in other namespaces
  • require, refer and use
  • Common compilation errors and typical problems that cause them
  • Namespaces and their relation to code compilation in Clojure

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Overview

Clojure functions are organized into namespaces. Clojure namespaces +are very similar to Java packages and Python modules. Namespaces are +basically maps (dictionaries) that map names to vars. In many cases, +those vars store functions in them.

Defining a Namespace

Namespaces are usually defined using the clojure.core/ns macro. In its basic +form, it takes a name as a symbol:

(ns superlib.core)
+

Namespaces can have multiple segments, separated by a dot:

(ns megacorp.service.core)
+

It is highly recommended to avoid using single segment namespaces +(e.g. superlib) to avoid inconvenient conflicts other developers +will have to work around. If a library or application belongs to an +organization or a group of projects, the +[organization].[library|app].[group-of-functions] pattern is +recommended. For example:

(ns clojurewerkz.welle.kv)
+
+(ns megacorp.search.indexer.core)
+

In addition, the ns macro takes a number of optional forms:

  • (:require ...)
  • (:import ...)
  • (:use ...)
  • (:refer-clojure ...)
  • (:gen-class ...)

These are just slightly more concise variants of clojure.core/import, clojure.core/require, et cetera.

The :require Helper Form

The :require helper form is for setting up access to other Clojure +namespaces from your code. For example:

(ns megacorp.profitd.scheduling
+  (:require clojure.set))
+
+;; Now it is possible to do:
+;; (clojure.set/difference #{1 2 3} #{3 4 5})
+

This will make sure the clojure.set namespace is loaded, compiled, and available as clojure.set +(using its fully qualified name). It is possible (and common) to make a namespace available +under an alias:

(ns megacorp.profitd.scheduling
+  (:require [clojure.set :as cs]))
+
+;; Now it is possible to do:
+;; (cs/difference #{1 2 3} #{3 4 5})
+

One more example with two required namespaces:

(ns megacorp.profitd.scheduling
+  (:require [clojure.set  :as cs]
+            [clojure.walk :as walk]))
+

The :refer Option

To make functions in clojure.set available in the defined namespace via short names +(i.e., their unqualified names, without the clojure.set or other prefix), you can tell Clojure compiler +to refer to certain functions:

(ns megacorp.profitd.scheduling
+  (:require [clojure.set :refer [difference intersection]]))
+
+;; Now it is possible to do:
+;; (difference #{1 2 3} #{3 4 5})
+

The :refer feature of the :require form is new in Clojure 1.4.

It is possible to refer to all functions in a namespace (usually not necessary):

(ns megacorp.profitd.scheduling
+  (:require [clojure.set :refer :all]))
+
+;; Now it is possible to do:
+;; (difference #{1 2 3} #{3 4 5})
+

The :import Helper Form

The :import helper form is for setting up access to Java classes +from your Clojure code. For example:

(ns megacorp.profitd.scheduling
+  (:import java.util.concurrent.Executors))
+

This will make sure the java.util.concurrent.Executors class is imported and can be used by its short +name, Executors. It is possible to import multiple classes:

(ns megacorp.profitd.scheduling
+  (:import java.util.concurrent.Executors
+           java.util.concurrent.TimeUnit
+           java.util.Date))
+

If multiple imported classes are in the same namespace (like in the example above), +it is possible to avoid some duplication by using an import list. The first element +of an import list is the package and other elements are class names in that package:

(ns megacorp.profitd.scheduling
+  (:import [java.util.concurrent Executors TimeUnit]
+           java.util.Date))
+

Even though import list is called a list, it can be any Clojure collection (typically +vectors are used).

The Current Namespace

Under the hood, Clojure keeps current namespace a special var, *ns*. +When vars are defined using the def special form, they are +added to the current namespace.

The :refer-clojure Helper Form

Functions like clojure.core/get and macros like clojure.core/defn can be used without +namespace qualification because they reside in the clojure.core namespace and Clojure +compiler automatically refers all vars in it. Therefore, if your +namespace defines a function with the same name (e.g. find), you will get a warning +from the compiler, like this:

WARNING: find already refers to: #'clojure.core/find in namespace: megacorp.profitd.scheduling, being replaced by: #'megacorp.profitd.scheduling/find
+

This means that in the megacorp.profitd.scheduling namespace, find already refers to +a value which happens to be clojure.core/find, but it is being replaced by a +different value. Remember, Clojure is a very dynamic language and namespaces are +basically maps, as far as the implementation goes. Most of the time, however, +replacing vars like this is not intentional and Clojure compiler emits a warning.

To solve this problem, you can either rename your function, or else +exclude certain clojure.core functions from being +referred using the (:refer-clojure ...) form within the ns:

(ns megacorp.profitd.scheduling
+  (:refer-clojure :exclude [find]))
+
+(defn find
+  "Finds a needle in the haystack."
+  [^String haystack]
+  (comment ...))
+

In this case, to use clojure.core/find, you will have to use its fully +qualified name: clojure.core/find:

(ns megacorp.profitd.scheduling
+  (:refer-clojure :exclude [find]))
+
+(defn find
+  "Finds a needle in the haystack."
+  [^String haystack]
+  (clojure.core/find haystack :needle))
+

The :use Helper Form

In Clojure versions before 1.4, there was no :refer support for the +(:require ...) form. Instead, a separate form was used: (:use ...):

(ns megacorp.profitd.scheduling-test
+  (:use clojure.test))
+

In the example above, all functions in clojure.test are made available +in the current namespace. This practice (known as "naked use") works for clojure.test in +test namespaces, but in general not a good idea. (:use ...) supports limiting +functions that will be referred:

(ns megacorp.profitd.scheduling-test
+  (:use clojure.test :only [deftest testing is]))
+

which is a pre-1.4 alternative of

(ns megacorp.profitd.scheduling-test
+  (:require clojure.test :refer [deftest testing is]))
+

It is highly recommended to use (:require ...) (optionally with ... :refer [...]) on Clojure 1.4 +and later releases. (:use ...) is a thing of the past and now that +(:require ...) with :refer is capable of doing the same thing when you +need it, it is a good idea to let (:use ...) go.

The :gen-class Helper Form

TBD: How to Contribute

Documentation and Metadata

Namespaces can have documentation strings. You can add one with the optional +ns macro parameter:

(ns superlib.core
+  "Core functionality of Superlib.
+
+   Other parts of Superlib depend on functions and macros in this namespace."
+  (:require [clojure.set :refer [union difference]]))
+

or metadata:

(ns ^{:doc "Core functionality of Superlib.
+            Other parts of Superlib depend on functions and macros in this namespace."
+      :author "Joe Smith"}
+   superlib.core
+  (:require [clojure.set :refer [union difference]]))
+

Metadata can contain any additional keys such as :author which may be of use to various tools +(such as Codox, Cadastre, or lein-clojuredocs).

How to Use Functions From Other Namespaces in the REPL

The ns macro is how you usually require functions from other namespaces. +However, it is not very convenient in the REPL. For that case, the clojure.core/require function +can be used directly:

;; Will be available as clojure.set, e.g. clojure.set/difference.
+(require 'clojure.set)
+
+;; Will be available as io, e.g. io/resource.
+(require '[clojure.java.io :as io])
+

It takes a quoted libspec. The libspec is either a namespace name or +a collection (typically a vector) of [name :as alias] or [name :refer [fns]]:

(require '[clojure.set :refer [difference]])
+
+(difference #{1 2 3} #{3 4 5 6})  ; โ‡’ #{1 2}
+

The :as and :refer options can be used together:

(require '[clojure.set :as cs :refer [difference]])
+
+(difference #{1 2 3} #{3 4 5 6})  ; โ‡’ #{1 2}
+(cs/union #{1 2 3} #{3 4 5 6})    ; โ‡’ #{1 2 3 4 5 6}
+

clojure.core/use does the same thing as clojure.core/require but with the +:refer option (as discussed above). It is not generally recommended to use use with Clojure +versions starting with 1.4. Use clojure.core/require with :refer +instead.

Namespaces and Class Generation

TBD: How to Contribute

Namespaces and Code Compilation in Clojure

Clojure is a compiled language: code is compiled when it is loaded (usually with clojure.core/require).

A namespace can contain vars or be used purely to extend protocols, add multimethod implementations, +or conditionally load other libraries (e.g. the most suitable JSON parser or key/value store implementation). +In all cases, to trigger compilation, you need to require the namespace.

Private Vars

Vars (and, in turn, functions defined with defn) can be private. There are two equivalent ways to +specify that a function is private: either via metadata or by using the defn- macro:

(ns megacorp.superlib)
+
+;;
+;; Implementation
+;;
+
+(def ^{:private true}
+  source-name "supersource")
+
+(defn- data-stream
+  [source]
+  (comment ...))
+

Constant Vars

Vars can be constant. This is done by setting the :const metadata key to true. This +will cause Clojure compiler to compile it as a constant:

(ns megacorp.epicgame)
+
+;;
+;; Implementation
+;;
+
+(def ^{:const true}
+  default-score 100)
+

How to Look up and Invoke a Function by Name

It is possible to look up a function in particular namespace by-name with clojure.core/ns-resolve. This takes +quoted names of the namespace and function. The returned value can be used just like any other +function, for example, passed as an argument to a higher order function:

(ns-resolve 'clojure.set 'difference)  ; โ‡’ #'clojure.set/difference
+
+(let [f (ns-resolve 'clojure.set 'difference)]
+   (f #{1 2 3} #{3 4 5 6}))  ; โ‡’ #{1 2}
+

Compiler Exceptions

This section describes some common compilation errors.

ClassNotFoundException

This exception means that JVM could not load a class. It is either misspelled or not on the +classpath. +Potentially your project has unsatisfied dependency (some dependencies may be optional).

Example:

user=> (import java.uyil.concurrent.TimeUnit)
+ClassNotFoundException java.uyil.concurrent.TimeUnit  java.net.URLClassLoader$1.run (URLClassLoader.java:366)
+

In the example above, java.uyil.concurrent.TimeUnit should have been java.util.concurrent.TimeUnit.

CompilerException java.lang.RuntimeException: No such var

This means that somewhere in the code a non-existent var is used. It may be a typo, an +incorrect macro-generated var name or a similar issue. Example:

user=> (clojure.java.io/resouce "thought_leaders_quotes.csv")
+CompilerException java.lang.RuntimeException: No such var: clojure.java.io/resouce, compiling:(NO_SOURCE_PATH:1)
+

In the example above, clojure.java.io/resouce should have been clojure.java.io/resource. NO_SOURCE_PATH +means that compilation was triggered from the REPL and not a Clojure source file.

Temporarily Overriding Vars in Namespaces

TBD: How to Contribute

Getting Information About and Programmatically Manipulating Namespaces

TBD: How to Contribute

Wrapping Up

Namespaces are basically maps (dictionaries) that map names to +vars. In many cases, those vars store functions in them.

This implementation lets Clojure have many of its highly dynamic +features at a very reasonable runtime overhead cost. For example, vars +in namespaces can be temporarily altered for unit testing purposes.

Contributors

Michael Klishin michael@defprotocol.org (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/language/polymorphism/index.html b/clones/clojure-doc.org/articles/language/polymorphism/index.html new file mode 100644 index 00000000..93c7a7eb --- /dev/null +++ b/clones/clojure-doc.org/articles/language/polymorphism/index.html @@ -0,0 +1,385 @@ + + + + + Clojure Guides: Polymorphism in Clojure: Protocols and Multimethods + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • What are polymorphic functions
  • Type-based polymorphism with protocols
  • Ad-hoc polymorphism with multimethods
  • How to create your own data types that behave like core Clojure data types

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5.

Overview

According to Wikipedia,

In computer science, polymorphism is a programming language feature that allows values of different data types to be handled using a uniform interface.

Polymorphism is not at all unique to object-oriented programming languages. Clojure has excellent support for +polymorphism.

For example, when a function can be used on multiple data types or behave differently based on additional argument +(often called dispatch value), that function is polymorphic. A simple example of such function is a function that +serializes its input to JSON (or other format).

Ideally, developers would like to use the same function regardless of the input, and be able to extend +it to new inputs, without having to change the original source. Inability to do so is known as the Expression Problem.

In Clojure, there are two approaches to polymorphism:

  • Data type-oriented. More efficient (modern JVMs optimize this case very well), less flexible.
  • So called "ad-hoc polymorphism" where the exact function implementation is picked at runtime based on a special argument (dispatch value).

The former is implemented using protocols, a feature first introduced in Clojure 1.2. The latter is available via +multimethods, a feature that was around in Clojure since the early days.

Type-based Polymorphism With Protocols

It is common for polymorphic functions to dispatch (pick implementation) on the type of the first argument. For example, +in Java or Ruby, when calling #toString or #to_s on an object, the exact implementation is located using that object's +type.

Because this is a common case and because JVM can optimize this dispatch logic very well, Clojure 1.2 introduced a new +feature called protocols. Protocols are simply groups of functions. Each of the functions can have different +implementations for different data types.

Protocols are defined using the clojure.core/defprotocol special form. The example below defines a protocol for working with URLs and URIs. +While URLs and URIs are not the same thing, some operations make sense for both:

(defprotocol URLLike
+  "Unifies operations on URLs and URIs"
+  (^String protocol-of  [input] "Returns protocol of given input")
+  (^String host-of      [input] "Returns host of given input")
+  (^String port-of      [input] "Returns port of given input")
+  (^String user-info-of [input] "Returns user information of given input")
+  (^String path-of      [input] "Returns path of given input")
+  (^String query-of     [input] "Returns query string of given input")
+  (^String fragment-of  [input] "Returns fragment of given input"))
+

clojure.core/defprotocol takes the name of the protocol and one or more lists of +function name, argument list, documentation string:

(^String protocol-of  [input] "Returns protocol of given input")
+(^String host-of      [input] "Returns host of given input")
+

The example above uses return type hints. This makes sense in the example but is not necessary. It could have been written +it as

(defprotocol URLLike
+  "Unifies operations on URLs and URIs"
+  (protocol-of  [input] "Returns protocol of given input")
+  (host-of      [input] "Returns hostname of given input")
+  (port-of      [input] "Returns port of given input")
+  (user-info-of [input] "Returns user information (username:password) of given input")
+  (path-of      [input] "Returns path of given input")
+  (query-of     [input] "Returns query string of given input")
+  (fragment-of  [input] "Returns fragment of given input"))
+

There are 3 ways URIs and URLs are commonly represented on the JVM:

  • java.net.URI instances
  • java.net.URL instances
  • Strings

When a new protocol imlementation is added for a type, it is called extending the protocol. The most common way to extend +a protocol is via the clojure.core/extend-protocol:

(import java.net.URI)
+(import java.net.URL)
+
+(extend-protocol URLLike
+  URI
+  (protocol-of [^URI input]
+    (when-let [s (.getScheme input)]
+      (.toLowerCase s)))
+  (host-of [^URI input]
+    (-> input .getHost .toLowerCase))
+  (port-of [^URI input]
+    (.getPort input))
+  (user-info-of [^URI input]
+    (.getUserInfo input))
+  (path-of [^URI input]
+    (.getPath input))
+  (query-of [^URI input]
+    (.getQuery input))
+  (fragment-of [^URI input]
+    (.getFragment input))
+
+  URL
+  (protocol-of [^URL input]
+    (protocol-of (.toURI input)))
+  (host-of [^URL input]
+    (host-of (.toURI input)))
+  (port-of [^URL input]
+    (.getPort input))
+  (user-info-of [^URL input]
+    (.getUserInfo input))
+  (path-of [^URL input]
+    (.getPath input))
+  (query-of [^URL input]
+    (.getQuery input))
+  (fragment-of [^URL input]
+    (.getRef input)))
+

Protocol functions are used just like regular Clojure functions:

(protocol-of (URI. "https://clojure-doc.github.io")) ;= "http"
+(protocol-of (URL. "https://clojure-doc.github.io")) ;= "http"
+
+(path-of (URL. "https://clojure-doc.github.io/articles/content.html")) ;= "/articles/content/"
+(path-of (URI. "https://clojure-doc.github.io/articles/content.html")) ;= "/articles/content/"
+

Using Protocols From Different Namespaces

Protocol functions are required and used the same way as regular protocol functions. Consider a +namespace that looks like this

(ns superlib.url-like
+  (:import [java.net URL URI]))
+
+(defprotocol URLLike
+  "Unifies operations on URLs and URIs"
+  (^String protocol-of  [input] "Returns protocol of given input")
+  (^String host-of      [input] "Returns host of given input")
+  (^String port-of      [input] "Returns port of given input")
+  (^String user-info-of [input] "Returns user information of given input")
+  (^String path-of      [input] "Returns path of given input")
+  (^String query-of     [input] "Returns query string of given input")
+  (^String fragment-of  [input] "Returns fragment of given input"))
+
+(extend-protocol URLLike
+  URI
+  (protocol-of [^URI input]
+    (when-let [s (.getScheme input)]
+      (.toLowerCase s)))
+  (host-of [^URI input]
+    (-> input .getHost .toLowerCase))
+  (port-of [^URI input]
+    (.getPort input))
+  (user-info-of [^URI input]
+    (.getUserInfo input))
+  (path-of [^URI input]
+    (.getPath input))
+  (query-of [^URI input]
+    (.getQuery input))
+  (fragment-of [^URI input]
+    (.getFragment input))
+
+  URL
+  (protocol-of [^URL input]
+    (protocol-of (.toURI input)))
+  (host-of [^URL input]
+    (host-of (.toURI input)))
+  (port-of [^URL input]
+    (.getPort input))
+  (user-info-of [^URL input]
+    (.getUserInfo input))
+  (path-of [^URL input]
+    (.getPath input))
+  (query-of [^URL input]
+    (.getQuery input))
+  (fragment-of [^URL input]
+    (.getRef input)))
+

To use superlib.url-like/path-of and other functions, you require them as regular functions:

(ns myapp
+  (:require [superlib.url-like] :refer [host-of scheme-of]))
+
+(host-of (java.net.URI. "https://twitter.com/cnn/"))
+

Extending Protocols For Core Clojure Data Types

TBD

Protocols and Custom Data Types

TBD: cover extend-type, extend

Partial Implementation of Protocols

With protocols, it is possible to only implement certain functions for certain types.

Ad-hoc Polymorphism with Multimethods

First Example: Shapes

Lets start with a simple problem definition. We have 3 shapes: square, circle and triangle, and +need to provide an polymorphic function that calculates the area of the given shape.

In total, we need 4 functions:

  • A function that calculates area of a square
  • A function that calculates area of a circle
  • A function that calculates area of a triangle
  • A polymorphic function that acts as a "unified frontend" to the functions above

we will start with the latter and define a multimethod (not related to methods on Java objects or object-oriented programming):

(defmulti area (fn [shape & _]
+                 shape))
+

Our multimethod has a name and a dispatch function that takes arguments passed to the multimethod and returns +a value. The returned value will define what implementation of multimethod is used. In Java or Ruby, method implementation +is picked by traversing the class hierarchy. With multimethods, the logic can be anything you need. That's why it is +called ad-hoc polymorphism.

An alternative way of doing the same thing is to pass clojure.core/first instead of an anonymous function:

(defmulti area first)
+

Next lets implement our area multimethod for squares:

(defmethod area :square
+  [_ side]
+  (* side side))
+

Here defmethod defines a particular implementation of the multimethod area, the one that will be used if dispatch function +returns :square. Lets try it out. Multimethods are invoked like regular Clojure functions:

(area :square 4)
+;= 16
+

In this case, we pass dispatch value as the first argument, our dispatch function returns it unmodified and +that's how the exact implementation is looked up.

Implementation for circles looks very similar, we choose :circle as a reasonable dispatch value:

(defmethod area :circle
+  [_ radius]
+  (* radius radius Math/PI))
+
+(area :circle 3)
+;= 28.274333882308138
+

For the record, Math/PI in this example refers to java.lang.Math/PI, a field that stores the value of Pi.

Finally, an implementation for triangles. Here you can see that exact implementations can take different number of +arguments. To calculate the area of a triangle, we multiple base by height and divide it by 2:

(defmethod area :triangle
+  [_ b h]
+  (* 1/2 b h))
+
+(area :triangle 3 5)
+;= 15/2
+

In this example we used Clojure ratio data type. We could have used doubles as well.

Putting it all together:

(defmulti area (fn [shape & _]
+                 shape))
+
+(defmethod area :square
+  [_ side]
+  (* side side))
+
+(defmethod area :circle
+  [_ radius]
+  (* radius radius Math/PI))
+
+(defmethod area :triangle
+  [_ b h]
+  (* 1/2 b h))
+
(area :square 4)
+;= 16
+
(area :circle 3)
+;= 28.274333882308138
+
(area :triangle 3 5)
+;= 15/2
+

Second Example: TBD

TBD: an example that demonstrates deriving

How To Create Custom Data Type That Core Functions Can Work With

TBD: How to Contribute

Wrapping Up

TBD: How to Contribute

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/basic_web_development/index.html b/clones/clojure-doc.org/articles/tutorials/basic_web_development/index.html new file mode 100644 index 00000000..77c64c88 --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/basic_web_development/index.html @@ -0,0 +1,476 @@ + + + + + Clojure Guides: Basic Web Development + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers building a simple web-application using common +Clojure libraries. When you're done working through it, you'll have a +little webapp that displays some (x, y) locations from a database, +letting you add more locations as well.

It's assumed that you're already somewhat familiar with Clojure. If +not, see the Getting Started and +Introduction guides.

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

This guide uses Clojure 1.5, as well as current versions of the +component libraries noted below.

Conceptual Overview of Components

We'll use four major components (briefly described below) for our +little webapp:

  • Ring
  • Compojure
  • Hiccup
  • H2

Ring

Ring (at +clojars) is a foundational Clojure web +application library. It:

  • sets things up such that an http request comes into your webapp +as a regular Clojure hashmap, and likewise makes it so that you +can return a response as a hashmap.
  • provides a +spec +describing exactly what those request and response maps should +look like.
  • brings along a web server +(Jetty) and connects your +webapp to it.

For this tutorial, we won't actually need to deal with these maps +by-hand, as you'll soon see.

For more info, see:

Compojure

If we were using only Ring, we'd have to write one single function to +take that incoming request map and then delegate to various functions +depending upon which page was requested. +Compojure (at +clojars) provides some handy features +to take care of this for us such that we can associate url paths with +corresponding functions, all in one place.

For more info, see:

Hiccup

Hiccup (at +clojars) provides a quick and easy way to +generate html. It converts regular Clojure data structures right into +html. For example,

[:p "Hello, " [:i "doctor"] " Jones."]
+

becomes

<p>Hello, <i>doctor</i> Jones.</p>
+

but it also does two extra handy bits of magic:

  • it provides some CSS-like shortcuts for specifying id and class, +and

  • it automatically unpacks seqs for you, for example:

    [:p '("a" "b" "c")]
    +;; expands to (and so, is the same as if you wrote)
    +[:p "a" "b" "c"]
    +

For more info, see:

H2

H2 is a small and fast Java SQL +database that could be embedded in your application or run in server +mode. Uses single file for storage, but also could be run as in-memory DB.

Another similar Java-based embedded DB that could be used in your +application is Apache Derby.

Create and set up your project

Create your new webapp project like so:

lein new compojure my-webapp
+cd my-webapp
+

Add the following extra dependencies to your project.clj's +:dependencies vector:

[hiccup "1.0.5"]
+[org.clojure/java.jdbc "0.6.0"]
+[com.h2database/h2 "1.4.193"]
+

(You might also remove the -SNAPSHOT from the project's version +string.)

Add some styling

mkdir -p resources/public/css
+touch resources/public/css/styles.css
+

and put into that file something like:

body {
+    background-color: Cornsilk;
+}
+
+#header-links {
+    background-color: BurlyWood;
+    padding: 10px;
+}
+
+h1 {
+    color: CornflowerBlue;
+}
+

Set up your database

A file with DB would be automatically created when you connect to it for the +first time, so all necessary DB preparations could be done programmatically +using the REPL (with help of clojure.java.jdbc):

lein repl
+

Execute the following code to create a new my-webapp.h2.db database file in db +subdirectory of your project, create a table we'll use for our webapp, and add +one record to start us off with:

(require '[clojure.java.jdbc :as jdbc])
+(jdbc/with-db-connection [conn {:dbtype "h2" :dbname "./my-webapp"}]
+
+  (jdbc/db-do-commands conn
+    (jdbc/create-table-ddl :locations
+      [[:id "bigint primary key auto_increment"]
+       [:x "integer"]
+       [:y "integer"]]))
+
+  (jdbc/insert! conn :locations
+    {:x 8 :y 9}))
+

and hit ctrl-d to exit.

For more about how to use the database functions, see the +Using java.jdbc on this site.

Set up your routes

In the default src/my_webapp/handler.clj file you're provided, we +specify our webapp's routes inside the defroutes macro. That is, +we assign a function to handle each of the url paths we'd like to +support, and then at the end provide a "not found" page for any other +url paths.

Make your handler.clj file look like this:

(ns my-webapp.handler
+  (:require [my-webapp.views :as views] ; add this require
+            [compojure.core :refer :all]
+            [compojure.route :as route]
+            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))
+
+(defroutes app-routes ; replace the generated app-routes with this
+  (GET "/"
+       []
+       (views/home-page))
+  (GET "/add-location"
+       []
+       (views/add-location-page))
+  (POST "/add-location"
+        {params :params}
+        (views/add-location-results-page params))
+  (GET "/location/:loc-id"
+       [loc-id]
+       (views/location-page loc-id))
+  (GET "/all-locations"
+       []
+       (views/all-locations-page))
+  (route/resources "/")
+  (route/not-found "Not Found"))
+
+(def app
+  (wrap-defaults app-routes site-defaults))
+

Each of those expressions in defroutes like (GET ...) or (POST ...) are +so-called "routes". They each evaluate to a function that +takes a ring request hashmap and returns a response hashmap. Your +views/foo function's job is to return that response hashmap, but note +that Compojure is kind enough to make a suitable response map out of +any html you return.

So, all you actually need to do now is write your views functions to +return some html.

Incidentally, note the special destructuring that Compojure does for +you in each of those routes. It can pull out url query (and body) +parameters, as well as pieces of the url path requested, and hand them +to your views functions. Read more about that at Compojure +destructuring.

Create your Views

Create a src/my_webapp/views.clj file and make it look like:

(ns my-webapp.views
+  (:require [my-webapp.db :as db]
+            [clojure.string :as str]
+            [hiccup.page :as page]
+            [ring.util.anti-forgery :as util]))
+
+(defn gen-page-head
+  [title]
+  [:head
+   [:title (str "Locations: " title)]
+   (page/include-css "/css/styles.css")])
+
+(def header-links
+  [:div#header-links
+   "[ "
+   [:a {:href "/"} "Home"]
+   " | "
+   [:a {:href "/add-location"} "Add a Location"]
+   " | "
+   [:a {:href "/all-locations"} "View All Locations"]
+   " ]"])
+
+(defn home-page
+  []
+  (page/html5
+   (gen-page-head "Home")
+   header-links
+   [:h1 "Home"]
+   [:p "Webapp to store and display some 2D (x,y) locations."]))
+
+(defn add-location-page
+  []
+  (page/html5
+   (gen-page-head "Add a Location")
+   header-links
+   [:h1 "Add a Location"]
+   [:form {:action "/add-location" :method "POST"}
+    (util/anti-forgery-field) ; prevents cross-site scripting attacks
+    [:p "x value: " [:input {:type "text" :name "x"}]]
+    [:p "y value: " [:input {:type "text" :name "y"}]]
+    [:p [:input {:type "submit" :value "submit location"}]]]))
+
+(defn add-location-results-page
+  [{:keys [x y]}]
+  (let [id (db/add-location-to-db x y)]
+    (page/html5
+     (gen-page-head "Added a Location")
+     header-links
+     [:h1 "Added a Location"]
+     [:p "Added [" x ", " y "] (id: " id ") to the db. "
+      [:a {:href (str "/location/" id)} "See for yourself"]
+      "."])))
+
+(defn location-page
+  [loc-id]
+  (let [{x :x y :y} (db/get-xy loc-id)]
+    (page/html5
+     (gen-page-head (str "Location " loc-id))
+     header-links
+     [:h1 "A Single Location"]
+     [:p "id: " loc-id]
+     [:p "x: " x]
+     [:p "y: " y])))
+
+(defn all-locations-page
+  []
+  (let [all-locs (db/get-all-locations)]
+    (page/html5
+     (gen-page-head "All Locations in the db")
+     header-links
+     [:h1 "All Locations"]
+     [:table
+      [:tr [:th "id"] [:th "x"] [:th "y"]]
+      (for [loc all-locs]
+        [:tr [:td (:id loc)] [:td (:x loc)] [:td (:y loc)]])])))
+

Here we've implemented each function used in handler.clj.

Again, note that each of the functions with names ending in "-page" +(the ones being called in handler.clj) is returning just a plain +string consisting of html markup. In handler.clj's defroutes, +Compojure is helpfully taking care of placing that into a response +hashmap for us.

Rather than clog up this file with database-related calls, we've put +them all into their own db.clj file (described next).

Create some db access functions

Create a src/my_webapp/db.clj file and make it look like:

(ns my-webapp.db
+  (:require [clojure.java.jdbc :as jdbc]))
+
+(def db-spec {:dbtype "h2" :dbname "./my-webapp"})
+
+(defn add-location-to-db
+  [x y]
+  (let [results (jdbc/insert! db-spec :locations {:x x :y y})]
+    (assert (= (count results) 1))
+    (first (vals (first results)))))
+
+(defn get-xy
+  [loc-id]
+  (let [results (jdbc/query db-spec
+                            ["select x, y from locations where id = ?" loc-id])]
+    (assert (= (count results) 1))
+    (first results)))
+
+(defn get-all-locations
+  []
+  (jdbc/query db-spec "select id, x, y from locations"))
+

Note that jdbc/query returns a seq of maps. Each map +entry's key is a column name (as a Clojure keyword), and its value is +the value for that column.

You'll also notice that we used a plain string in get-all-locations, +rather than putting it in a vector. java.jdbc allows us to omit the vector +wrapping when we have a simple SQL query with no parameters.

Of course, you can try out all these calls yourself in the REPL, +if you like:

~/temp/my-webapp$ lein repl
+...
+user=> (require 'my-webapp.db)
+nil
+user=> (ns my-webapp.db)
+nil
+my-webapp.db=> (jdbc/query db-spec
+          #_=>     "select x, y from locations where id = 1")
+({:y 9, :x 8})
+

Run your webapp during development

You can run your webapp via lein:

lein ring server
+

It should start up and also open a browser window for you pointed at +http://localhost:3000. You should be able to stop the webapp by +hitting ctrl-c.

If you don't want it to automatically open a +browser window, run it like so:

lein ring server-headless
+

Deploy your webapp

To make your webapp suitable for deployment, make the following +changes:

Changes in project.clj

In your project.clj file:

  • add to :dependencies (the version should generally match compojures version):

    [ring/ring-jetty-adapter "1.5.1"] ; e.g., for compojure version 1.5.1
    +
  • and also add :main my-webapp.handler

Changes in handler.clj

In src/my_webapp/handler.clj:

  • in your ns macro: +
    • add [ring.adapter.jetty :as jetty] to the :require, and
    • add (:gen-class) to the end

The ns form should now look like this:

(ns my-webapp.handler
+  (:require [my-webapp.views :as views]
+            [compojure.core :refer :all]
+            [compojure.route :as route]
+            [ring.adapter.jetty :as jetty] ; add this require
+            [ring.middleware.defaults :refer [wrap-defaults site-defaults]])
+  (:gen-class)) ; and add this gen-class
+
  • and at the bottom, add the following -main function:

    (defn -main
    +  [& [port]]
    +  (let [port (Integer. (or port
    +                           (System/getenv "PORT")
    +                           5000))]
    +    (jetty/run-jetty #'app {:port  port
    +                            :join? false})))
    +

Build and Run it

Now create an uberjar of your webapp:

lein uberjar
+

And now you can run it directly:

java -jar target/my-webapp-0.1.0-standalone.jar 8080
+

(or on whatever port number you wish). If you run the JAR file from another +folder, remember to copy the my-webapp.mv.db file to that folder!

NOTE: if you did not remove "-SNAPSHOT" from the project's version string +when you first edited project.clj, then the JAR file will have -SNAPSHOT +in its name.

See Also

  • To get a head start with a more "batteries-included" project +template, see Luminus.

Contributors

John Gabriele jmg3000@gmail.com (original author)

Ivan Kryvoruchko gildraug@gmail.com

Sean Corfield sean@corfield.org

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/eclipse/index.html b/clones/clojure-doc.org/articles/tutorials/eclipse/index.html new file mode 100644 index 00000000..524dc03d --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/eclipse/index.html @@ -0,0 +1,250 @@ + + + + + Clojure Guides: Starting with Eclipse and Counterclockwise For Clojure Development + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • Installing Eclipse
  • Installing Counterclockwise, the Clojure plugin for Eclipse
  • Creating a sample project

This work is licensed under a Creative Commons Attribution 3.0 Unported License +(including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.4.

Installing Eclipse

  1. Download the latest release of Eclipse from the official site.
  2. Install Counterclockwise plugin. +
    1. navigate to the "Install new Software" tab under the help menu
    2. paste in the CCW update URL: http://ccw.cgrand.net/updatesite in the "Work with:" text field
    3. check the "Clojure Programming" checkbox and hit the "Next" button
  3. Follow the instructions on the screen and restart Eclipse for changes to take effect.

Counterclockwise takes care of setting up Clojure and Leiningen for you. And once the plugin is installed, you will be +able to create a new Clojure project or a new Leiningen project.

Clojure project will use Eclipse to manage dependencies, while the Leiningen project will pull dependencies from the +project.clj in the root folder of the project.

At this point you should have Eclipse with CCW up and running. Navigate to File->new->project in Eclipse menu. +Then select Leiningen->Leiningen project. Here you'll see the default Leiningen Template filled in. +And only thing you have to do is provide a project name. Give the project a name and hit the finish button.

You should now see a new project in your Package Explorer view on the left. If you created a project called +myproject then the project template will have a src folder which will contain the package folder named myproject.

Note that since Java cannot use dashes in names, all the dashes in package folders for namespaces get converted to underscores. +The package will contain a core.clj file, and its contents should look like the following:

(ns myproject.core)
+
+(defn foo
+  "I don't do a whole lot."
+  [x]
+  (println x "Hello, World!"))
+

Let's open it and then hit the run button. You should see a REPL pop up momentarily on the bottom of the IDE. +If all went well, your project should be ready to work on (if it failed, see the troubleshooting section). The code that's in the file will have already been +loaded up in the REPL when we hit run, and we should now be able to call our foo function.

To do that, let's write the code which calls foo below it:

(foo "Test: ")
+

Then navigate the cursor inside the call body and hit CTRL+ENTER on Linux/Windows or CMD+ENTER on OS X. +You should see "Hello, World!" printed in the REPL view on the bottom. We can now change the behavior of the +foo function and after reloading it the new behavior will be available next time it's called.

It's also recommended to enable the "strict/paredit" mode under Preferences->Clojure->Editor section. +This will allow the editor to keep track of balancing the parens for you.

Another useful feature of the editor is the ability to select code by expression. +If you navigate inside a function and press ALT+SHIFT+UP (use CMD instead of ALT in OS X), then inner +body of the expression will be selected, pressing it again, will select the expression, and then the outer body, +and so on. Conversely pressing ALT+SHIFT+DOWN will narrow the selection. This allows you to quickly navigate nested +structures, and select code by chunks of logic as opposed to simply selecting individual lines.

Managing dependencies

Eclipse Dependencies

  1. Right click on the project navigate to properties.
  2. Under properties select "Java Build Path"
  3. Under Libraries select "Add External JARs..."
  4. Click OK

The library will show up under "Referenced Libraries" in Package Explorer.

Leiningen

You will also see a project.clj` file in the root of the project. This file should look like the following:

(defproject myproject "0.1.0-SNAPSHOT"
+  :description "FIXME: write description"
+  :url "http://example.com/FIXME"
+  :license {:name "Eclipse Public License"
+            :url "http://www.eclipse.org/legal/epl-v10.html"}
+  :dependencies [[org.clojure/clojure "1.4.0"]])
+

You can add new dependencies to your project by adding them to the dependencies vector. +For example, if we wanted to add an HTTP client, head to ClojureSphere +and navigate to the clj-http page.

From there follow the link to Clojars and copy the following:

[clj-http "0.6.4"]
+

now we'll simply paste it under dependencies in our project.clj:

:dependencies [[org.clojure/clojure "1.4.0"]
+               [clj-http "0.6.4"]]
+

In the package explorer view on the left expand "Leiningen dependencies" +and see that the clj-http jar included there. You will now have to kill our current REPL +if it is running. To do that navigate to the terminal view next to it and press the stop button. +When we start a new instance of the REPL, the library will be available for use.

In the core file we can now require the library in the namespace definition:

(ns myproject.core
+  (:require [clj-http.client :as client]))
+

and test using the client by typing

(client/get "http://google.com")
+

and running it as we did earlier.

Troubleshooting

If when you attempt to run your code for the first time, you are asked +to select a way to run your project, rather than it just running, you +can try right clicking on the root project folder and then selecting +Leiningen->Reset Project Configuration.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/emacs/index.html b/clones/clojure-doc.org/articles/tutorials/emacs/index.html new file mode 100644 index 00000000..79b80931 --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/emacs/index.html @@ -0,0 +1,445 @@ + + + + + Clojure Guides: Clojure with Emacs + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.5+ and Emacs 24+ for MS Windows and Linux, +and Emacs 26+ for macOS. Earlier Clojure and Emacs releases +are not supported by these instructions.

Overview

Emacs has traditionally been one of the best development environments +for functional languages and Lisps in particular. This guide will +explain how to get it installed, and give an example of a basic +workflow to use while developing a simple library.

Installing Emacs

macOS

The easiest way to get going with Emacs on macOS is to +use Homebrew. Instructions for installing Homebrew +are provided on the landing page, and requirements (such as Xcode) are +listed on the installation details +page.

Once brew is installed, you can install Emacs using:

$ brew cask install emacs
+

This will install Emacs into your /Applications/Emacs.app folder and +provide a symlink to the application as /usr/local/bin/emacs.

After installing, Emacs can be launched the same as other Mac applications +or from the terminal via:

$ emacs
+

Debian/Ubuntu

Newer Debian-based systems (post-wheezy) ship Emacs 24 in apt:

$ sudo apt install emacs24
+

Arch/Antergos

The latest version of Emacs(i.e. v25.1) is available in Arch's official repositories.

$ sudo pacman -S emacs
+

On older systems you can add unofficial package sources for emacs-snapshot, +either for Debian or +Ubuntu.

MS Windows

You can find Emacs for Windows in the FSF FTP +directory.

Download the file named emacs-24.1-bin-i386.zip and unzip it in a new folder. +Avoid folder with spaces in their names such as C:\Documents and Settings. +Prefer folder names such as C:\emacs-24.1.

Create an environment variable +with name HOME and value equal to the location of your home folder; in Windows +XP, it's C:\Documents and Settings\YourUsername, in Windows 7, it's +C:\Users\YourUsername. With this variable set, you can use the tilde character +(~) to type the name of a file under your home folder and Emacs will expand +its full path.

The following section describes Emacs configuration using the folder .emacs.d. +When using Emacs in Windows, you should create this folder under your home +folder. In Windows XP, that will be the folder C:\Documents and Settings\YourUsername\.emacs.d; in Windows 7, that will be the folder +C:\Users\YourUsername\.emacs.d.

Configuring Emacs

So Emacs is installed, but running it now would be a somewhat +barebones experience and not particularly useful for Clojure +development.

Manual setup

Emacs can be configured through a folder in your home folder called +~/.emacs.d, and +configuration options are pretty much endless. To help you through +this, Phil Hagelberg has created a small library enables a few +non-intrusive helpful features called +better-defaults +which might be useful if you are not already an Emacs pro.

Most Emacs packages are kept at MELPA, +the community package host. Add this code to your config in +~/.emacs.d/init.el to tell Emacs to look there:

For the stable repository:

(require 'package)
+(add-to-list 'package-archives
+             '("melpa-stable" . "http://stable.melpa.org/packages/") t)
+(package-initialize)
+

For the latest packages:

(require 'package)
+(add-to-list 'package-archives
+             '("melpa" . "http://melpa.org/packages/") t)
+(package-initialize)
+

Run M-x package-refresh-contents to pull in the package listing.

M-x means meta-x, and meta is mapped to the alt key on most keyboards, +though Mac OS X usually maps it to the command key.

You'll need to install the following packages:

  • clojure-mode - a major mode for editing Clojure and ClojureScript code
  • CIDER - a Clojure interactive development environment and REPL for Emacs
  • projectile(optional) - for navigating inside your projects swiftly

Before continuing any further you should briefly consult their documentation.

You can either install each package one-by-one with M-x package-install or specify all your packages in Emacs Lisp as part of +your configuration file. This is helpful if you take your dotfiles to +a new machine; you don't have to remember everything you've installed +by hand.

(defvar my-packages '(better-defaults
+                      projectile
+                      clojure-mode
+                      cider))
+
+(dolist (p my-packages)
+  (unless (package-installed-p p)
+    (package-install p)))
+

Put the code above in ~/.emacs.d/init.el and run it with M-x eval-buffer.

A lot of warnings will likely whizz by as it installs and compiles +packages. Unless you have any actual errors this is all fine.

To look at the other packages available for installation you can +invoke M-x package-list-packages. To manually install a package, +move the point to line of the package with the keyboard and press 'i' +for 'install'. After selecting all the packages you are interested in, +press 'x' for 'eXecute' to install.

Preconfigured setup

There are also some ready-made Emacs configurations that are optimized +for Clojure development - +Prelude(developed by the +maintainer of CIDER and clojure-mode) and +Emacs Live.

If you want a more powerful Emacs setup you should definitely check them out.

Basics

The first thing you should do without question, is to go through the +built-in Emacs tutorial. To do this press C-h t or hold down Control +and press h and then press t by itself.

With that in mind, these are the basic keystrokes you're going to be +using most often with the default binary of Emacs 24+:

File/buffer/window commands
+C-x C-f     Find file
+C-x C-s     Save buffer
+C-x s       Save file (like save-as)
+C-x b       Switch buffer
+C-x k       Kill buffer
+C-x 1       Delete other windows
+C-x 0       Delete current window
+C-x 2       Split window horizontally
+C-x 3       Split window vertically
+
+Movement commands
+C-a         Beginning of line
+C-e         End of line
+C-n         Next line (down)
+C-p         Previous line (up)
+C-b         Back (left)
+C-f         Forward (right)
+M-f         Forward a word
+M-b         Back a word
+C-v         Forward a page
+M-v         Back a page
+
+Edit commands
+C-d         Kill character
+M-d         Kill word
+M-delete    Kill word backwards
+
+Misc commands
+C-s         Regex search forwards
+C-r         Regex search backwards
+M-%         Query replace
+

I should also mention the help commands:

C-h t     Tutorial (goes over the basics)
+C-h b     Describe all current key bindings
+C-h m     Describe the current mode
+C-h a     Apropos - search the help for a term
+C-h k     Describe key
+

I recommend going through the tutorial at least once as it will give +you a good understanding of the navigation and movement commands. +Another useful command you will use a lot is M-x which allows you to +run any command. And there are a LOT. Apropos is very useful for +searching for something C-h a.

So after doing the tutorial (you did do that, RIGHT? O_O) you can move +around, open files, save files, etc., and are generally comfortable at +the basics. There is an almost infinite amount of things to learn +about Emacs, but those basics will get you a long way.

Creating a project

Let's go through the process of creating a small sample clojure project +and illustrate how Emacs helps makes us champions in the land of lisp.

The project we will be building is a trivially simple command line +parser that will take the argument pairs given to it and turn them +into a map of key-value pairs. The functionality is irrelevant and not +particularly useful. It serves purely to illustrate the development +flow.

If you don't have Leiningen yet, get it +installed and then use it to create a new project:

$ lein new command-line-args
+$ cd command-line-args
+

Take a look at the project structure:

+ doc
+  - intro.md
+- project.clj
+- README.md
++ src
+  + command_line_args
+    - core.clj
++ test
+  + command_line_args
+    - core_test.clj
+

Should be fairly self-explanatory, though Leiningen's built-in tutorial +(available via lein help tutorial) provides a detailed explanation of +the project structure.

Let's start up a live REPL session.

M-x cider-jack-in
+

This should open up a new window looking at our *cider-repl* buffer.

First thing to do is add a simple test (in fact the only test we will +be adding because by default, we get it right first time). Open the +core_test.clj file inside of the test folder. Replace the test that +is there with the following:

(deftest pairs-of-values
+   (let [args ["--server" "localhost"
+               "--port" "8080"
+               "--environment" "production"]]
+      (is (= {:server "localhost"
+              :port "8080"
+              :environment "production"}
+             (parse-args args)))))
+

We are simply assigning a list of arguments as they would arrive from +the command line to a local called args, and asserting that the +return value from a function called parse-args is equal to those +command line args turned into a simple map.

Compile the file with C-c C-k(M-x cider-load-buffer). We should get an error +message at the bottom of the emacs window complaining that clojure can't find +parse-args. Let's try to fix the exception by opening core.clj (C-x C-f/M-x find-file) and adding the following definition:

(defn parse-args [args]
+  {})
+

Compile this with C-c C-k, save it (C-x C-s/M-x save-buffer), switch back +to the test buffer (C-x b RET/M-x switch-to-buffer RET) and try compiling +again (C-c C-k). This time it will succeed, so try running the tests with +C-c C-t t(i.e M-x cider-test-run-test) and you should get a test report +buffer showing some failure information:

(not (= {:server "localhost",
+         :port "8080",
+         :environment "production"}
+        {}))
+

Anyway, our map was empty as expected. Let's fix that:

(defn parse-args [args]
+  (apply hash-map args))
+

Running our tests again we now get another error:

(not (= {:server "localhost",
+         :port "8080",
+         :environment "production"}
+        {"--port" "8080",
+         "--server" "localhost",
+         "--environment" "production"}))
+

Whoops, our keys are just strings with the dashes still in place. We +need to strip those off and turn them into keywords:

(defn parse-args [args]
+  (into {} (map (fn [[k v]] [(keyword (.replace k "--" "")) v])
+                (partition 2 args))))
+

And re-running the tests in the test buffer we are all happy. If we +had multiple test files we can run them all from the CLI using:

$ lein test
+

Re-running all the tests from Leiningen can be a good sanity check +before you wrap up work on a feature or branch since there are some +cases where developing from a REPL can give misleading results. For +instance, if you delete a function definition but still call it from +other functions, you won't notice until your process is restarted.

So that is an extremely simple example of a workflow using Emacs with +clojure-mode and cider-test.

Using the REPL

One thing we haven't looked at is how useful having an open running +REPL in Emacs can be for development. If you still have your project +open, split the window (C-x 2 (horizontally) or C-x 3 (vertically)) in +two so you have the core.clj and *cider-repl* buffers open. +Let's say you are editing the core.clj and you want to play around with +the functions as you define them. Looking at parse-args you have +decided you want to pull out the anonymous function to be a named +function keywordize.

First load and compile the buffer into the REPL process with C-c C-k. Change the namespace of the REPL buffer to the one of the file +you're in with C-c M-n. Now switch to the REPL window with C-x o.

You now have access to the functions in this namespace that were +defined when you compiled the file. Try it:

command-line-args.core> (parse-args '("key" "value"))
+{:key "value"}
+

Let's go ahead and create our new function in core.clj:

(defn keywordize [kvp]
+  (let [[k v] kvp]
+    [(keyword (.replace k "--" "")) v]))
+
+(defn parse-args [args]
+  (into {} (map keywordize (partition 2 args))))
+

Now we have a couple of options, we could re-compile the whole file again +(C-c C-k) or we could evaluate each function on its own by going to the end +of the s-exp and using C-x C-e(i.e. cider-eval-last-sexp) which sends the +s-exp to the running REPL. Now switching back to the core.clj namespace +(C-c M-n) and switching back to the REPL buffer we can try out our +keywordize function:

command-line-args.core> (keywordize ["--oh" "hai"])
+[:oh "hai"]
+

If your REPL is starting to get cluttered you can M-x cider-repl-clear-buffer +to clear by first switching to the REPL buffer. The ability to continually +change the code and play around with it is one of the things that makes Emacs +and a lisp a great combination for development.

If you find yourself wanting to repeat a command you just typed at the +REPL, you can use M-p scroll back through history and M-n to go +forwards. Also, all of the Emacs editing commands are available in the +REPL, which is great.

A handy clojure function to use in the REPL is clojure.repl/doc which +gives you the docstring for a given function:

command-line-args.core> (use 'clojure.repl)
+nil
+command-line-args.core> (doc println)
+-------------------------
+clojure.core/println
+([& more])
+  Same as print followed by (newline)
+nil
+

However there is a shortcut C-c C-d d when your cursor is over a +function name. This will show the Clojure (or Javadoc) doc in a new window. If +instead you want to jump to the source of the function you can use +M-., which is awesome. This works on your own functions as well as +those which come from third-party libraries. Use M-, to pop the +stack and return to where you were. For all the definitions in a +single file you can use M-x imenu to list them and jump to one.

When you are finished with the REPL (or if for some reason it has +gotten into a bad state), you can simply kill the *cider-repl* +buffer by typing M-x cider-quit and re-run cider-jack-in to start another.

Appendix

MELPA documentation

CIDER keyboard shortcuts can be found in CIDER documentation.

Contributors

Gareth Jones, 2012 (original author)

Thanks to Phil Hagelberg, Mikael +Sundberg, and Jake +McCrary for suggestions for improvements to +the original blog posts from which this guide was created.

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/getting_started/index.html b/clones/clojure-doc.org/articles/tutorials/getting_started/index.html new file mode 100644 index 00000000..58af1462 --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/getting_started/index.html @@ -0,0 +1,256 @@ + + + + + Clojure Guides: Getting Started with Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • prerequisites (such as Leiningen) and installing
  • running the REPL
  • creating a project
  • interactive development

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

Overview

Clojure is a wonderfully simple language and you are going to love +it.

To quickly get started, first make sure you've got Java installed.

Then install the Leiningen project management +tool.

This author (jg) recommends always installing by downloading the +script directly (as described in the instructions at leiningen.org), +rather than using your OS's package manager. This will ensure that +you get the latest lein version 2.

Clojure programs are typically developed inside their own project +directory, and Leiningen manages projects for you. Lein takes care of +pulling in dependencies (including Clojure itself), running the REPL, +running your program and its tests, packaging your program for +distribution, and other administrative tasks. Run lein help to +see the list of all the tasks in can perform.

Again, there's no need to "install" Clojure, per se. Lein +will take care of fetching it for you.

Trying out the REPL

Although lein facilitates managing your projects, you can also run it +on its own (outside of any particular project directory). Once you +have the lein tool installed, run it from anywhere you like to get a +repl:

$ lein repl
+

You should be greeted with a "user=>" prompt. Try it out:

user=> (+ 1 1)
+;; โ‡’ 2
+user=> (distinct [:a :b :a :c :a :d])
+;; โ‡’ (:a :b :c :d)
+user=> (dotimes [i 3]
+  #_=>   (println (rand-nth ["Fabulous!" "Marvelous!" "Inconceivable!"])
+  #_=>            i))
+;; Marvelous! 0
+;; Inconceivable! 1
+;; Fabulous! 2
+;; โ‡’ nil
+

Your first project

Create your first Clojure program like so:

lein new app my-proj
+cd my-proj
+# Have a look at the "-main" function in src/my_proj/core.clj.
+lein run
+

and see the output from that println function call in +my_proj/core.clj!

Interactive Development

In your project directory, start up a repl (lein repl) and +run your -main function to see its output in the repl:

$ lein repl
+...
+my-proj.core=> (-main)
+Hello, World!
+nil
+

(The prompt is now "my-proj.core=>" instead of "user=>" because lein +has started the repl in an app project. More about that ("namespaces") +in the topical guides.)

From elsewhere, open up your my-proj/src/my_proj/core.clj file +in your editor. Modify the text in that println call.

Back in the repl, reload your source file and run -main again:

my-proj.core=> (require 'my-proj.core :reload)
+my-proj.core=> (-main)
+

to see your changes.

See Also

Other getting started documentation you might find useful:

Next Stop

Next stop: the basic Clojure language tutorial.

Contributors

John Gabriele jmg3000@gmail.com (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/growing_a_dsl_with_clojure/index.html b/clones/clojure-doc.org/articles/tutorials/growing_a_dsl_with_clojure/index.html new file mode 100644 index 00000000..d828d2a0 --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/growing_a_dsl_with_clojure/index.html @@ -0,0 +1,385 @@ + + + + + Clojure Guides: Growing a DSL with Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

Lisps like Clojure are well suited to creating rich DSLs that integrate seamlessly into the language.

You may have heard Lisps boasting about code being data and data being code. In this article we will define a DSL that benefits handsomely from this fact.

We will see our DSL evolve from humble beginnings, using successively more of Clojureโ€™s powerful and unique means of abstraction.

The Mission

Our goal will be to define a DSL that allows us to generate various scripting languages. The DSL code should look similar to regular Clojure code.

For example, we might use this Clojure form to generate either Bash or Windows Batch script output:

Input (Clojure form):

(if (= 1 2)
+  (println "a")
+  (println "b"))
+

Output (Bash script):

if [ 1 -eq 2 ]; then
+  echo "a"
+else
+  echo "b"
+fi
+

Output (Windows Batch script):

IF 1==2 (
+  ECHO a
+) ELSE (
+  ECHO b
+)
+

We might, for example, use this DSL to dynamically generate scripts to perform maintenance tasks on server farms.

Baby Steps: Mapping to Our Domain Language

I like Bash, so letโ€™s start with a Bash script generator.

To start, we need to expose some parallels between Clojureโ€™s core types and our domain language.

So which Clojure types have simple analogues in Bash script?

Strings and numbers should just simply return their String representation, so we will start with those.

Letโ€™s define a function emit-bash-form that takes a Clojure form and returns a string that represents the equivalent Bash script.


+(require '[chivorcam.core :refer [defmacro defmacfn]])
+
(defn emit-bash-form [a]
+  "Returns a String containing the equivalent Bash script
+  to its argument."
+  (cond
+    (string? a ) a
+    (number? a) (str a)
+    :else (throw (ex-info "Fell through" a))))
+

The cond expression handles cases for strings and numbers or throws an exception.

(emit-bash-form 1)
+
(emit-bash-form "a")
+
(emit-bash-form {})
+

Now if we want to add some more dispatches, we just need to add a new clause to our cond expression.

Echo and Print

Letโ€™s add a feature.

Bash prints to the screen using echo. Youโ€™ve probably seen it if youโ€™ve spent any time with a Linux shell.

ambrose@ambrose-desktop> echo asdf
+asdf
+

clojure.core also contains a function println that has similar semantics to Bash's echo.

(println "asdf")
+

Wouldnโ€™t it be cool if we could pass (println "a") to emit-bash-form?

(emit-bash-form (println "asdf"))
+

At first, this seems like asking the impossible.

To made an analogy with Java, imagine calling this Java code and expecting the first argument to equal System.out.println("asdf").

foo( System.out.println("asdf") );
+

(Letโ€™s ignore the fact that System.out.println(...) returns a void).

Java evaluates the arguments before you can even blink, resulting in a function call to println. How can we stop this evaluation and return the raw code?

Indeed this is an impossible task in Java. Even if this were possible, what could we expect do with the raw code?(!)

System.out.println("asdf") is not a Collection, so we canโ€™t iterate over it; it is not a String, so we canโ€™t partition it with regular expressions.

Whatever "type" the raw code System.out.println("asdf") has, itโ€™s not meant to be known by anyone but compiler writers.

Lisp turns this notion on its head.

Lisp Code Is Data

A problem with raw code forms in Java (assuming it is possible to extract them) is the lack of facilities to interrogate them. How does Clojure get around this limitation?

To get to the actual raw code at all, Clojure provides a mechanism to stop evaluation via quote. Prepending a quote to a code form prevents its evaluation and returns the raw Clojure form.

'(println "a")
+

So what is the type of our result?

(type '(println "a"))
+

It's a list!

We can now interrogate the raw code as if it were any old Clojure list (because it is!).

(first '(println "a"))
+
(second '(println "a"))
+

This is a result of Lispโ€™s remarkable property of code being data.

A Little Closer to Clojure

Using quote, we can get halfway to a DSL that looks like Clojure code.

(emit-bash-form
+  '(println "a"))
+

Letโ€™s add this feature to emit-bash-form. We need to add a new clause to the cond form. Which type should the dispatch value be?

So letโ€™s add a clause for lists.

(defn emit-bash-form [a]
+  "Returns a String containing the equivalent Bash script
+  to its argument."
+  (cond
+    (list? a) 
+    (case (name (first a))
+      "println" (str "echo " (second a)))
+
+    (string? a) a
+    (number? a) (str a)
+    :else (throw (ex-info "Fell through" a))))
+

As long as we remember to quote the argument, this is not bad.

(emit-bash-form '(println "a"))
+
(emit-bash-form '(println "hello"))
+

Multimethods to Abstract the Dispatch

Weโ€™ve made a good start, but I think itโ€™s time for some refactoring.

Currently, to extend our implementation we add to our function emit-bash-form. Eventually this function will be too large to manage; we need a mechanism to split this function into more manageable pieces.

Essentially emit-bash-form is dispatching on the type of its argument. This dispatch style is a perfect fit for an abstraction Clojure provides called a multimethod.

Letโ€™s define a multimethod called emit-bash.

The multimethod handles dispatch in a similar way to cond, but without having to actually write each case. Letโ€™s compare this multimethod with our previous cond expression. defmulti is used to create a new multimethod, and associates it with a dispatch function.

(defmulti emit-bash
+          (fn [form]
+            (cond
+              (list? form) :list
+              (string? form) :string
+              (number? form) :number
+              :else (throw (ex-info "Unknown type" form)))))
+

defmethod is used to add methods to an existing multimethod. Here :string is the dispatch value, and the method returns the form as is.

(defmethod emit-bash
+  :string
+  [form]
+  form)
+

Similar for numbers and lists:

(defmethod emit-bash
+  :number
+  [form]
+  (str form))
+
+(defmethod emit-bash
+  :list
+  [form]
+  (case (name (first form))
+    "println" (str "echo " (second form))))
+

Adding new methods has the same result as extending our cond expression, except:

  • multimethods handle the dispatch, instead of writing it manually
  • anyone can extend the multimethod at any point, without disturbing existing code

So how can we use emit-bash? Calling a multimethod is just like calling any Clojure function.

(emit-bash '(println "a"))
+

The dispatch is silently handled under the covers by the multimethod.

Extending our DSL for Batch Script

Letโ€™s say Iโ€™m happy with the Bash implementation. I feel like starting a new implementation that generates Windows Batch script. Letโ€™s define a new multimethod, emit-batch.

(defmulti emit-batch
+          (fn [form]
+            (cond
+              (list? form) :list
+              (string? form) :string
+              (number? form) :number
+              :else (throw (ex-info "Unknown type" form)))))
+
+(defmethod emit-batch 
+  :list
+  [form]
+  (case (name (first form))
+    "println" (str "ECHO " (second form))
+    nil))
+
+(defmethod emit-batch
+  :string
+  [form]
+  form)
+
+(defmethod emit-batch
+  :number
+  [form]
+  (str form))
+

We can now use emit-batch and emit-bash when we want Batch and Bash script output respectively.

(emit-batch '(println "a"))
+
(emit-bash '(println "a"))
+"echo a"
+

Ad-hoc Hierarchies

Comparing the two implementations reveals many similarities. In fact, the only dispatch that differs is clojure.lang.PersistentList!

Some form of implementation inheritance would come in handy here.

We can tackle this with a simple mechanism Clojure provides to define global, ad-hoc hierarchies.

When I say this mechanism is simple, I mean non-compound; inheritance is not compounded into the mechanism to define classes or namespaces but rather is a separate functionality.

Contrast this to languages like Java, where inheritance is tightly coupled with defining a hierarchy of classes.

We can derive relationships from names to other names, and between classes and names. Names can be symbols or keywords. This is both very general and powerful!

We will use (derive child parent) to establishes a parent/child relationship between two keywords. isa? returns true if the first argument is derived from the second in a global hierarchy.

(derive ::child ::parent)
+
+(isa? ::child ::parent)
+

Letโ€™s define a hierarchy in which the Bash and Batch implementations are siblings.

(derive ::bash ::common)
+(derive ::batch ::common)
+

Letโ€™s test this hierarchy.

(parents ::bash)
+
(parents ::batch)
+

Utilizing a Hierarchy in a Multimethod

We can now define a new multimethod emit that utilizes our global hierarchy of names.

(defmulti emit
+          (fn [form]
+            [*current-implementation*
+             (cond
+               (list? form) :list
+               (string? form) :string
+               (number? form) :number
+               :else (throw (ex-info "Unknown type" form)))]))
+

The dispatch function returns a vector of two items: the current implementation (either ::bash or ::batch), and the class of our form (like emit-bash's dispatch function).

*current-implementation* is a dynamic var, which can be thought of as a thread-safe global variable.

(def ^{:dynamic true}
+  ;; The current script language implementation to generate
+  *current-implementation*)
+

In our hierarchy, ::common is the parent, which means it should provide the methods in common with its children. Let's fill in these common implementations.

Remember the dispatch value is now a vector, notated with square brackets. In particular, in each defmethod the first vector is the dispatch value (the second vector is the list of formal parameters).

(defmethod emit [::common :string]
+  [form]
+  form)
+
+(defmethod emit [::common :number]
+  [form]
+  (str form))
+

This should look familiar. The only methods that needs to be specialized are those for clojure.lang.PersistentList, as we identified earlier. Notice the first item in the dispatch value is ::bash or ::batch instead of ::common.

(defmethod emit [::bash :list]
+  [form]
+  (case (name (first form))
+    "println" (str "echo " (second form))
+    nil))
+
+(defmethod emit [::batch :list]
+  [form]
+  (case (name (first form))
+    "println" (str "ECHO " (second form))
+    nil))
+

The ::common implementation is intentionally incomplete; it merely exists to manage any common methods between its children.

We can test emit by rebinding *current-implementation* to the implementation of our choice with binding.

(binding [*current-implementation* ::common]
+         (emit "a"))
+
(binding [*current-implementation* ::batch]
+  (emit '(println "a")))
+
(binding [*current-implementation* ::bash]
+  (emit '(println "a")))
+
(binding [*current-implementation* ::common]
+  (emit '(println "a")))
+

Because we didnโ€™t define an implementation for [::common :list], the multimethod falls through and throws an Exception.

Multimethods offer great flexibility and power, but with power comes great responsibility. Just because we can put our multimethods all in one namespace doesnโ€™t mean we should. If our DSL becomes any bigger, we would probably separate all Bash and Batch implementations into individual namespaces.

This small example, however, is a good showcase for the flexibility of decoupling namespaces and inheritance.

Icing on the Cake

Weโ€™ve built a nice, solid foundation for our DSL using a combination of multimethods, dynamic vars, and ad-hoc hierarchies, but itโ€™s a bit of a pain to use.

(binding [*current-implementation* ::bash]
+  (emit '(println "a")))
+

Letโ€™s eliminate the boilerplate. But where is it?

The binding expression is an good candidate. We can reduce the chore of rebinding current-implementation by introducing with-implementation (which we will define soon).

(with-implementation ::bash
+  (emit '(println "a")))
+

Thatโ€™s an improvement. But thereโ€™s another improvement thatโ€™s not as obvious: the quote used to delay our formโ€™s evaluation. Letโ€™s use script, which we will define later, to get rid of this boilerplate:

(with-implementation ::bash
+  (script
+    (println "a")))
+

This looks great, but how do we implement script? Clojure functions evaluate all their arguments before evaluating the function body, exactly the problem the quote was designed to solve.

To hide this detail we must wield one of Lispโ€™s most unique forms: the macro.

The macroโ€™s main drawcard is that it doesnโ€™t implicitly evaluate its arguments. This is a perfect fit for an implementation of script.

(defmacro script [form]
+  `(emit '~form))
+

To get an idea what is happening, hereโ€™s what a call to script returns and then implicitly evaluates.

(macroexpand '(script (println "a")))
+

It isnโ€™t crucial that you understand the details, rather appreciate the role that macros play in cleaning up the syntax.

We will also implement with-implementation as a macro, but for different reasons than with script. To evaluate our script form inside a binding form we need to drop it in before evaluation.

(defmacro with-implementation
+  [impl & body]
+  `(binding [cljs.user/*current-implementation* ~impl]
+     ~@body))
+

Roughly, here is the lifecyle of our DSL, from the sugared wrapper to our unsugared foundations.

(with-implementation ::bash
+  (script
+    (println "a")))
+=>
+(with-implementation ::bash
+  (emit
+    '(println "a"))
+=>
+(binding [*current-implementation* ::bash]
+  (emit
+    '(println "a")))
+

Let's see it in action for Bash:

(with-implementation ::bash
+  (script
+    (println "a")))
+

And for Windows:

(with-implementation ::batch
+  (script
+    (println "a")))
+

Itโ€™s easy to see how a few well-placed macros can put the sugar on top of strong foundations. Our DSL really looks like Clojure code!

Conclusion

We have seen many of Clojureโ€™s advanced features working in harmony in this DSL, even though we incrementally incorported many of them. Generally, Clojure helps us switch our implementation strategies with minimum fuss.

This is notable when you consider how much our DSL evolved.

We initially used a simple cond expression, which was converted into two multimethods, one for each implementation. As multimethods are just ordinary functions, the transition was seamless for any existing testing code. (In this case I renamed the function for clarity).

We then merged these multimethods, utilizing a global hierachy for inheritance and dynamic vars to select the current implementation.

Finally, we devised a pleasant syntactic interface with a two simple macros, eliminating that last bit of boilerplate that other languages would have to live with.

I hope you have enjoyed following the evolution of our little DSL. This DSL is based on a simplified version of Stevedore by Hugo Duncan. If you are interested in how this DSL can be extended, you can do no better than browsing the source code of Stevedore.

Copyright Ambrose Bonnaire-Sergeant, 2013

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/introduction/index.html b/clones/clojure-doc.org/articles/tutorials/introduction/index.html new file mode 100644 index 00000000..b3c4d966 --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/introduction/index.html @@ -0,0 +1,968 @@ + + + + + Clojure Guides: Introduction to Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This guide covers:

  • Clojure language basics
  • expressions, identifiers (locals, vars)
  • let forms
  • scalars
  • functions
  • basic data types
  • introduction to immutable data structures
  • overview of Clojure reference types (vars, atoms, agents, refs)
  • looping and recursion
  • basics of Clojure macros

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

Overview

This is a brief beginner's introduction to Clojure. If you haven't +already done so, have a look at the Getting +Started tutorial. Before +continuing, make sure you've got Java and +Leiningen installed, and can create a new +project and run a REPL in it. The author expects you'll want to have a +REPL running while following this introduction so you can type +expressions into it as you go.

Note: In the code samples below, unless we're specifically +discussing the REPL, to reduce clutter we've usually omitted showing +the REPL prompt (ex. "user=>" or "my-proj.core=>").

Additionally: In Clojure, a semicolon begins a single-line comment, +and in this document we use "; โ‡’" (for trailing comments) and +";; โ‡’" (for comments on their own line) to indicate what the +previous expression evaluates to.

This introduction is a whirlwind tutorial of most of the basics of +Clojure. Its goal is to rapidly get you familiar with the core +areas of the language without wasting your time and also without getting +too bogged down in details or advanced topics (the various topics will +get more comprehensive coverage in the topic guides anyway).

As we said in the Getting Started tutorial, Clojure is a wonderfully +simple language, and you're going to love it.

The Basics

Clojure is a general-purpose programming language, and a quite +practical one at that.

The syntax for Clojure is like Lisp and is very simple: code is made +up of expressions which are evaluated to some value. Here are some +examples of expressions:

5                      ; โ‡’ 5
+"hi"                   ; โ‡’ "hi"
+[1 2 3]                ; evaluates to the vector `[1 2 3]`
+(+ 1 2)                ; evaluates to the sum of 1 and 2
+(if true "yes" "no")   ; evaluates to the string "yes"
+(println "hello!")     ; evaluates to nil (but also prints "hello!")
+

Clojure supports a few extra bits of syntax which will be noted as we +encounter them.

Expressions can contain sub-expressions:

(+ 1
+   (* 2 3)
+   (/ 10 2))   ; โ‡’ 1 + (2 * 3) + (10 / 2) = 12
+

Expressions in (various types of) brackets are often referred to as +"forms".

An expression in parentheses is usually treated as a function call, +but may also be a macro or special form (more about those in the +Evaluation section below).

Clojure is not whitespace-sensitive. Also, commas count as whitespace, +so you can omit them (for example, you can write a vector as [1 2 3] +instead of [1, 2, 3]).

Clojure code is block-structured and lexically scoped (though dynamic +scope is supported as well, if you really need it).

Clojure is a compiled language. The Clojure reader reads your source +code, then your code is compiled to JVM bytecode, and then it's run on +the JVM. The reader supports a few extra bits of syntactic sugar (for +example, a literal syntax for specifying regular expressions) that we +will cover as we go along.

Throughout this tutorial, we will liberally reference and lean on the +marvelous Clojure Cheatsheet. Aside +from being a great organizational aide, it also handily includes links +to the relevant Clojuredocs pages where you +can find docs for and examples of the various Clojure functions.

In the REPL, at any time you can see the documentation for a given +function:

(doc some-function)
+

and even the source code for it:

(source some-function)
+

So, it will be of great use to you to have your REPL running so you +can try things out while following along.

Identifiers

Identifiers are used to name things. For example, in

(def the-answer 42)
+

we've named something "the-answer" and given it the value 42.

In this document we'll mostly use lowercase letters, numbers, and +dashes to name things, although some other characters are allowed too, +such as _<>!?* (ex. this->that, ready?). We'll note more +examples of those cases later on as they come up.

Scalars

Clojure has support for the following kinds of scalar values:

nil
+true, false
+

nil is like Python's None, or Java's null. It's just another value. +Incidentally, there's no "undefined" value in Clojure --- if you try +to use a symbol which you haven't defined, then it's undefined and the +compiler will let you know about it.

As we go along, type those expressions into your REPL to see them +evaluated. These too:

1        ; integer
+1N       ; arbitrary-precision integer
+1.2      ; float/double/decimal
+1.2M     ; arbitrary-precision decimal
+1.2e4    ; scientific notation
+1.2e4M   ; sci notation of arbitrary-precision decimal
+
+0x3a     ; hex literal (58 in decimal)
+1/3      ; Rational number, or "ratio".
+\a       ; The character "a".
+"hi"     ; A string.
+

Strings can span multiple lines --- just hit Enter and keep typing. If +you want to include a double-quote mark in a string, backslash-escape +it.

#"^foo\d?$"   ; A regular expression.
+:foo          ; A keyword.
+

We'll have more to say about regular +expressions later on.

Keywords are just scalars that evaluate to themselves and are useful +where in other languages you might use little strings as identifiers +(for example, as the keys in a hashmap). More about keywords in the +next section (Data Structures).

'foo   ; A symbol.
+

A symbol is an object that represents the name of something. The +single quote mark is there to keep Clojure from trying to figure out +to what the symbol refers (the quote isn't part of the identifier of +the symbol). When you want to represent the name of a thing --- rather +than the value to which it refers --- you use a symbol. Their utility +will become clearer later on when we briefly mention +Macros.

Terminology: By "object" we just mean the internal thing that +Clojure uses to represent a value --- not "object" as in "object +oriented programming". Clojure is not an object oriented +language. Sure, you can easily access Java OOP objects from Clojure, +but that is outside the scope of this tutorial.

Also, the words "reference" and "refer" are used in Clojure in the +generic sense. A symbol refers to an object (it is not the object +itself). Clojure also happens to support something called +reference types. We'll cover them later on in the Reference +Types section.

Data Structures

Clojure comes out of the box with nice literal syntax for the various +core data structures:

[1 2 3]            ; A vector (can access items by index).
+[1 :two "three"]   ; Put anything into them you like.
+{:a 1 :b 2}        ; A hashmap (or just "map", for short).
+

A hashmap is your typical hash/dictionary data structure. In the above +example, the keys are :a and :b, and the values are 1 and 2. One key-value +pair in a map is called an entry.

Although it's most common to use keywords (as shown above) for hashmap +keys, you can use any values you like for the keys as well as the +values.

#{:a :b :c}        ; A set (unordered, and contains no duplicates).
+'(1 2 3)           ; A list (linked-list)
+

You generally don't use lists very often for typical sequential data +in your programs:

(def my-stuff '("shirt" "coat" "hat"))  ; Works fine, but ...
+(def my-stuff ["shirt" "coat" "hat"])   ; this is more typical usage.
+

Lists are most often used when treating code itself as just a bunch of +nested lists --- see Macros.

BTW, don't mind that single-quote mark before the list's open paren; +it's just there to tell Clojure that this isn't a function call +(discussed in Function Calls, below), but rather, an actual +list.

Note: In Clojure, we use the term "vector" rather than "array". +"Array" would refer to the native Java array, whereas "vector" +refers to the Clojure data structure.

Nesting data structures works like you'd expect:

#{:a
+  [1 2 3]
+  {:foo 11 :bar 12}
+  #{"shirt" "coat" "hat"}}
+

We will see how to get at values inside nested data structures a little +later on.

Abstractions

The data structures we just looked at (lists, vectors, maps, and sets) +are all concrete data types. The various Clojure functions for working +on them (which we will get to later on) actually aren't written to +work on the concrete types, but rather, are written to work on +abstract data types. The concrete data types are implementations of +the various abstract data types.

Some of the Clojure abstractions are:

  • Collection (Lists, vectors, maps, and sets are all collections.)
  • Sequential (Lists and vectors are ordered collections.)
  • Associative (Hashmaps associate keys with values. Vectors associate numeric indices with values.)
  • Indexed (Vectors, for example, can be quickly indexed into.)

In the docs for the various functions, you'll often see that they +take, for example, a "coll". This means that the particular function +will work on any of the collections.

If you'd like to look under the covers and see what the type of +an object is, try (type my-stuff).

Evaluation

So far you've been typing various literal values (expressions) into +the repl and Clojure has evaluated them and repeated their resulting +values back to you (printed them out in the repl):

user=> "hi"
+;; "hi"
+user=> :foo
+;; :foo
+user=> [1 2 3]
+;; [1 2 3]
+

Clojure evaluates the expressions you give it and tries to come up +with a resulting value. If the expression starts with an open paren, +Clojure treats it as either a macro, a special form (discussed +below) or else a function call.

Function Calls

If the symbol right after the open paren names a function, Clojure +evaluates all of its function arguments first, then applies the +function to the values of those args:

(my-func arg1 arg2 arg3)
+

You can nest function calls as deep as tasteful discretion allows:

(my-func (my-func2 arg1
+                   arg2)
+         (other-func arg-a
+                     (foo-bar arg-x
+                              arg-y
+                              (+ arg-xx
+                                 arg-yy
+                                 arg-zz))
+                     arg-b))
+

Note that your code will be easiest to read if you line up args to +functions vertically (as shown above). Your editor should take care of +this for you automatically.

By the way, there are no "operators" in Clojure per se; just function +names (symbols which refer to their corresponding functions). So, for +example, +, >, <=, =, *, and not= are all just function +names.

Macros and Special Forms

If an expression starts with an open paren, Clojure first checks to +see if it's a macro or special form. These are forms which don't +follow the regular evaluation rule and get special treatment from the +Clojure compiler.

Macros are like functions which take as arguments regular Clojure code +(which is, after all, just a list of expressions and (usually nested) +other lists), and returns the code transformed / expanded in some +useful way.

You write macros to add new syntax to the Clojure language, and +usually it's only done when necessary, after you've already gotten as +far as you can with plain functions.

Macros are created using defmacro. Writing them involves +manipulating lists (Clojure code), just like you've already +seen. Though quoting and unquoting is used to control evaluation of +the code you're handling.

Macro calls in your code get expanded at compile-time, right before +the rest of your code is compiled. Certain Clojure built-ins like +let, def, and if are written as special forms which are +hard-coded into the compiler rather than macros, but this is an +implementation detail; the effect is the same.

This tutorial does not discuss macros further.

Quoting

If for whatever reason you'd rather Clojure not treat something like +(+ 1 2 3) as a function call, you can "quote" it like so:

'(+ 1 2 3)
+

This causes Clojure to then regard it simply as a 4-element list; +the first element of which is the symbol for some function. Reasons +for wanting to do this will become clearer later on.

Let and Locals

When you want some lexically-scoped named values to use in a section +of your code, you can use the let expression:

(let [width     10
+      height    20
+      thickness 2]
+  (println "hello from inside the `let`.")
+  (* width
+     height
+     thickness))
+

The first thing inside the let is a binding vector. In it, you +specify the local names you'd like to make available inside the let, +along with their values.

Formatting note: Your readers might appreciate you vertically +lining up the values used in the binding vector, as we've done +above with 10, 20, and 2.

These local names are symbols that refer directly to the values you +set them to.

You can re-set the symbols in the binding vector multiple times +(building it up into the value you need), if you find it useful:

(let [x 2
+      x (* x x)
+      x (+ x 1)]
+  x)
+

The let expression itself evaluates to the last expression in its +body. You can put other things inside the let (like our println +expression, in the previous example), but the overall value of the +let is its last expression.

Note that the println expression just evaluates to nil. We don't +use its value for anything --- we only care about its side-effects +(printing out to the console). More about +Side-Effects shortly.

Namespaces

Clojure uses namespaces to organize function names into groups +and to keep them from colliding with other function names. +All function names live in a namespace. All the core functions +we've been using thus far are in the clojure.core namespace:

(clojure.core/println "hi")
+

That's the fully-qualified name of println. You'd normally have to +use the fully-qualified name for functions (or else use an alias to +the namespace --- covered in a moment), but Clojure makes all the +clojure.core functions automatically available by their unqualified +names (that is, sans namespace) for convenience.

Fully-qualified names are written "namespace/symbol". The namespace +may have dots in it, which correspond to directories in your +filesystem. For example, the function foo-bar.core/my-func corresponds +to the my-func function in src/foo_bar/core.clj. (It's just a bit of +the underlying Java platform showing through that you need to use +underscores in your directory names instead of dashes).

It's most common for one source code file to correspond to one +namespace, and often comprise one library. At the top of your source +file, you write (ns whatever) and that declares the namespace for +the rest of the file.

In the repl, you can make use of libraries --- and at the same time +provide a handy alias for them --- by requiring them like so:

(require '[clojure.string :as str])
+

Now we can use all the functions in the clojure.string library by +prefixing them with "str/". We'll do exactly this in the section below +on Functions for working with +strings.

Functions for Creating Data Structures

There are functions for creating the various data structures without +using the usual literal syntax:

(list 1 2 3)            ; โ‡’ '(1 2 3)
+(vector 1 2 3)          ; โ‡’ [1 2 3]
+(hash-map :a 1 :b 2)    ; โ‡’ {:a 1 :b 2}
+(hash-set :a :b :c)     ; โ‡’ #{:a :b :c}
+

And there are various functions for converting between vectors, sets, +and maps:

(def my-vec [1 2 3])
+(set my-vec)                   ; โ‡’ #{1 2 3}
+
+(def my-map {:a 1 :b 2})
+(vec my-map)                   ; โ‡’ [[:a 1] [:b 2]]
+(flatten (vec my-map))         ; โ‡’ (:a 1 :b 2)
+(set my-map)                   ; โ‡’ #{[:b 2] [:a 1]}
+
+(def my-set #{:a :b :c :d})
+(vec my-set)                   ; โ‡’ [:a :c :b :d]
+
+;; And for fun:
+(zipmap [:a :b :c] [1 2 3])    ; โ‡’ {:c 3 :b 2 :a 1}
+(apply hash-map [:a 1 :b 2])   ; โ‡’ {:a 1 :b 2}
+

(We cover apply in the Bread and Butter +functions section.)

If you need to convert to a sequential collection but don't need fast +random access to items via index, you can use seq instead of vec +(to convert to a generic linked-list-like ("sequential") data +structure). More about seq when we get to Laziness.

By the way, you may have noticed a pattern here: longer function +names are for passing in values one-by-one to create the data +structure, whereas the shorter function names are for passing in a +whole data structure at once:

literal  long name  short name
+-------  ---------  ------------------
+()       list       *{no short name}*
+[]       vector     vec
+{}       hash-map   *{no short name}*
+#{}      hash-set   set
+

You might think of seq as the short name for list, but that's +probably pushing it, since there are a few differences.

Functions For Working With Data Structures

Getting values from data structures:

;; Vectors
+(def v [:a :b :c])
+(nth v 1)             ; โ‡’ :b
+(v 1)                 ; โ‡’ :b  (same)
+(first v)             ; โ‡’ :a
+(rest v)              ; โ‡’ (:b :c)
+(next v)              ; โ‡’ (:b :c)
+(last v)              ; โ‡’ :c
+
+;; Lists
+;; Same as vectors, but can't index.
+
+;; Maps
+(def m {:a 1 :b 2})
+(get m :a)            ; โ‡’ 1
+(m :a)                ; โ‡’ 1       (same)
+(:a m)                ; โ‡’ 1       (same!)
+(get m :x 44)         ; โ‡’ 44      (if no :x, 44 is the default)
+(keys m)              ; โ‡’ (:a :b)
+(vals m)              ; โ‡’ (1 2)
+;; Grab a key or a val from a single map entry:
+(key (first m))       ; โ‡’ :a
+(val (first m))       ; โ‡’ 1
+;; Of course, note that maps are not ordered.
+
+;; Sets
+(def s #{:a :b :c})
+(s :a)                ; โ‡’ :a
+(s :z)                ; โ‡’ nil
+

Data structures in Clojure are actually immutable --- you can't +change them. Though it may sound batty, it actually works out nicely +in practice, and we'll read more about in the +Immutability section +below. For now, just note that data structures can't be mutated, but +we can get a new modified copy of a data structure:

;; Vectors
+(def v   [:a :b :c])
+(def li '(:a :b :c))
+(conj v  :d)          ; โ‡’ [:a :b :c :d]
+(conj li :d)          ; โ‡’ (:d :a :b :c)
+
+v   ; โ‡’ is still [:a :b :c]
+li  ; โ‡’ is still (:a :b :c)
+
+;; Maps
+(def m {:a 1 :b 2})
+(assoc m :c 3)        ; โ‡’ {:a 1 :c 3 :b 2}
+(dissoc m :b)         ; โ‡’ {:a 1}
+
+m   ; โ‡’ is still {:a 1 :b 2}
+
+;; Sets
+(def s #{:a :b})
+(conj s :c)           ; โ‡’ #{:a :c :b}
+(disj s :a)           ; โ‡’ #{:b}
+
+s   ; โ‡’ is still #{:a :b}
+

See the cheatsheet for much more +you can do with these core data structures.

Regular Expressions

As you've seen, Clojure provides a handy literal syntax for regular +expressions: #"regex here". Clojure uses the same regular expression +syntax as Java, which is nearly the same as what Perl 5 (and Python, +and Ruby) uses. You can read more about the specifics in the Java +java.util.regex Pattern +docs.

Clojure provides a number of functions for working with strings, and a +number of those can make use of regexes. See the next section for some +examples.

Functions For Working With Strings

There are a number of functions for working with strings listed in the +Strings section of the cheatsheet. Here are some examples of a few of +them:

(str "hi" "there")
+;; โ‡’ "hithere"
+(count "hello")
+;; โ‡’ 5
+(require '[clojure.string :as str])
+;; โ‡’ nil
+(str/split "hello there" #" ")
+;; โ‡’ ["hello" "there"]
+(str/join ["hello" "there"])
+;; โ‡’ "hellothere"
+(str/join " " ["hello" "there"])
+;; โ‡’ "hello there"
+(str/replace "hello there" "ll" "LL")
+;; โ‡’ "heLLo there"
+

Some of them make optional use of regexes. There's more in the +cheatsheet. Try them out!

Incidentally, since strings are sequential, any function that works on +sequentials works on strings. For example:

(first "hello")
+;; โ‡’ \h
+(last "hello")
+;; โ‡’ \o
+(rest "hello")
+;; โ‡’ (\e \l \l \o)
+(nth "hello" 1)
+;; โ‡’ \e
+(doseq [letter "hello"] (println letter))
+;; h
+;; e
+;; l
+;; l
+;; o
+;; โ‡’ nil
+

Again, see the cheatsheet for more.

Values, Immutability, and Persistence

A value is fundamentally a constant thing; For example, the letter +"a" is a value. You don't "set" the letter "a" to some other value; it +always stays the letter "a". It's immutable. The value 10 is always +10. You can't ever "set 10 to 11". That makes no sense. If you want +11, you just use 11 instead of 10.

In Clojure, all scalars and core data structures are like this. They +are values. They are immutable. The map

{:name "John"
+ :hit-points 200
+ :super-power :resourcefulness}
+

is a value. If you want to "change" John's hit-points, you don't +change anything per se, but rather, you just conjure up a whole new +hashmap value.

But wait: If you've done any imperative style programming in +C-like languages, this sounds crazy wasteful. However, the yin to +this immutability yang is that --- behind the scenes --- Clojure +shares data structures. It keeps track of all their pieces and +re-uses them pervasively. For example, if you have a 1,000,000-item +list and want to tack on one more item, you just tell Clojure, "give +me a new one but with this item added" --- and Clojure dutifully gives +you back a 1,000,001-item list in no time flat. Unbeknownst to you +it's re-using the original list.

Clojure data structures are said to be persistent.

And, again: this works just fine because to you the data structures +are all immutable. There is no "action at a distance". Other functions +can't change the value of a data structure you're working on because +values don't change.

Note that, of course, Clojure doesn't do any unnecessary copying. +For example, when you pass a large data structure to a function

(my-func a-really-big-data-structure)
+

it merely passes along a reference to the big data structure. You +can't change it in the caller's scope, because of course it's +immutable.

And of course, you don't get any action-at-a-distance in situations +like this either:

(def a [1 2 3 4 5])
+(def b a)
+;; Do what you will with `b`, ...
+(my-func a)   ; but it won't affect `a`.
+

since, regardless, you can't mutate the vector (neither via bnor a).

If you're wondering how the heck it's even possible to program at all +if you don't have "variables" and can't change anything, it will +become clear as we continue.

Control Structures

Clojure has most of the usual control structures you'd expect to find, +for example: if, and, or, and cond. You can find them listed +in the Cheatsheet.

Note that they are all expressions in Clojure, and evaluate to +something. So, for example, this if expression:

(if motor-turning?
+  "yes"
+  "no")
+

Evaluates to either the value "yes" or the value "no".

Looping is handled by either using one of the various built-in +functions such as map, filter, reduce, for, etc., or else it's +handled by manually using loop and using recursion. We'll get to +these shortly.

Incidentally, looping is something that is required far less in +Clojure than in imperative languages like Python and Java. The +functions that Clojure provides often makes looping unnecessary. +For example, where in Python you might do something like this:

specific_stuff = []
+for i in my_items:
+    if is_what_i_want(i):
+        specific_stuff.append(i)
+

in Clojure you lose the loop and it becomes:

(def specific-stuff (filter what-i-want? my-items))
+

This sort of thing comes up again and again, and we'll cover more +examples of it in the Bread and Butter +functions section.

Truthiness

In (if <test> <then-this> <otherwise-this>) (and in and, or, +cond, etc. expressions), Clojure checks if the <test> evaluates to +something that looks either true or false. Clojure takes a very simple +approach here: nil and false are falsey; everything else is +truthy.

This means that zero, the empty string, and empty core data structures +are all true:

(if   0 :t :f)  ; โ‡’ :t
+(if  "" :t :f)  ; โ‡’ :t
+(if  [] :t :f)  ; โ‡’ :t
+(if  {} :t :f)  ; โ‡’ :t
+(if #{} :t :f)  ; โ‡’ :t
+

If you want to check if one of those is empty, you could use the +empty? function, though, the docs recommend using this idiom:

(if (seq my-stuff)
+  "still has stuff left"
+  "all gone")
+

Equality

You'll often check for equality using = (and likewise inequality +using not=), for example:

(if (= tries max-tries)
+  "you're done"
+  "keep going")
+

= recursively checks equality of nested data structures (and +considers lists and vectors containing the same values in the same +order as equal), for example:

(= {:a  [1 2 3] :b #{:x :y} :c {:foo 1 :bar 2}}
+   {:a '(1 2 3) :b #{:y :x} :c {:bar 2 :foo 1}})
+;; โ‡’ true
+

There's also a double-equals function == that is more forgiving +across various types of numbers:

(= 4 4.0)
+;; โ‡’ false
+(== 4 4.0)
+;; โ‡’ true
+

See the docs for += and +== for more +info.

Predicates and Comparators

Predicates are functions that take one or more arguments and return +a true or false value. They usually are named with a trailing question +mark, for example, even?, odd?, nil?, etc. Though, some names +don't have the question mark, such as >, >=, <, <=, =, ==, +and not=.

Comparators are functions that take 2 args and return -1, 0, or 1 +depending upon whether the first arg is less than, equal to, or +greater than the second arg. The main one is compare.

Vars

Near the top of this tutorial is the following definition:

(def the-answer 42)
+

The thing being defined here (behind the scenes) is officially called +a Var. The symbol "the-answer" refers to that var which itself +refers to the value 42:

the-answer (a symbol) โ†’ a var โ†’ 42 (a value).

When Clojure sees "the-answer", it automatically looks up the var, +then from there finds and returns the value 42.

Recall that locals don't involve vars at all: +those symbols refer directly to their values.

Functions: Defining Your Own

You can create a function using fn, and give it a name using def:

(def my-func
+  (fn [a b]
+    (println "adding them!")
+    (+ a b)))
+

As you might guess, this actually creates the symbol my-func which +refers to a var which itself refers to the function (which is a +value). Call it:

(my-func 10 20)
+

But for creating top-level functions, it's more convenient to use +defn (which uses def under the hood):

(defn my-func
+  "Docstring goes here."
+  [a b]
+  (println "adding them!")
+  (+ a b))
+

A few points to note:

  • The function parameters (a and b) are present in a vector +(just like with the let expression, except we don't include +values for them).
  • Inside my-func you can do a sequence of operations if you like +(for example, our println call) --- just like in a let --- but +the value of the last expression is what the function call as a +whole will evaluate to.
  • Function definitions (using defn) should only go at the +"top-level".

Functions can return data structures instead of just scalars:

(defn foo
+  [x]
+  [x (+ x 2) (* x 2)])
+

and you can of course pass them data structures as well:

(defn bar
+  [x]
+  (println x))
+
+(bar {:a 1 :b 2})
+(bar [1 2 3])
+

To define a function to take, say, two or more arguments:

(defn baz
+  [a b & the-rest]
+  (println a)
+  (println b)
+  (println the-rest))
+

Any additional args you pass beyond the first two get packaged into a +sequence assigned to the-rest. To have that function take zero or +more arguments, change the parameter vector to just [& the-rest].

Layout of Functions

Your author likes to write his functions in a top-down fashion:

;; BROKEN pseudocode
+
+(do-it)
+
+(defn do-it
+  []
+  (... (my-func-a ...)))
+
+(defn my-func-a
+  [...]
+  (... (my-func-b ...)))
+
+(defn my-func-b ...)
+

but Clojure doesn't like that because it wants to have at least +heard about a function before you write a call to it. To let Clojure +know about a function's existence, use declare:

;; pseudocode
+
+(declare do-it)
+
+(do-it)
+
+(declare my-func-a)
+
+(defn do-it
+  []
+  (... (my-func-a ...)))
+
+(declare my-func-b)
+
+(defn my-func-a
+  [...]
+  (... (my-func-b ...)))
+
+(defn my-func-b ...)
+

Side-effects

Some expressions in Clojure have side-effects. Many do not. All +expressions evaluate to something.

For example, (+ 1 2) evaluates to 3 and has no side-effects. +(println "hi") evaluates to nil and has the side-effect of printing +"hi" to standard out. You usually call println for the side-effect, +not for the return value.

Pure functions are those which have no side-effects and which do not +depend upon anything outside to compute their return value(s): you +pass it one or more values, and it returns one or more values.

If you want to make an expression that has some side-effects before +it evaluates to a value, use do:

(do
+  (println "Spinning up warp drive, captain ...")
+  (spin-up-warp-drive)
+  (get-engine-temperature))
+

There are a handful of functions/macros/special-forms in Clojure for +making use of side-effects, and they are spelled with a "do" at the +beginning. Try these on for size:

(def my-items ["shirt" "coat" "hat"])
+
+(doseq [i my-items]
+  (println i))
+
(dotimes [i 10]
+  (println "counting:" i))
+

There's also dorun and doall, both of which are discussed below in +the section on Laziness.

We say that let expressions and function bodies (and also loop +expressions, which you'll read about later in Looping and +Recursion) have an "implicit do": within them +you can list expressions one after another, and they all get evaluated +in order (presumably for the side-effects), but the last one is what +determines the overall resulting value of the let expression.

Incidentally, if in the binding vector of a let you'd like to have +some side-effects happen and aren't really concerned about the local +values involved, it's customary to use "_" (an underscore) as the +identifier:

(let [_ (do-something)
+      _ (println "done with that")
+      x 10]
+  ...)
+

There's nothing special about the identifier "_" --- it's just +shorter to type than, say, "this-is-of-no-consequence".

There's a version of if which supports no "else" expression and +which provides an "implicit do": it's spelled "when" (and likewise +with if-not โ†” when-not).

Destructuring

Clojure provides a little bit of extra syntactic support for assigning +values to locals in let expressions and function definitions. Using +let as an example, suppose you have a nested data structure, and +you'd like to assign some values in it to locals. Where you could do +this:

(def games [:chess :checkers :backgammon :cards])
+
+(let [game-a (games 0)
+      game-b (games 1)
+      game-c (games 2)
+      game-d (games 3)]
+  ...
+  ...)
+

Destructuring allows you to instead write:

(let [[game-a game-b game-c game-d] games]
+  ...
+  ...)
+

The thing to the left of "games" in the binding vector is referred to +as the "binding form". In the above case, the binding form is a +vector.

The way it works is: if the binding form is a vector, Clojure assumes +that the thing you're trying to assign to it must also be a vector, +and so it unpacks the values from that data structure into the +corresponding items listed in the binding form.

If you want to omit one or more of the values in the games, you +can do so like this:

(let [[_ my-game _ your-game] games]
+  ...
+  ...)
+

The underscore is just used as a placeholder. It's a valid identifier, +but conventionally used when you don't care what value it gets. Above, +my-game gets :checkers and your-game gets :cards.

Destructuring also works for maps in additon to vectors. For example, +instead of:

(def concert {:band     "The Blues Brothers"
+              :location "Palace Hotel Ballroom"
+              :promos   "Ladies night, tonight"
+              :perks    "Free parking"})
+
+(let [band     (concert :band)
+      location (concert :location)
+      promos   (concert :promos)
+      perks    (concert :perks)]
+  ...
+  ...)
+

you could do:

(let [{band     :band
+       location :location
+       promos   :promos
+       perks    :perks} concert]
+  ...
+  ...)
+

but an even better shortcut that destructuring provides for that is:

(let [{:keys [band location promos perks]} concert]
+  ...
+  ...)
+

Laziness

Most of the sequences Clojure creates (via calls to map, reduce, +filter, for, etc. --- covered in the next section) are lazy. A +lazy sequence is one that isn't realized (computed) all at +once. Instead, its values are only realized when you ask for them. If +you've only asked for the first 5 values of a lazy seq, then that seq +consists of 5 values plus a box that makes more values only when you +ask for them. .

A nice feature of laziness is that you can create lazy infinite +sequences but only realize (and consume memory for) the first n that +you actually need.

Be aware that the repl causes lazy lists to be fully realized if you +ask to see their value (which one is apt to do). After using the repl +for a while, you start to get a false sense of eagerness. ;)

If you've got some code that generates a lazy seq and you want to realize +the whole thing right then and there, you can either use

  • (doall my-lazy-seq) (to get the whole thing), or else
  • (dorun my-lazy-seq) (to realize each value (presumably for some +side-effects you're expecting to get in the process) but then +forget it as you proceed to realize the next one).

Bread and Butter Functions

Given Clojure's extensive use of immutability, persistent data +structures, and laziness, one of its strong suits is functional +programming. To this author, functional programming means:

  • treating functions just like any other regular value (for example, +passing them as args to other functions)
  • writing and using functions that return other functions
  • avoiding mutable state, preferring instead Clojure's functional +alternatives (map, filter, reduce, etc.) or else just +directly using recursion.

Let's try out some of the power tools that Clojure comes with. In the +subsections that follow, we've left out the corresponding links to +clojuredocs for the given functions, but you'll probably want to read +the docs and see the examples there to get the full story for each.

map

With map you can apply a function to every value in a collection. +The result is a new collection. You can often use map instead of +manually looping over a collection. Some examples using map:

(map inc [10 20 30])
+
(map str [10 20 30])
+
;; You can define the function to be used on-the-fly:
+(map (fn [x] (str "=" x "=")) [10 20 30])
+
;; And `map` knows how to apply the function you give it
+;; to multiple collections in a coordinated way:
+(map (fn [x y] (str x y)) [:a :b :c] [1 2 3])
+

When working on more than one collection at a time, map is smart +enough to stop when the shorter of the colls runs out of items:

(map (fn [x y] (str x y)) [:a :b :c] [1 2 3 4 5 6 7])
+

filter and remove

Use filter with a predicate function to pare down a collection to +just the values for which (the-pred the-value) returns true:

(filter odd? (range 10))
+

Use remove for the opposite effect (which amounts to removing the +items for which (pred val) returns true):

(remove odd? (range 10))
+

You will often find yourself using these functions instead +of writing loops like in imperative languages.

apply

apply is for when you have a function which takes individual args, +for example, max, but the values you'd like to pass to it are in a +collection. apply "unpacks" the items in the coll:

(max 1 5 2 8 3)
+
(max [1 5 2 8 3]) ;; ERROR
+
(apply max [1 5 2 8 3])
+

A nice feature of apply is that you can supply extra args which +you'd like to be treated as if they were part of the collection:

(apply max 4 55 [1 5 2 8 3])
+

for

for is for generating collections from scratch (again, without +needing to resort to manually looping). for is similar to Python's +"list comprehensions". Some examples of using for:

(for [i (range 10)] i)
+
(for [i (range 10)] (* i i))
+
(for [i (range 10) :when (odd? i)] [i (str "<" i ">")])
+

Notice we snuck a ":when (odd? i)" in there. for even supports a +:let modifier in there to set up your values before getting to the +body of the for expression.

reduce

reduce is a gem. You use it to apply a function to the first and +second items in a coll and get a result. Then you apply it to the +result you just got and the 3rd item in the coll. Then the result of +that and the 4th. And so on. The process looks something like this:

(reduce + [1 2 3 4 5])
+;; โ†’ 1 + 2   [3 4 5]
+;; โ†’ 3       [3 4 5]
+;; โ†’ 3 + 3   [4 5]
+;; โ†’ 6       [4 5]
+;; โ†’ 6 + 4   [5]
+;; โ†’ 10      [5]
+;; โ†’ 10 + 5
+;; => 5
+

And, of course, you can supply your own function if you like:

(reduce (fn [x y] ...) [...])
+

A nice additional feature of reduce is that you can supply a value +for it to start off with:

(reduce + 10 [1 2 3 4 5])
+

This by itself is pretty handy. But it gets even better. Since you can +supply an initial argument, and you can supply your own function, you +can use a data structure as that initial argument and have your +function "build it up" as you go. For example:

(reduce (fn [accum x]
+          (assoc accum
+                 (keyword x)
+                 (str x \- (rand-int 100))))
+        {}
+        ["hi" "hello" "bye"])
+
+;; โ†’ {}
+;; โ†’ {:hi "hi-29"}
+;; โ†’ {:hi "hi-29" :hello "hello-42"}
+;; โ‡’  {:hi "hi-29" :hello "hello-42" :bye "bye-10"}
+

Building up some accumulator using reduce and your own custom +function is a fairly common pattern (and once again allows us to +avoid looping and manipulations of anything mutable).

partial, comp, and iterate

With partial you can create a function which wraps another one and +passes it some standard arguments every time, along with the ones you +supply right when you call it. For example:

(defn lots-of-args [a b c d] (str/join "-" [a b c d]))
+
(lots-of-args 10 20 30 40)
+
(def fewer-args (partial lots-of-args 10 20 30))
+
(fewer-args 40)
+
(fewer-args 99)
+

comp is for composing a function from other ones. That is, (comp foo bar baz) gives you a function that will first call baz on +whatever you pass it, then bar on the result of that, then foo on the +result of that, and finally returns the result. Here's a silly +example:

(defn wrap-in-stars  [s] (str "*" s "*"))
+
(defn wrap-in-equals [s] (str "=" s "="))
+
(defn wrap-in-ats    [s] (str "@" s "@"))
+
(def wrap-it (comp wrap-in-ats
+                   wrap-in-equals
+                   wrap-in-stars))
+
(wrap-it "hi")
+
;; Which is the same as:
+(wrap-in-ats (wrap-in-equals (wrap-in-stars "hi")))
+

(iterate foo x) yields an infinite lazy list consisting +of:

(x
+ (foo x)
+ (foo (foo x))
+ (foo (foo (foo x)))
+ ...)
+

To just take the first, say, 5 values from an infinite list, try this:

(defn square [x] (* x x))
+
(take 5 (iterate square 2))
+

Looping and Recursion

As you've seen in the previous section, looping is often just handled +by various built-in functions such as map, filter, and reduce. +You should use those whenever you can. For times when you need more +manual control, you can write loops yourself. By-hand.

A loop expression looks like a let; you set up locals in its +binding vector, then the body of the loop is executed. The body has an +implicit do, just like let and function bodies. However, within the +body of the loop expression you exit at some point with what you +have or else loop again. When you loop again, you call the loop (using +recur) as if it's a function, passing new values in for the ones you +previously set up in the binding vector. The loop calling itself like +this is called recursion. Here's a trivial example:

(loop [accum []
+       i     1]
+  (if (= i 10)
+    accum
+    (recur (conj accum i)
+           (inc i))))
+

The state in this loop is carried in the accum vector, which we +update each time through the loop. i is the counter, and we finally +exit the loop (which evaluates to accum) when i equals 10.

accum could be any other data structure, and that call (conj accum i) could be any expression that yields a new data structure to take +the old one's place the next time through.

You don't actually need a loop to use recur. If you use recur in +a function body, it will just call the function again, replacing the +args it was previously called with with the ones you pass to recur.

Finally, recall that if you just need looping for the side-effects +only, see doseq and dotimes.

Reference Types

Although we've been saying all along that Clojure doesn't have +"variables", and that everything is immutable, ... that's not entirely +true.

For when you really do need mutability, Clojure offers reference +types. And Clojure provides built-in support for helping you mutate +them in safe ways.

Aside from vars (which is a sort of special reference type), there are +3 kinds of reference types:

  • Atoms
  • Refs
  • Agents

You might typically create a reference type like this:

(def my-atom (atom {}))
+

This reference type is an atom, and its state is a hashmap (an empty +one, for now). Here, the my-atom symbol refers to a var which refers +to the atom.

Although you still can't literally change the value of the atom, you +can swap in a new hashmap value for it any time you like. To retrieve +the value of the atom, you "deref" it, or just use the shorter "@" +syntax. Here's an (atom-specific) example:

(def my-atom (atom {:foo 1}))
+
@my-atom
+
(swap! my-atom update-in [:foo] inc)
+
@my-atom
+

... and we've just changed the state of the atom. (Note, swap! is a +function used only for atoms. There are other specific functions for +working with the other reference types.)

The point of having reference types is that, in your programs, you may +want to represent an identity. An identity is something that may +change its state over time, but is still the same entity, +regardless. In Clojure, an identity is represented by a reference +type, and its state is represented by a value.

We won't discuss reference types further in this tutorial. Perhaps +someone will write a good topical guide...

See Also

  • 4Clojure --- try out what you've +learned so far by interactively solving a set of interesting +programming problems.

Not Covered In This Tutorial

To keep this tutorial down to a manageable length, advanced topics or +other far (or not so far) corners not covered herein include but +aren't limited to: function literals, multiple-arity functions, +exceptions, dynamic scoping of vars, namespaced keywords, metadata, +any substantial coverage of macros, transients, zippers, delays, +futures, promises, refs, agents or anything about multithreading, +thread-first, thread-last, trampolines, datatypes, protocols, +multimethods, and Java interop.

Contributors

John Gabriele jmg3000@gmail.com (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/parsing_xml_with_zippers/index.html b/clones/clojure-doc.org/articles/tutorials/parsing_xml_with_zippers/index.html new file mode 100644 index 00000000..e032cd53 --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/parsing_xml_with_zippers/index.html @@ -0,0 +1,486 @@ + + + + + Clojure Guides: Parsing XML in Clojure + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.4 and Leiningen 2.x.

Overview

Try as you might, XML is difficult to avoid. This is particularly true +in the Java ecosystem. This guide will show you how to parse XML with +the minimum amount of pain using the excellent tools available in +Clojure.

Parsing NZB files

For the purpose of the tutorial I have chosen a simple and fairly well +known XML file format: NZB. An NZB file is used to describe files to +download from NNTP servers. In this tutorial we will take a basic NZB +document and turn it into a Clojure map.

Let us start by creating a new project (for details on using +Leiningen, see this guide:

$ lein new nzb
+

Now edit project.clj to contain the following:

(defproject nzb "0.1.0-SNAPSHOT"
+  :description ""
+  :url ""
+  :license {:name "Eclipse Public License"
+            :url "http://www.eclipse.org/legal/epl-v10.html"}
+  :dependencies [[org.clojure/clojure "1.4.0"]
+                 [org.clojure/data.zip "0.1.1"]])
+

We are including a dependency on +clojure.data.zip, which is a +"system for filtering trees, and XML trees in particular".

Make a dir called dev-resources at the root of your project, and +create a file named example.nzb inside of it. This will be the file +we use to test our code (taken from +wikipedia). dev-resources is by +convention the location to store file resources you use during +development / testing.

Put the following XML in the example.nzb file:

<?xml version="1.0" encoding="iso-8859-1" ?>
+<!-- <!DOCTYPE nzb PUBLIC "-//newzBin//DTD NZB 1.1//EN" "http://www.newzbin.com/DTD/nzb/nzb-1.1.dtd"> -->
+<nzb xmlns="http://www.newzbin.com/DTD/2003/nzb">
+ <head>
+   <meta type="title">Your File!</meta>
+   <meta type="tag">Example</meta>
+ </head>
+ <file poster="Joe Bloggs &lt;bloggs@nowhere.example&gt;" date="1071674882" subject="Here's your file!  abc-mr2a.r01 (1/2)">
+   <groups>
+     <group>alt.binaries.newzbin</group>
+     <group>alt.binaries.mojo</group>
+   </groups>
+   <segments>
+     <segment bytes="102394" number="1">123456789abcdef@news.newzbin.com</segment>
+     <segment bytes="4501" number="2">987654321fedbca@news.newzbin.com</segment>
+   </segments>
+ </file>
+</nzb>
+

Note The eagle eyed among you will notice that I have commented out the +DOCTYPE declaration, as this causes an Exception to be thrown. I will +show you how to get around this towards the end of the tutorial.

Let's write a high level test to illustrate more clearly what we are +trying to do. Open up the test/nzb/core_test.clj file and make enter +the following:

(ns nzb.core-test
+  (:use clojure.test
+        nzb.core)
+  (:require [clojure.java.io :as io]))
+
+(deftest test-nzb->map
+  (let [input (io/resource "example.nzb")]
+    (is (= {:meta {:title "Your File!"
+                   :tag "Example"}
+            :files [{:poster "Joe Bloggs <bloggs@nowhere.example>"
+                     :date 1071674882
+                     :subject "Here's your file!  abc-mr2a.r01 (1/2)"
+                     :groups ["alt.binaries.newzbin"
+                              "alt.binaries.mojo"]
+                     :segments [{:bytes 102394
+                                 :number 1
+                                 :id "123456789abcdef@news.newzbin.com"}
+                                {:bytes 4501
+                                 :number 2
+                                 :id "987654321fedbca@news.newzbin.com"}]}]}
+           (nzb->map input)))))
+

This should be fairly self-explanatory, I have directly translated the +XML into Clojure data structures of maps and vectors. If we were to +just use the clojure.xml library to parse the NZB file, we get a +tree based representation. For example:

(-> "example.nzb" io/resource io/file xml/parse)
+{:tag :nzb,
+ :attrs {:xmlns "http://www.newzbin.com/DTD/2003/nzb"},
+ :content
+ [{:tag :head,
+   :attrs nil,
+   :content
+   [{:tag :meta, :attrs {:type "title"}, :content ["Your File!"]}
+    {:tag :meta, :attrs {:type "tag"}, :content ["Example"]}]}
+  {:tag :file,
+   :attrs
+   {:poster "Joe Bloggs <bloggs@nowhere.example>",
+    :date "1071674882",
+    :subject "Here's your file!  abc-mr2a.r01 (1/2)"},
+   :content
+   [{:tag :groups,
+     :attrs nil,
+     :content
+     [{:tag :group, :attrs nil, :content ["alt.binaries.newzbin"]}
+      {:tag :group, :attrs nil, :content ["alt.binaries.mojo"]}]}
+    {:tag :segments,
+     :attrs nil,
+     :content
+     [{:tag :segment,
+       :attrs {:bytes "102394", :number "1"},
+       :content ["123456789abcdef@news.newzbin.com"]}
+      {:tag :segment,
+       :attrs {:bytes "4501", :number "2"},
+       :content ["987654321fedbca@news.newzbin.com"]}]}]}]}
+

That's great, and can sometimes be enough. But I would rather work +with the representation I have in the test. To do that, we need a way +of traversing this tree and picking out the pieces of information we +require. The clojure.zip and clojure.data.zip libraries are +perfect for this. The +documentation for the +data.zip library on github is nice, but it initially left me a +little confused as to how to go about using the library (not being +familiar with zippers).

A Simple Example

Zippers allow you to easily traverse a data structure. Let's play with +it in a REPL and start with the root node of our NZB file:

(require '[clojure.java.io :as io])
+(require '[clojure.xml :as xml])
+(require '[clojure.zip :as zip])
+(require '[clojure.data.zip.xml :as zip-xml])
+
+(def root (-> "example.nzb" io/resource io/file xml/parse zip/xml-zip))
+

Now we have a zipper for the root element of our document, we can +start traversing it for information. The two main functions we will +use for this are xml-> and xml1->. The former returns a sequence +of items based on the predicates given to it, the latter returning the +first matching item. As an example, let's get the meta data from the NZB +document root and create a Clojure map:

(into {}
+      (for [m (zip-xml/xml-> root :head :meta)]
+        [(keyword (zip-xml/attr m :type))
+         (zip-xml/text m)]))
+;; => {:title "Your File!", :tag "Example"}
+

A couple of things are happening here. First of all we use xml-> to +return a sequence of <meta> tags that live under the <head> tag:

(zip-xml/xml-> root :head :meta)
+

We use the for list comprehension macro to evaluate each item in the +sequence. For each item we find the contents of the :type attribute +using the attr function:

(keyword (zip-xml/attr m :type))
+

This returns us the contents of the attribute as a string, which we +turn into a keyword to use as the key in the map. We then use the +text function to get the textual contents of the meta tag:

(zip-xml/text m)
+

We make a tuple of these values, and pass the resulting sequence to +into to build the map.

Putting It Together

Using only these functions, we can parse the raw XML into the Clojure +data structure from our unit test. If you like, open +./src/nzb/core.clj, and make the changes as you read along.

First let's define our nzb->map function from the test, and pull in +the code we have already written for parsing the metadata of the NZB:

(ns nzb.core
+  (:require [clojure.xml :as xml]
+            [clojure.java.io :as io]
+            [clojure.zip :as zip]
+            [clojure.data.zip.xml :as zip-xml]))
+
+(defn meta->map
+  [root]
+  (into {}
+        (for [m (zip-xml/xml-> root :head :meta)]
+          [(keyword (zip-xml/attr m :type))
+           (zip-xml/text m)])))
+
+(defn file->map
+  [file]
+  ;; TODO
+)
+
+(defn nzb->map
+  [input]
+  (let [root (-> input
+                 io/input-stream
+                 xml/parse
+                 zip/xml-zip)]
+    {:meta  (meta->map root)
+     :files (mapv file->map (zip-xml/xml-> root :file))}))
+

The only new thing here is the use of io/input-stream to allow us to +use anything as input that the io/input-stream supports. These are +currently OutputStream, File, URI, URL, Socket, byte array, and String arguments. See the +clojure.java.io +docs for details.

Now let's fill in the file->map function:

(defn segment->map
+  [seg]
+  {:bytes  (Long/valueOf (zip-xml/attr seg :bytes))
+   :number (Integer/valueOf (zip-xml/attr seg :number))
+   :id     (zip-xml/xml1-> seg zip-xml/text)})
+
+(defn file->map
+  [file]
+  {:poster   (zip-xml/attr file :poster)
+   :date     (Long/valueOf (zip-xml/attr file :date))
+   :subject  (zip-xml/attr file :subject)
+   :groups   (vec (zip-xml/xml-> file :groups :group zip-xml/text))
+   :segments (mapv segment->map
+                   (zip-xml/xml-> file :segments :segment))})
+

Again, nothing new. We simply pick out the pieces of the document we +wish to process using a combination of the xml1->, xml->, attr, +and text functions. Run the test, and it should pass.

Prevent Parsing the DTD

Interestingly, if we uncomment the DTD declaration in the +example.nzb file, our code now explodes with an Exception:

org.xml.sax.SAXParseException: The markup declarations contained or pointed to by the document type declaration must be well-formed
+

We can fix this by swapping out the SAXParserFactory and setting a +feature to not validate the DTD. Here's how:

Update the ns declaration to include some required classes:

(ns nzb.core
+  (:require [clojure.xml :as xml]
+            [clojure.java.io :as io]
+            [clojure.zip :as zip]
+            [clojure.data.zip.xml :as zip-xml])
+  (:import (javax.xml.parsers SAXParser SAXParserFactory)))
+

Define a function to switch out the SAXParserFactory:

(defn startparse-sax
+  "Don't validate the DTDs, they are usually messed up."
+  [s ch]
+  (let [factory (SAXParserFactory/newInstance)]
+    (.setFeature factory "http://apache.org/xml/features/nonvalidating/load-external-dtd" false)
+    (let [^SAXParser parser (.newSAXParser factory)]
+      (.parse parser s ch))))
+

Update our nzb->map definition to use it:

(defn nzb->map
+  [input]
+  (let [root (-> input
+                 io/input-stream
+                 (xml/parse startparse-sax)
+                 zip/xml-zip)]
+    {:meta  (meta->map root)
+     :files (mapv file->map (zip-xml/xml-> root :file))}))
+

Yay, our test passes again.

Query Predicates

There are a few other useful functions in the clojure.data.zip.xml +ns we haven't yet looked at, namely: text=, attr=, and tag=. +These functions allow you to construct query predicates to run against +a given node. As an example, let's pull out the first file segment +from the example.nzb file using the attr= function:

(zip-xml/xml1-> root
+                :file
+                :segments
+                :segment
+                (zip-xml/attr= :number "1"))
+                zip-xml/text)
+"123456789abcdef@news.newzbin.com"
+

From the root node of the document we reach down into :file, +:segments, and :segment in turn, then use the attr= query +predicate to match a :segment with a value of "1".

Interestingly enough, the other two query predicates have shortcuts +for their use. You have already been using the tag= query predicate +every time you use a keyword to locate a tag. To use the text= +predicate easily, just use a string. For example, to retrieve the +second :segment based on its content of +987654321fedbca@news.newzbin.com:

(zip-xml/xml1-> root
+                :file
+                :segments
+                :segment
+                "987654321fedbca@news.newzbin.com")
+;; ... the resulting node
+

Finally, you can combine these query predicates to match multiple +things on a given node by using a vector:

(zip-xml/xml1-> root
+                :file
+                :segments
+                :segment
+                [(zip-xml/attr= :number "1")
+                 (zip-xml/attr= :bytes "102394")]
+                zip-xml/text)
+"123456789abcdef@news.newzbin.com"
+

Here we are matching on both the :number attribute being "1", and +the :bytes attribute being "102394". Obviously, you can use +strings here to match against content too.

Creating New Predicates

OK, now let's suppose we want to use some kind of numerical comparison +in our XML (like we might do with XPath). As it stands, we have no way +to do that with the built-in functions but we can easily define our +own.

Let's start with a general function for comparing attribute values:

(defn attr-fn
+  [attrname f test-val & [conv-fn]]
+  (fn [loc]
+    (let [conv-fn (or conv-fn identity)
+          val (conv-fn (zip-xml/attr loc attrname))]
+      (f val test-val))))
+

This function takes an attribute name (attrname), a function for +making a comparison (f), a value to test agains (test-val) and +optionally a conversion function. Imagine our example.nzb file had +100 segments, and we only wanted to get segments over 75. We could now +achieve this using our general function:

(zip-xml/xml-> root
+               :file
+               :segments
+               :segment
+               (attr-fn :number > 75 #(Long/valueOf %))
+               zip-xml/text)
+

Let's provide a helper for this to make the syntax clearer:

(defn attr>
+  [attrname val]
+  (attr-fn attrname > val #(Long/valueOf %)))
+
+(zip-xml/xml-> doc
+               :file
+               :segments
+               :segment
+               (attr> :number 75)
+               zip-xml/text)
+

We could build a whole suite of helper functions for examining XML +nodes, if we are unlucky enough to be required to do so :)

Conclusion

I hope these simple examples have given you an idea of the ease with +which you can process XML using Clojure, and how simple it is to +extend the tools already provded in interesting directions.

Contributors

Gareth Jones, 2012 (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/articles/tutorials/vim_fireplace/index.html b/clones/clojure-doc.org/articles/tutorials/vim_fireplace/index.html new file mode 100644 index 00000000..1c62c093 --- /dev/null +++ b/clones/clojure-doc.org/articles/tutorials/vim_fireplace/index.html @@ -0,0 +1,271 @@ + + + + + Clojure Guides: Clojure with Vim and fireplace.vim + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+ + +

This work is licensed under a Creative Commons +Attribution 3.0 Unported License (including images & +stylesheets). The source is available on +Github.

Overview

fireplace.vim is a Vim plugin developed by Tim Pope which provides support for the "dynamic" aspects of Clojure development. Namely, connection to an nREPL server, code evaluation, code completion, and basically everything beyond syntax highlighting and indentation.

This guide will cover installation and some basic usage within a typical Clojure project.

About the Name

fireplace was once called foreplay, but people weren't ready for that, so now it's fireplace

What About VimClojure?

Until recently (late 2012), VimClojure was the preeminent plugin for Clojure development in Vim. Since then, its developer, Meikel Brandmeyer, has acknowledged that VimClojure development has slowed to a trickle and that fireplace is the future. That said, VimClojure is still a viable and excellent development evironment.

What Versions of Clojure and fireplace Does This Guide Cover?

This guide covers Clojure 1.4 and the latest version of fireplace as of January 2013. It should work on most versions of both.

Essential References

fireplace.vim lives on github. That's the source of truth for development and where issues should be reported.

The vimclojure mailing list remains the primary place to get help and ask questions related to Clojuring in Vim.

Finally, don't forget the documentation that comes with the plugin itself. All features are documented there in standard Vim help format. Just :help fireplace, or view it online. I'm dead serious. READ THIS FILE.

How fireplace.vim Works

Before using fireplace, it's useful to have a basic understanding of how it works, especially when it comes to evaluating Clojure code. This will help avoid confusion and tears. fireplace itself is a collection of VimScript code running withing Vim. When it needs to evaluate some Clojure code (for example, you just required a namespace, or gave it a command to run the tests in a namespace) it sends commands to an nREPL server embedded in a Java Virtual Machine (JVM).

Note that because fireplace evaluates code synchronously, so if you evaluate a long-running command, your entire Vim process will be blocked/frozen until the operation completes. More on this below.

Usually the task of running an nREPL server falls to Leiningen, but fireplace can connect to any nREPL server. See the nREPL docs for details.

Installing Vim

TODO: Someone should write Vim installation instructions and basic usage here.

OSX

  • Install Homebrew
  • The dance: brew update
  • If you're like me, you tend to inspect a homebrew formula's options before installing: brew options macvim
  • And if you're like me: brew install --override-system-vim macvim
  • Optionally you can: brew linkapps which will, by default, create a symlink to MacVim.app in ~/Applications.
  • Assuming your PATH is set correctly, you can run vim from the command line by typing mvim
  • If you'd rather launch it from the dock, you can navigate to ~/Applications and double-click MacVim.app assuming you've run brew linkapps

Debian/Ubuntu

  • Install: sudo apt-get install vim
  • Create your .vimrc and a couple of vim-related dirs: +
    • touch ~/.vimrc && mkdir ~/.vim && mkdir ~/.vim/bundle
  • Install pathogen to make the future of vim plugin installs a breeze.
  • Enjoy the wonderful world of vim.

Windows

  • Search and install gvim anywhere on your computer.
  • Make sure that echo %HOME% and echo %userprofile% is set to something typical as C:\Users\user.
  • Check your vim runtimepath with :echo &rtp in vim. This is where your vim searches.
  • Note: The UNIX .vimrc is the windows_vimrc and the UNIX .vim is the Windows vimfiles!
  • Now make sure that both .vimrc and vimfiles live in the desired location (as e.g. C:\Users\user) so that the vim runtimepath can find it.
  • Test it by putting something as A) in the _vimrc as set number and as B) in the vimfiles\colors\ as the solarized color scheme (and refer to it in _vimrc with colorscheme solarized).

Installing fireplace.vim

Because fireplace.vim handles only the dynamic aspects of Clojure development, a separate plugin, vim-clojure-static (extracted from VimClojure and maintained by Sung Pae) includes support for syntax highlighting, indentation, etc. You'll want to install both for a pleasant experience.

Installation is covered thoroughly in the fireplace README. Since it's likely to be most up-to-date, we'll defer to it for purposes of installation.

Once installed, there's really nothing to configure. Yay!

Vim Basics

vimtutor is a ~30 minute tutorial on the bare basics of using Vim. It is included with Vim and it will get your some real experience editing text with Vim.

On Unix-based systems(ie: Mac, Linux), if Vim has been properly installed, you can start vimtutor from the shell.

On MS-Windows you can find it in the Program/Vim menu or execute vimtutor.bat from your Vim installation directory.

For more information on vimtutor and how to use it on other platforms, run :help tutor inside vim.

It is also recommended to have a cheat sheet handy when starting out so you have the commands in front of you if you need them. There are a lot of options available, but this one is fairly clean and makes a lot of sense after running through vimtutor.

Basics

Let's go through the process of creating a simple project to demonstrate some of fireplace.vim's capabilities. +Because this author is a little lazy, we'll use the same example as the emacs tutorial. That is, a simple +command-line argument parser.

First, we'll need a new project:

$ lein new command-line-args
+$ cd command-line-args
+

Now we need to start up Vim as well as the nREPL server. Luckily, just running the Leiningen 2 REPL will start up a server for us. If you're using console Vim, I suggest running +each in its own console.

In console 1:

$ lein repl
+nREPL server started on port 58197
+... REPL help message elided ...
+user=>
+

Nice. And in console 2:

$ vim
+

If you're using gvim, just start gvim and then run the REPL:

$ gvim
+$ lein repl
+nREPL server started on port 58197
+... REPL help message elided ...
+user=>
+

fireplace.vim will automatically figure out the nREPL port from the target/repl-port file written by Leiningen.

Now we can start editing code (see Editing below for tips on effectively editing Clojure code in Vim).

Let's add a simple test. Execute :e test/command_line_args/core_test.clj, enter insert mode and add the following to the file:

(deftest pairs-of-values
+   (let [args ["--server" "localhost"
+               "--port" "8080"
+               "--environment" "production"]]
+      (is (= {:server "localhost"
+              :port "8080"
+              :environment "production"}
+              (parse-args args)))))
+

To run the test, save the file, :w, and now we'll invoke our first fireplace.vim command, cpr. All commands are run in normal mode, so bang on escape a few times first. This performs a (require ... :reload) on the current buffer/namespace. Here we don't even get a chance to run the test. The code doesn't even compile because command-line-args.core/parse-args hasn't been defined yet. Let's fix that.

Note: Anytime fireplace reports an exception in a namespace, you can get the full stack trace by opening Vim's "location list" with :lopen. Hit enter on a Clojure stack frame to jump to the relevant source.

The easiest way to get to the command-line-args.core namespace is to put your cursor on command-line-args.core in the ns declaration at the top of the file and hit gf. This key combination will open the file for the namespace under the cursor. It even works for namespaces in jar files!

Next add the following definition in the command-line-args.core namespace:

(defn parse-args [args]
+  {})
+

Tip: Use ctrl-w f (ctrl-w followed by the f key) to split the view into two windows opening the file under the cursor in a new split.

Save the file, :w, and then switch back to test/command_line_args/core_test.clj. Now we can try requiring the test namespace again. This time we'll type :Require!, which performs a (require ... :reload-all) on the current namespace. That should succeed, so we can run the tests with the command :Eval (clojure.test/run-tests) which will print out a test failure with something like this:

Testing command-line-args.core-test
+
+FAIL in (pairs-of-values) (core_test.clj:9)
+expected: (= {:server "localhost", :port "8080", :environment "production"} (parse-args args))
+  actual: (not (= {:server "localhost", :environment "production", :port "8080"} {}))
+
+Ran 1 tests containing 1 assertions.
+1 failures, 0 errors.
+{:type :summary, :pass 0, :test 1, :error 0, :fail 1}
+

Note that we know a few fireplace commands now:

  • gf - Jumps to the namespace under the cursor
  • cpr and :Require! - (require :reload) or (require :reload-all) the current namespace.
  • :Eval (clojure code) - Evaluate arbitrary Clojure code in the current namespace.
  • :lopen - Not really a fireplace command, but it opens the stacktrace for the last exception in the buffer.

Now we can fix some errors. Return to command-line-args.core and edit:

(defn parse-args [args]
+  (apply hash-map args))
+

Running our tests again we get another error:

Testing command-line-args.core-test
+
+FAIL in (pairs-of-values) (core_test.clj:9)
+expected: (= {:server "localhost", :port "8080", :environment "production"} (parse-args args))
+  actual: (not (= {:server "localhost", :environment "production", :port "8080"} {"--port"
+ "8080", "--server" "localhost", "--environment" "production"}))
+
+Ran 1 tests containing 1 assertions.
+1 failures, 0 errors.
+{:type :summary, :pass 0, :test 1, :error 0, :fail 1}
+

We need to strip off those dashes and turn them into keywords. Back to core.clj again. Let's take a different route this time. Put your cursor on parse-args in the test file and hit ] ctrl-D (two keystrokes). That jumps right to parse-args. Now we can fix it up:

(defn parse-args [args]
+  (into {} (map (fn [[k v]] [(keyword (.replace k "--" "")) v])
+                (partition 2 args))))
+

and the test passes.

Tip: During testing you may get into the situation where you've deleted an old, possibly failing, test, yet it still runs because it's still in memory. Supposing the name of the test is a-test, you have a few options:

  • Hit cqp (or use :Eval) and run (ns-unmap *ns* 'a-test) to remove the test from the namespace.
  • Restart the Leiningen REPL. fireplace will re-initialize the connection the next time you run a command.

Wondering what clojure.core/ns-unmap does? In fireplace, use the command :Doc ns-unmap to see the docstring. If a symbol's under your cursor you can just hit shift-K to do the same thing.

The Quasi-REPL and Evaluating Code

Note we've learned another handy command, cqp, which opens fireplace's "quasi-repl" where you can execute Clojure code in the current namespace. Tab-completion and command history are supported there as you'd expect. If you need to do a little more editing or you'd like to edit and re-run a previous command, hit cqc to bring up a command-line window similar to what you'd get with q: in normal Vim.

Many times you'd like to just evaluate some snippet of code. fireplace.vim really shines here because it brings idiomatic Vim to bear on the problem. For example, it's common to have a snippet of test code you're playing with in a namespace, often in a (comment ) at the end of the file. Let's say we have something like this:

(comment
+  (my-service-call (choose-server load-balancer)
+                   (normalize-request { ... request map ...})))
+

Say we wanted to evaluate the entire (my-service-call ...) expression. There are a few ways to do this:

  • Put the cursor on my-service-call and hit cpp. This evaluates the inner-most expression containing the cursor
  • Put the cursor on the opening paren and hit cp%. cp followed by a Vim text motion (see below) executes the text described by that motion. We could also do, for example cpiw (inner word) to look at the value of the symbol under the cursor.
  • Put the cursor on the opening paren and hit cq%. This will grab the text (the % text motion again) and pre-populate the command-line window (cqc above) with the expression.

With all that it's easy to see we can evaluate the whole my-service-call expression, or any of the sub-expressions in the comment. Furthermore, if you're code's all referentially transparent and everything, the cpX family of commands have cousins of the form c!X which replace the expression with its result.

The (non-quasi) REPL

Unlike VimClojure, fireplace.vim doesn't have an integrated REPL. I (DR) miss it a little, but REPL-y, the REPL that ships with Leiningen is very nice and since it's separated from Vim there's much less chance of locking up Vim with a long-running or infinite operation.

Keep in mind that the nREPL server (the lein REPL) and fireplace are both playing in the same JVM. fireplace can see changes you make in nREPL and vice versa. So you can make some changes, save and hit cpr to reload the namespace and switch over to the REPL and the changes will be there.

Editing

This section includes some tips on basic Clojure code editing in Vim.

TODO: Move this to a separate, more general doc?

"Words"

The vim-clojure-static plugin makes some minor adjustments to Vim's settings to improve the editing experience. In particular, it extends the notion of a "word" (:help word) to include additional characters like - (hyphen), . (dot), etc. This changes has a number of effects:

  • Insert mode code completion (ctrl-n and ctrl-p) will complete words with hyphens which is very common in Clojure code
  • The insanely useful, magical "star" (*) operator in normal mode will search for the full Clojure symbol under the cursor, including dots, hyphens, etc.
  • Word motions (:help w), include dots, hyphens, etc. So dw in normal mode will delete an entire Clojure symbol.

Wrangling Parentheses

The most effective way to edit Clojure code is structurally with paredit.vim, but if you don't have time to learn that, Vim still brings a lot to the table for dealing with all the parentheses in Clojure code.

First, obviously, the % motion (:help %) is very useful. In normal mode, put the cursor on an opening or closing paren and you can:

  • Hit % to jump to the matching paren.
  • Hit d% to delete the parens and everything they contain.
  • Hit y% to "yank"/copy the parens and everything in them.
  • Hit c% to delete the parens and the text they contain and start editing.
  • Hit v% to select the parens and the text they contain visually.

The % motion is useful, but it's often more convenient to work with Vim's "block" text object (:help text-objects). This manifests in two forms. First, ab ("all block") which is an entire form, including the parentheses. Second, ib ("inner block") which is all the text within the enclosing parentheses. So, put your cursor anywhere within some parentheses in normal mode and you can:

  • Hit dab ("delete all block") to delete the entire form.
  • Hit dib ("delete inner block") to delete everything inside the parens.
  • Hit cab ("change all block") to delete the entire form and enter insert mode.
  • Hit cib ("change inner block") to delete the contents of the form, preserving parens, and enter insert mode.
  • Hit yab ("yank all block") to copy the entire form including parens.
  • Hit yib ("yank inner block") to copy the everything inside the parens.

And so on. Getting these commands in muscle memory can really speed up working with Clojure forms.

Tip: Vim has text objects for blocks enclosed in square brackets (vectors), quotes (strings), curly braces (maps, sets) etc. They're all invaluable. :help text-objects !!!

Code Completion

Some code completion is available with fireplace. It is built using Vim's omni-complete +system. When typing a symbol, hit ctrl-x ctrl-o to start omni-complete. A popup with a +list of suggestions will appear. Use ctrl-n and ctrl-p to change the selection and hit +enter to expand a selection into the buffer.

Note that Vim's built-in code completion, ctrl-n and ctrl-p in insert mode, also work fine while editing Clojure code.

Getting Documentation

fireplace has handy shortcuts for getting documentation for Clojure functions:

  • shift-K: Lookup the doc string for the symbol under the cursor. Works for Java classes as well.
  • :Doc: Lookup the doc string for a symbol entered in a prompt. Works for Java classes as well.

And since source code is often the best/only documentation in Clojure:

  • [d: display the source for the symbol under the cursor
  • :Source: display the source code for a symbol entered in a prompt

Other Resources

Contributors

Dave Ray, 2013 (original author)

+ + +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/css/screen.css b/clones/clojure-doc.org/css/screen.css new file mode 100644 index 00000000..1bdb661a --- /dev/null +++ b/clones/clojure-doc.org/css/screen.css @@ -0,0 +1,168 @@ +h1, h2, h3, h4, h5, h6 { + font-family: 'Alegreya'; +} + +body { + color: #333; + background-color: #f2f2f2; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-size: 16px; +} + +.container { + max-width: 1000px; +} + +.right { + float: right; + text-align: right; +} + +.navbar { + border-radius: 0; + box-shadow: 0 0 0 0,0 6px 12px rgba(34,34,34,0.3); +} + +.navbar-default { + background-color: #428bca; + border: none; +} + +.navbar-default .navbar-brand { + color: #fff; + font-family: 'Alegreya'; +} + +.navbar-default .navbar-brand:hover { + color: #fff; +} + +.navbar-default .navbar-nav li a { + color: #fff; +} + +.navbar-default .navbar-nav li a:hover { + color: #fff; + background-color: #3d80ba; +} + +.navbar-default .navbar-nav .active a { + color: #fff; + background-color: #3d80ba; +} + +.navbar-default .navbar-toggle:hover{ + background-color: #3d80ba; +} + +.navbar-default .navbar-toggle .icon-bar { + background-color: #fff; +} + +#sidebar { + margin-left: 15px; + margin-top: 50px; +} + +#content { + background-color: #fff; + border-radius: 3px; + box-shadow: 0 0 0 0,0 6px 12px rgba(34,34,34,0.1); +} + +#content img { + max-width: 100%; + height: auto; +} + +footer { + font-size: 14px; + text-align: center; + padding-top: 75px; + padding-bottom: 30px; +} + +blockquote footer { + text-align: left; + padding-top: 0px; + padding-bottom: 0px; +} + +#post-tags { + margin-top: 30px; +} + +#prev-next { + padding: 15px 0; +} + +.post-header { + margin-bottom: 20px; +} +.post-header h2 { + font-size: 32px; +} + +#post-meta { + font-size: 14px; + color: rgba(0,0,0,0.4) +} + +#page-header { + border-bottom: 1px solid #dbdbdb; + margin-bottom: 20px; +} +#page-header h2 { + font-size: 32px; +} + +pre { + overflow-x: auto; +} +pre code { + display: block; + padding: 0.5em; + overflow-wrap: normal; + white-space: pre; +} + +code { + color: #428bca; +} + +pre, code, .hljs { + background-color: #f7f9fd; +} + +@media (min-width: 768px) { + .navbar { + min-height: 70px; + } + .navbar-nav>li>a { + padding: 30px 20px; + } + .navbar-default .navbar-brand { + font-size: 36px; + padding: 25px 15px; + } + #content{ + margin-top: 30px; + padding: 30px 40px; + } +} + +@media (max-width: 767px) { + body{ + font-size: 14px; + } + .navbar-default .navbar-brand { + font-size: 30px; + } + #content{ + padding: 15px; + } + #post-meta .right { + float:left; + text-align: left; + } +} diff --git a/clones/clojure-doc.org/index.html b/clones/clojure-doc.org/index.html new file mode 100644 index 00000000..550a0862 --- /dev/null +++ b/clones/clojure-doc.org/index.html @@ -0,0 +1,237 @@ + + + + + Clojure Guides + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+
+ +
+
+

Clojure Documentation

+

Welcome to the community-driven documentation site for the Clojure programming language.

+ + Get Started! ยป + See all content ยป + Contribute ยป + +
+
+ +
+
+

Essentials

+

Tutorials aimed at new users.

+
+ +
+

Language Guides

+

Comprehensive guides on every aspect of the core language.

+
+ +
+

Contributor-friendly

+

+ This material is not covered by the Clojure Contributor Agreement and is developed using pull-requests on GitHub. +

+
+
+ +
+
+

Ecosystem & Tools

+

Guides covering areas outside of the core language.

+
+ +
+

Tutorials and Cookbooks

+

Subject-specific tutorials and guides.

+
+ +
+

Interactive Examples

+

Klipse is used in several sections to provide + live, interactive code examples that you can edit to explore the concepts being + discussed. +

+
+
+
+ +
+ +
+
+ +
+ +
+
+
Copyright © 2021 Multiple Authors +

Powered by Cryogen

+
+ + + + + + + + diff --git a/clones/clojure-doc.org/js/highlight.pack.js b/clones/clojure-doc.org/js/highlight.pack.js new file mode 100644 index 00000000..acf70cc7 --- /dev/null +++ b/clones/clojure-doc.org/js/highlight.pack.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.7.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||R(i))return i}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):E(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":y.classPrefix,i='',i+n+o}function p(){var e,t,r,a;if(!E.k)return n(B);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)a+=n(B.substr(t,r.index-t)),e=g(E,r),e?(M+=e[1],a+=h(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return a+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?B+=n:(a.rE||a.eE||(B+=n),b(),a.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=i||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substr(O,I.index-O),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},a=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"
":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n,t,r,o,s,p=i(e);a(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&","<":"<",">":">"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},s=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];r.c=s;var i=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(s)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:s.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[i,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double else enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while nameof add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},r={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},t=e.inherit(r,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},n=e.inherit(a,{i:/\n/}),c={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,n]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},n]});a.c=[s,c,r,e.ASM,e.QSM,e.CNM,e.CBCM],n.c=[o,c,t,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,c,r,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+")\\s*",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",w="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",u=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+w+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(u).concat(d)}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*#]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:o}});hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-รฟ][a-zA-Z0-9_-รฟ]*"},i={cN:"meta",b:/<\?(php)?|\?>/},t={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[i]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},i,{cN:"keyword",b:/\$this\b/},c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,t,a]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},t,a]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U)?L?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:"<",e:">",i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("makefile",function(e){var a={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:"section",b:/^[\w]+:\s*$/},{cN:"meta",b:/^\.PHONY:/,e:/$/,k:{"meta-keyword":".PHONY"},l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,a]}]}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("python",function(e){var r={cN:"meta",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},l={cN:"params",b:/\(/,e:/\)/,c:["self",r,a,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,a,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,l,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("java",function(e){var t=e.UIR+"(<"+e.UIR+"(\\s*,\\s*"+e.UIR+")*>)?",a="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports",r="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",s={cN:"number",b:r,r:0};return{aliases:["jsp"],k:a,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:a,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:a,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},s,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\._]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}}); \ No newline at end of file diff --git a/clones/docs.racket-lang.org/local-redirect/local-redirect.js b/clones/docs.racket-lang.org/local-redirect/local-redirect.js index 0f5acdce..f8f9ed78 100644 --- a/clones/docs.racket-lang.org/local-redirect/local-redirect.js +++ b/clones/docs.racket-lang.org/local-redirect/local-redirect.js @@ -90,6 +90,7 @@ var link_dirs = [ ["bs", "../bs"], ["bug-report", "../bug-report"], ["buid", "../buid"], + ["bv", "../bv"], ["bzip2", "../bzip2"], ["c", "../c"], ["c-defs", "../c-defs"], @@ -153,6 +154,7 @@ var link_dirs = [ ["cpu-affinity", "../cpu-affinity"], ["cpuinfo", "../cpuinfo"], ["crc32c", "../crc32c"], + ["crontab-manual", "../crontab-manual"], ["crypto", "../crypto"], ["cs135-drtools", "../cs135-drtools"], ["cs2500f16-jsonlab", "../cs2500f16-jsonlab"], @@ -256,6 +258,7 @@ var link_dirs = [ ["ebml", "../ebml"], ["ebuild", "../ebuild"], ["ec", "../ec"], + ["eclass2scrbl", "../eclass2scrbl"], ["ecmascript", "../ecmascript"], ["ee-lib", "../ee-lib"], ["effection", "../effection"], @@ -296,6 +299,7 @@ var link_dirs = [ ["font-finder", "../font-finder"], ["for-helpers", "../for-helpers"], ["foreign", "../foreign"], + ["forged-ocelot", "../forged-ocelot"], ["formatted-string", "../formatted-string"], ["forms", "../forms"], ["forth", "../forth"], @@ -409,6 +413,7 @@ var link_dirs = [ ["inexact-number-lang", "../inexact-number-lang"], ["infix-manual", "../infix-manual"], ["infix-syntax", "../infix-syntax"], + ["ini", "../ini"], ["inside", "../inside"], ["interactive-brokers-api", "../interactive-brokers-api"], ["interconfection", "../interconfection"], @@ -492,6 +497,7 @@ var link_dirs = [ ["magenc", "../magenc"], ["magnolisp", "../magnolisp"], ["main", "../main"], + ["majordomo2", "../majordomo2"], ["make", "../make"], ["make-log-interceptor", "../make-log-interceptor"], ["manual-flomat", "../manual-flomat"], @@ -728,6 +734,7 @@ var link_dirs = [ ["racket-paint", "../racket-paint"], ["racket-quandl", "../racket-quandl"], ["racket-route-match", "../racket-route-match"], + ["racket-tree-sitter", "../racket-tree-sitter"], ["racket_turtle", "../racket_turtle"], ["racketscript", "../racketscript"], ["racketui", "../racketui"], @@ -801,6 +808,7 @@ var link_dirs = [ ["rokit-racket", "../rokit-racket"], ["roman-numeral", "../roman-numeral"], ["roomba", "../roomba"], + ["rosette-guide", "../rosette-guide"], ["routy", "../routy"], ["rparallel", "../rparallel"], ["rpn", "../rpn"], @@ -814,6 +822,7 @@ var link_dirs = [ ["ruckus", "../ruckus"], ["runomatic", "../runomatic"], ["russian", "../russian"], + ["russian-lang", "../russian-lang"], ["rws-html-template", "../rws-html-template"], ["rx-tx-async-channel", "../rx-tx-async-channel"], ["s3-sync", "../s3-sync"], @@ -1142,7 +1151,7 @@ function demand_load(p, callback) { var loaded_link_targets = []; var link_targets = []; -var num_link_target_bins = 20; +var num_link_target_bins = 21; function convert_all_links() { var elements = document.getElementsByClassName("Sq"); @@ -1166,7 +1175,7 @@ function convert_all_links() { } } if (tag) { - var v = hash_string(decodeURIComponent(tag[0].substring(4))) % 20; + var v = hash_string(decodeURIComponent(tag[0].substring(4))) % 21; if (!loaded_link_targets[v]) { loaded_link_targets[v] = true; var p = "../local-redirect/local-redirect_" + v + ".js"; diff --git a/clones/docs.racket-lang.org/reference/Building_New_Contract_Combinators.html b/clones/docs.racket-lang.org/reference/Building_New_Contract_Combinators.html new file mode 100644 index 00000000..342decb0 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Building_New_Contract_Combinators.html @@ -0,0 +1,313 @@ + +8.7 Building New Contract Combinators

8.7 Building New Contract Combinators

 (require racket/contract/combinator) package: base

procedure

(make-contract 
  [#:name name 
  #:first-order first-order 
  #:late-neg-projection late-neg-proj 
  #:collapsible-late-neg-projection collapsible-late-neg-proj 
  #:val-first-projection val-first-proj 
  #:projection proj 
  #:stronger stronger 
  #:equivalent equivalent 
  #:list-contract? is-list-contract?]) 
  contract?
  name : any/c = 'anonymous-contract
  first-order : (-> any/c any/c) = (λ (x) #t)
  late-neg-proj : (or/c #f (-> blame? (-> any/c any/c any/c)))
   = #f
  collapsible-late-neg-proj : (or/c #f (-> blame? (values (-> any/c any/c any/c) collapsible-contract?)))
   = #f
  val-first-proj : (or/c #f (-> blame? (-> any/c (-> any/c any/c))))
   = #f
  proj : (-> blame? (-> any/c any/c))
   = 
(λ (b)
  (λ (x)
    (if (first-order x)
      x
      (raise-blame-error
       b x
       '(expected: "~a" given: "~e")
       name x))))
  stronger : (or/c #f (-> contract? contract? boolean?)) = #f
  equivalent : (or/c #f (-> contract? contract? boolean?)) = #f
  is-list-contract? : boolean? = #f

procedure

(make-chaperone-contract 
  [#:name name 
  #:first-order first-order 
  #:late-neg-projection late-neg-proj 
  #:collapsible-late-neg-projection collapsible-late-neg-proj 
  #:val-first-projection val-first-proj 
  #:projection proj 
  #:stronger stronger 
  #:equivalent equivalent 
  #:list-contract? is-list-contract?]) 
  chaperone-contract?
  name : any/c = 'anonymous-chaperone-contract
  first-order : (-> any/c any/c) = (λ (x) #t)
  late-neg-proj : (or/c #f (-> blame? (-> any/c any/c any/c)))
   = #f
  collapsible-late-neg-proj : (or/c #f (-> blame? (values (-> any/c any/c any/c) collapsible-contract?)))
   = #f
  val-first-proj : (or/c #f (-> blame? (-> any/c (-> any/c any/c))))
   = #f
  proj : (-> blame? (-> any/c any/c))
   = 
(λ (b)
  (λ (x)
    (if (first-order x)
      x
      (raise-blame-error
       b x
       '(expected: "~a" given: "~e")
       name x))))
  stronger : (or/c #f (-> contract? contract? boolean?)) = #f
  equivalent : (or/c #f (-> contract? contract? boolean?)) = #f
  is-list-contract? : boolean? = #f

procedure

(make-flat-contract 
  [#:name name 
  #:first-order first-order 
  #:late-neg-projection late-neg-proj 
  #:collapsible-late-neg-projection collapsible-late-neg-proj 
  #:val-first-projection val-first-proj 
  #:projection proj 
  #:stronger stronger 
  #:equivalent equivalent 
  #:list-contract? is-list-contract?]) 
  flat-contract?
  name : any/c = 'anonymous-flat-contract
  first-order : (-> any/c any/c) = (λ (x) #t)
  late-neg-proj : (or/c #f (-> blame? (-> any/c any/c any/c)))
   = #f
  collapsible-late-neg-proj : (or/c #f (-> blame? (values (-> any/c any/c any/c) collapsible-contract?)))
   = #f
  val-first-proj : (or/c #f (-> blame? (-> any/c (-> any/c any/c))))
   = #f
  proj : (-> blame? (-> any/c any/c))
   = 
(λ (b)
  (λ (x)
    (if (first-order x)
      x
      (raise-blame-error
       b x
       '(expected: "~a" given: "~e")
       name x))))
  stronger : (or/c #f (-> contract? contract? boolean?)) = #f
  equivalent : (or/c #f (-> contract? contract? boolean?)) = #f
  is-list-contract? : boolean? = #f
These functions build simple higher-order contracts, chaperone contracts, +and flat contracts, respectively. They all take the same set of three +optional arguments: a name, a first-order predicate, and a blame-tracking projection. +For make-flat-contract, see also flat-contract-with-explanation.

The name argument is any value to be rendered using display to +describe the contract when a violation occurs. The default name for simple +higher-order contracts is anonymous-contract, for +chaperone contracts is anonymous-chaperone-contract, and for +flat contracts is anonymous-flat-contract.

The first-order predicate first-order is used to determine which values +the contract applies to. This test is used +by contract-first-order-passes?, and indirectly by or/c +and first-or/c to determine which higher-order contract to wrap a +value with when there are multiple higher-order contracts to choose from. +The default value accepts any value, but it must match the behavior of the +projection argument (see below for how). The predicate should be influenced by +the value of (contract-first-order-okay-to-give-up?) (see it’s documentation +for more explanation).

The late-neg-proj argument defines the behavior of applying + the contract via a late neg projection. If it is supplied, this + argument accepts a blame object that is missing one party (see also + blame-missing-party?). Then it must return a function that accepts + both the value that is getting the contract and the name of the missing blame + party, in that order. The result must either be the value (perhaps suitably + wrapped with a chaperone or impersonator to enforce the + contract), or signal a contract violation using raise-blame-error. + The default is #f.

The collapsible-late-neg-proj argument takes the place of the + late-neg-proj argument for contracts that support collapsing. + If it is supplied, this argument accepts a blame object that is + missing one party. It must return two values. The first value must be + a function that accepts both the value that is getting the contract and + the name of the missing blame party, in that order. The second value should + be a collapsible representation of the contract.

The projection proj and val-first-proj are older mechanisms for + defining the behavior of applying the contract. The proj argument +is a curried function of two arguments: the first application accepts a blame +object, and the second accepts a value to protect with the contract. The +projection must either produce the value, suitably wrapped to enforce any +higher-order aspects of the contract, or signal a contract violation using +raise-blame-error. The default projection produces an error when the +first-order test fails, and produces the value unchanged otherwise. +The val-first-proj is like late-neg-proj, except with +an extra layer of currying.

At least one of the late-neg-proj, proj, + val-first-proj, or first-order must be non-#f.

The projection arguments (late-neg-proj, proj, and + val-first-proj) must be in sync with the first-order argument. + In particular, if the first-order argument returns #f for some value, + then the projections must raise a blame error for that value and if the + first-order argument returns #t for some value, then the projection must + not signal any blame for this value, unless there are higher-order interactions + later. In other words, for flat contracts, the first-order and + projection arguments must check the same predicate. For convenience, the + the default projection uses the first-order argument, signalling an error + when it returns #f and never signalling one otherwise.

Projections for chaperone contracts must produce a value that passes +chaperone-of? when compared with the original, uncontracted value. +Projections for flat contracts must fail precisely when first-order +does, and must produce the input value unchanged otherwise. Applying a +flat contract may result in either an application of the predicate, or the +projection, or both; therefore, the two must be consistent. The existence of a +separate projection only serves to provide more specific error messages. Most +flat contracts do not need to supply an explicit projection.

The stronger argument is used to implement contract-stronger?. The +first argument is always the contract itself and the second argument is whatever +was passed as the second argument to contract-stronger?. If no +stronger argument is supplied, then a default that compares its arguments +with equal? is used for flat contracts and chaperone contracts. +For impersonator contracts constructed with make-contract that do not +supply the stronger argument, contract-stronger? returns #f.

Similarly, the equivalent argument is used to implement contract-equivalent?. +If it isn’t supplied or #false is supplied, then equal? is used +for chaperone and flat contracts, and (λ (x y) #f) is used otherwise.

The is-list-contract? argument is used by the list-contract? predicate +to determine if this is a contract that accepts only list? values.

Examples:
> (define int/c
    (make-flat-contract #:name 'int/c #:first-order integer?))
> (contract int/c 1 'positive 'negative)

1

> (contract int/c "not one" 'positive 'negative)

eval:4:0: broke its own contract

  promised: int/c

  produced: "not one"

  in: int/c

  contract from: positive

  blaming: positive

   (assuming the contract is correct)

> (int/c 1)

#t

> (int/c "not one")

#f

> (define int->int/c
    (make-contract
     #:name 'int->int/c
     #:first-order
     (λ (x) (and (procedure? x) (procedure-arity-includes? x 1)))
     #:projection
     (λ (b)
       (let ([domain ((contract-projection int/c) (blame-swap b))]
             [range ((contract-projection int/c) b)])
         (λ (f)
           (if (and (procedure? f) (procedure-arity-includes? f 1))
             (λ (x) (range (f (domain x))))
             (raise-blame-error
              b f
              '(expected "a function of one argument" given: "~e")
              f)))))))
> (contract int->int/c "not fun" 'positive 'negative)

eval:8:0: broke its own contract;

 promised a function of one argument

  produced: "not fun"

  in: int->int/c

  contract from: positive

  blaming: positive

   (assuming the contract is correct)

> (define halve
    (contract int->int/c (λ (x) (/ x 2)) 'positive 'negative))
> (halve 2)

1

> (halve 1/2)

halve: contract violation

  expected: int/c

  given: 1/2

  in: int->int/c

  contract from: positive

  blaming: negative

   (assuming the contract is correct)

> (halve 1)

halve: broke its own contract

  promised: int/c

  produced: 1/2

  in: int->int/c

  contract from: positive

  blaming: positive

   (assuming the contract is correct)

Changed in version 6.0.1.13 of package base: Added the #:list-contract? argument.
Changed in version 6.90.0.30: Added the #:equivalent argument.
Changed in version 7.1.0.10: Added the #:collapsible-late-neg-projection argument.

procedure

(build-compound-type-name c/s ...)  any

  c/s : any/c
Produces an S-expression to be used as a name +for a contract. The arguments should be either contracts or +symbols. It wraps parentheses around its arguments and +extracts the names from any contracts it is supplied with.

procedure

(coerce-contract id v)  contract?

  id : symbol?
  v : any/c
Converts a regular Racket value into an instance of a contract struct, +converting it according to the description of contracts.

If v is not one of the coercible values, +coerce-contract signals an error, using the first argument in +the error message.

procedure

(coerce-contracts id vs)  (listof contract?)

  id : symbol?
  vs : (listof any/c)
Coerces all of the arguments in vs into contracts (via +coerce-contract/f) and signals an error if any of them are not +contracts. The error messages assume that the function named by +id got vs as its entire argument list.

procedure

(coerce-chaperone-contract id v)  chaperone-contract?

  id : symbol?
  v : any/c
Like coerce-contract, but requires the result +to be a chaperone contract, not an arbitrary contract.

procedure

(coerce-chaperone-contracts id vs)

  (listof chaperone-contract?)
  id : symbol?
  vs : (listof any/c)
Like coerce-contracts, but requires the results +to be chaperone contracts, not arbitrary contracts.

procedure

(coerce-flat-contract id v)  flat-contract?

  id : symbol?
  v : any/c
Like coerce-contract, but requires the result +to be a flat contract, not an arbitrary contract.

procedure

(coerce-flat-contracts id v)  (listof flat-contract?)

  id : symbol?
  v : (listof any/c)
Like coerce-contracts, but requires the results +to be flat contracts, not arbitrary contracts.

procedure

(coerce-contract/f v)  (or/c contract? #f)

  v : any/c
Like coerce-contract, but returns #f if +the value cannot be coerced to a contract.

parameter

(skip-projection-wrapper?)  boolean?

(skip-projection-wrapper? wrap?)  void?
  wrap? : boolean?
 = #f
The functions make-chaperone-contract and +build-chaperone-contract-property wrap their +arguments to ensure that the result of the projections +are chaperones of the input. This layer of wrapping can, +in some cases, introduce unwanted overhead into contract +checking. If this parameter’s value is #t +during the dynamic extent of the call to either of those +functions, the wrapping (and thus the checks) are skipped.

syntax

(with-contract-continuation-mark blame body ...)

(with-contract-continuation-mark blame+neg-party body ...)
Inserts a continuation mark that informs the contract profiler (see +the contract profiling documentation) +that contract checking is happening. +For the costs from checking your new combinator to be included, you should wrap +any deferred, higher-order checks with this form. First-order checks are +recognized automatically and do not require this form.

If your combinator’s projections operate on complete blame objects (i.e., no +missing blame parties), the blame object should be the first argument to this +form. Otherwise (e.g., in the case of late-neg projections), a pair +of the blame object and the missing party should be used instead.

Added in version 6.4.0.4 of package base.

Some contract combinators need to build projections for +subcontracts with both regular and blame-swaped +versions of the blame that they are given in order to check +both access and mutations (e.g., vector/c and +vectorof). In the case that such combinators are +nested deeply inside each other, there is a potential for an +exponential explosion of nested projections being built.

To avoid that explosion, wrap each of the calls to the +blame-accepting portion of the combinator in +contract-pos/neg-doubling. It returns three values. +The first is a boolean, indicating how to interpret the +other two results. If the boolean is #t, then the +other two results are the values of e1 and +e2 and we are not too deep in the nesting. If the +boolean is #f, then we have passed a threshold and +it is not safe to evaluate e1 and e2 yet, +as we are in danger of running into the exponential +slowdown. In that case, the last two results are thunks +that, when invoked, compute the values of e1 and +e2.

As an example, vectorof uses +contract-pos/neg-doubling wrapping its two calls to +the blame-accepting part of the projection for its +subcontract. When it receives a #f as that first +boolean, it does not invoke the thunks right away, but waits +until the interposition procedure that it attaches to the +chaperoned vector is called. Then it invokes them (and caches +the result). This delays the construction of the projections +until they are actually needed, avoiding the exponential blowup.

Added in version 6.90.0.27 of package base.

8.7.1 Blame Objects

This section describes blame objects and operations on them.

procedure

(blame? v)  boolean?

  v : any/c
This predicate recognizes blame objects.

procedure

(raise-blame-error b    
  #:missing-party missing-party    
  v    
  fmt    
  v-fmt ...)  none/c
  b : blame?
  missing-party : #f
  v : any/c
  fmt : 
(or/c string?
      (listof (or/c string?
                    'given 'given:
                    'expected 'expected:)))
  v-fmt : any/c
Signals a contract violation. The first argument, b, records the +current blame information, including positive and negative parties, the name of +the contract, the name of the value, and the source location of the contract +application. The #:missing-party argument supplies one of the blame +parties. It should be non-#f when the b object was created +without supplying a negative party. See blame-add-missing-party and +the description of the late-neg-proj argument of make-contract.

The second positional argument, v, is the value that failed to +satisfy the contract.

The remaining arguments are a format string, +fmt, and its arguments, v-fmt ..., specifying an error message +specific to the precise violation.

If fmt is a list, then the elements are concatenated together +(with spaces added, unless there are already spaces at the ends of the strings), +after first replacing symbols with either their string counterparts, or +replacing 'given with "produced" and +'expected with "promised", depending on whether or not +the b argument has been swapped or not (see blame-swap).

If fmt contains the symbols 'given: or 'expected:, +they are replaced like 'given and 'expected are, but +the replacements are prefixed with the string "\n  " to conform +to the error message guidelines in Error Message Conventions.

procedure

(blame-add-context blame    
  context    
  [#:important important    
  #:swap? swap?])  blame?
  blame : blame?
  context : (or/c string? #f)
  important : (or/c string? #f) = #f
  swap? : boolean? = #f
Adds some context information to blame error messages + that explicates which portion of the contract failed + (and that gets rendered by raise-blame-error).

The context argument describes one layer of the + portion of the contract, typically of the form "the 1st argument of" + (in the case of a function contract) + or "a conjunct of" (in the case of an and/c contract).

For example, consider this contract violation: +
> (define/contract f
    (list/c (-> integer? integer?))
    (list (λ (x) x)))
> ((car f) #f)

f: contract violation

  expected: integer?

  given: #f

  in: the 1st argument of

      the 1st element of

      (list/c (-> integer? integer?))

  contract from: (definition f)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

It shows that the portion of the contract being violated is the first +occurrence of integer?, because the -> and +the list/c combinators each internally called +blame-add-context to add the two lines following +“in” in the error message.

The important argument is used to build the beginning part +of the contract violation. The last important argument that +gets added to a blame object is used. The class/c contract +adds an important argument, as does the -> contract (when +-> knows the name of the function getting the contract).

The swap? argument has the effect of calling blame-swap +while adding the layer of context, but without creating an extra +blame object.

Passing #f as the context string argument is no longer relevant. +For backwards compatibility, blame-add-context returns b +when context is #f.

Changed in version 6.90.0.29 of package base: The context argument being +#f is no longer relevant.

procedure

(blame-context blame)  (listof string?)

  blame : blame?
Returns the context information that would be supplied in +an error message, if blame is passed to raise-blame-error.

procedure

(blame-positive b)  any/c

  b : blame?

procedure

(blame-negative b)  any/c

  b : blame?
These functions produce printable descriptions of the current positive and +negative parties of a blame object.

procedure

(blame-contract b)  any/c

  b : blame?
This function produces a description of the contract associated with a blame +object (the result of contract-name).

procedure

(blame-value b)  any/c

  b : blame?
This function produces the name of the value to which the contract was applied, +or #f if no name was provided.

procedure

(blame-source b)  srcloc?

  b : blame?
This function produces the source location associated with a contract. If no +source location was provided, all fields of the structure will contain +#f.

procedure

(blame-swap b)  blame?

  b : blame?
This function swaps the positive and negative parties of a blame object. +(See also blame-add-context.)

procedure

(blame-original? b)  boolean?

  b : blame?

procedure

(blame-swapped? b)  boolean?

  b : blame?
These functions report whether the current blame of a given blame object is the +same as in the original contract invocation (possibly of a compound contract +containing the current one), or swapped, respectively. Each is the negation of +the other; both are provided for convenience and clarity.

procedure

(blame-replace-negative b neg)  blame?

  b : blame?
  neg : any/c
Produces a blame? object just like b except + that it uses neg instead of the negative + position b has.

procedure

(blame-replaced-negative? b)  boolean?

  b : blame?
Returns #t if b is the result of calling +blame-replace-negative (or the result of some other function +whose input was the result of blame-replace-negative).

procedure

(blame-update b pos neg)  blame?

  b : blame?
  pos : any/c
  neg : any/c
Produces a blame? object just like b except + that it adds pos and neg to the positive + and negative parties of b respectively.

procedure

(blame-missing-party? b)  boolean?

  b : blame?
Returns #t when b does not have both parties.

procedure

(blame-add-missing-party b missing-party)

  (and/c blame? (not/c blame-missing-party?))
  b : (and/c blame? blame-missing-party?)
  missing-party : any/c
Produces a new blame object like b, except that the missing +party is replaced with missing-party.

struct

(struct exn:fail:contract:blame exn:fail:contract (object)
    #:extra-constructor-name make-exn:fail:contract:blame)
  object : blame?
This exception is raised to signal a contract error. The object +field contains a blame object associated with a contract violation.

parameter

(current-blame-format)  (-> blame? any/c string? string?)

(current-blame-format proc)  void?
  proc : (-> blame? any/c string? string?)
A parameter that is used when constructing a +contract violation error. Its value is procedure that +accepts three arguments: +
  • the blame object for the violation,

  • the value that the contract applies to, and

  • a message indicating the kind of violation.

The procedure then +returns a string that is put into the contract error +message. Note that the value is often already included in +the message that indicates the violation.

Examples:
> (define (show-blame-error blame value message)
    (string-append
     "Contract Violation!\n"
     (format "Guilty Party: ~a\n" (blame-positive blame))
     (format "Innocent Party: ~a\n" (blame-negative blame))
     (format "Contracted Value Name: ~a\n" (blame-value blame))
     (format "Contract Location: ~s\n" (blame-source blame))
     (format "Contract Name: ~a\n" (blame-contract blame))
     (format "Offending Value: ~s\n" value)
     (format "Offense: ~a\n" message)))
> (current-blame-format show-blame-error)
> (define/contract (f x)
    (-> integer? integer?)
    (/ x 2))
> (f 2)

1

> (f 1)

Contract Violation!

Guilty Party: (function f)

Innocent Party: top-level

Contracted Value Name: f

Contract Location: #(struct:srcloc eval 4 0 4 1)

Contract Name: (-> integer? integer?)

Offending Value: 1/2

Offense: promised: integer?

  produced: 1/2

> (f 1/2)

Contract Violation!

Guilty Party: top-level

Innocent Party: (function f)

Contracted Value Name: f

Contract Location: #(struct:srcloc eval 4 0 4 1)

Contract Name: (-> integer? integer?)

Offending Value: 1/2

Offense: expected: integer?

  given: 1/2

8.7.2 Contracts as structs

The property prop:contract allows arbitrary structures to act as +contracts. The property prop:chaperone-contract allows arbitrary +structures to act as chaperone contracts; prop:chaperone-contract +inherits prop:contract, so chaperone contract structures may also act +as general contracts. The property prop:flat-contract allows arbitrary structures +to act as flat contracts; prop:flat-contract inherits both +prop:chaperone-contract and prop:procedure, so flat contract structures +may also act as chaperone contracts, as general contracts, and as predicate procedures.

These properties declare structures to be contracts or flat contracts, +respectively. The value for prop:contract must be a contract +property constructed by build-contract-property; likewise, the value +for prop:chaperone-contract must be a chaperone contract property +constructed by build-chaperone-contract-property and the value +for prop:flat-contract must be a flat contract property +constructed by build-flat-contract-property.

These properties attach a contract value to the protected structure, +chaperone, or impersonator value. The function has-contract? +returns #t for values that have one of these properties, and +value-contract extracts the value from the property (which +is expected to be the contract on the value).

These properties attach a blame information to the protected structure, +chaperone, or impersonator value. The function has-blame? +returns #t for values that have one of these properties, and +value-blame extracts the value from the property.

The value is expected to be the blame record for the contract on the value or +a cons-pair of a blame record with a missing party and the missing +party. The value-blame function reassembles the arguments of the pair +into a complete blame record using blame-add-missing-party. If +the value has one of the properties, but the value is not a blame object +or a pair whose car position is a blame object, then has-blame? +returns #f but value-blame returns #f.

procedure

(build-flat-contract-property 
  [#:name get-name 
  #:first-order get-first-order 
  #:late-neg-projection late-neg-proj 
  #:collapsible-late-neg-projection collapsible-late-neg-proj 
  #:val-first-projection val-first-proj 
  #:projection get-projection 
  #:stronger stronger 
  #:equivalent equivalent 
  #:generate generate 
  #:list-contract? is-list-contract?]) 
  flat-contract-property?
  get-name : (-> contract? any/c)
   = (λ (c) 'anonymous-flat-contract)
  get-first-order : (-> contract? (-> any/c boolean?))
   = (λ (c) (λ (x) #t))
  late-neg-proj : (or/c #f (-> contract? (-> blame? (-> any/c any/c any/c))))
   = #f
  collapsible-late-neg-proj : (or/c #f (-> contract? (-> blame? (values (-> any/c any/c any/c) collapsible-contract?))))
   = #f
  val-first-proj : (or/c #f (-> contract? blame? (-> any/c (-> any/c any/c))))
   = #f
  get-projection : (-> contract? (-> blame? (-> any/c any/c)))
   = 
(λ (c)
  (λ (b)
    (λ (x)
      (if ((get-first-order c) x)
          x
          (raise-blame-error
           b x '(expected: "~a" given: "~e")
           (get-name c) x)))))
  stronger : (or/c (-> contract? contract? boolean?) #f) = #f
  equivalent : (or/c #f (-> contract? contract? boolean?)) = #f
  generate : 
(->i ([c contract?])
     [generator
      (c)
      (-> exact-nonnegative-integer?
          (or/c (-> (or/c contract-random-generate-fail? c))
                #f))])
   = (λ (c) (λ (fuel) #f))
  is-list-contract? : (-> contract? boolean?) = (λ (c) #f)

procedure

(build-chaperone-contract-property 
  [#:name get-name 
  #:first-order get-first-order 
  #:late-neg-projection late-neg-proj 
  #:collapsible-late-neg-projection collapsible-late-neg-proj 
  #:val-first-projection val-first-proj 
  #:projection get-projection 
  #:stronger stronger 
  #:equivalent equivalent 
  #:generate generate 
  #:exercise exercise 
  #:list-contract? is-list-contract?]) 
  chaperone-contract-property?
  get-name : (-> contract? any/c)
   = (λ (c) 'anonymous-chaperone-contract)
  get-first-order : (-> contract? (-> any/c boolean?))
   = (λ (c) (λ (x) #t))
  late-neg-proj : (or/c #f (-> contract? (-> blame? (-> any/c any/c any/c))))
   = #f
  collapsible-late-neg-proj : (or/c #f (-> contract? (-> blame? (values (-> any/c any/c any/c) collapsible-contract?))))
   = #f
  val-first-proj : (or/c #f (-> contract? blame? (-> any/c (-> any/c any/c))))
   = #f
  get-projection : (-> contract? (-> blame? (-> any/c any/c)))
   = 
(λ (c)
  (λ (b)
    (λ (x)
      (if ((get-first-order c) x)
          x
          (raise-blame-error
           b x '(expected: "~a" given: "~e")
           (get-name c) x)))))
  stronger : (or/c (-> contract? contract? boolean?) #f) = #f
  equivalent : (or/c #f (-> contract? contract? boolean?)) = #f
  generate : 
(->i ([c contract?])
     [generator
      (c)
      (-> exact-nonnegative-integer?
          (or/c (-> (or/c contract-random-generate-fail? c))
                #f))])
   = (λ (c) (λ (fuel) #f))
  exercise : 
(->i ([c contract?])
     [result
      (c)
      (-> exact-nonnegative-integer?
          (values
           (-> c void?)
           (listof contract?)))])
   = (λ (c) (λ (fuel) (values void '())))
  is-list-contract? : (-> contract? boolean?) = (λ (c) #f)

procedure

(build-contract-property 
  [#:name get-name 
  #:first-order get-first-order 
  #:late-neg-projection late-neg-proj 
  #:collapsible-late-neg-projection collapsible-late-neg-proj 
  #:val-first-projection val-first-proj 
  #:projection get-projection 
  #:stronger stronger 
  #:equivalent equivalent 
  #:generate generate 
  #:exercise exercise 
  #:list-contract? is-list-contract?]) 
  contract-property?
  get-name : (-> contract? any/c) = (λ (c) 'anonymous-contract)
  get-first-order : (-> contract? (-> any/c boolean?))
   = (λ (c) (λ (x) #t))
  late-neg-proj : (or/c #f (-> contract? (-> blame? (-> any/c any/c any/c))))
   = #f
  collapsible-late-neg-proj : (or/c #f (-> contract? (-> blame? (values (-> any/c any/c any/c) collapsible-contract?))))
   = #f
  val-first-proj : (or/c #f (-> contract? blame? (-> any/c (-> any/c any/c))))
   = #f
  get-projection : (-> contract? (-> blame? (-> any/c any/c)))
   = 
(λ (c)
  (λ (b)
    (λ (x)
      (if ((get-first-order c) x)
          x
          (raise-blame-error
           b x '(expected: "~a" given: "~e")
           (get-name c) x)))))
  stronger : (or/c (-> contract? contract? boolean?) #f) = #f
  equivalent : (or/c #f (-> contract? contract? boolean?)) = #f
  generate : 
(->i ([c contract?])
     [generator
      (c)
      (-> exact-nonnegative-integer?
          (or/c (-> (or/c contract-random-generate-fail? c))
                #f))])
   = (λ (c) (λ (fuel) #f))
  exercise : 
(->i ([c contract?])
     [result
      (c)
      (-> exact-nonnegative-integer?
          (values
           (-> c void?)
           (listof contract?)))])
   = (λ (c) (λ (fuel) (values void '())))
  is-list-contract? : (-> contract? boolean?) = (λ (c) #f)
These functions build the arguments for prop:contract, +prop:chaperone-contract, and prop:flat-contract, respectively.

A contract property specifies the behavior of a structure when used as +a contract. It is specified in terms of seven properties: +
  • get-name which produces a description to write as part +of a contract violation;

  • get-first-order, which produces a first-order predicate to be +used by contract-first-order-passes?;

  • late-neg-proj, which produces a blame-tracking projection +defining the behavior of the contract (The get-projection +and val-first-proj arguments also specify the projection, +but using a different signature. They are here for backwards compatibility.);

  • collapsible-late-neg-proj, similar to late-neg-proj +which produces a blame-tracking projection defining the behavior of the +contract, this function additionally specifies the +collapsible behavior of the contract;

  • stronger, a predicate that determines whether this +contract (passed in the first argument) is stronger than some other +contract (passed in the second argument) and whose default always +returns #f;

  • equivalent, a predicate that determines whether this +contract (passed in the first argument) is equivalent to some other +contract (passed in the second argument); the default for flat +and chaperone contracts is equal? and for impersonator contracts +returns #f;

  • generate, which returns a thunk that generates random values +matching the contract (using contract-random-generate-fail) +to indicate failure) or #f to indicate that random +generation for this contract isn’t supported;

  • exercise, which returns a function that exercises values +matching the contract (e.g., if it is a function contract, it may call +the function) and a list of contracts whose values will be generated +by this process;

  • and is-list-contract?, which is used by flat-contract? +to determine if this contract accepts only list?s.

At least one of the late-neg-proj, collapsible-late-neg-proj, +get-projection, val-first-proj, or get-first-order +must be non-#f.

These accessors are passed as (optional) keyword arguments to +build-contract-property, and are applied to instances of the +appropriate structure type by the contract system. Their results are used +analogously to the arguments of make-contract.

A chaperone contract property specifies the behavior of a structure +when used as a chaperone contract. It is specified using +build-chaperone-contract-property, and accepts exactly the same set of +arguments as build-contract-property. The only difference is that the +projection accessor must return a value that passes chaperone-of? when +compared with the original, uncontracted value.

A flat contract property specifies the behavior of a structure when +used as a flat contract. It is specified using +build-flat-contract-property, and accepts similar +arguments as build-contract-property. The differences are: +
  • the projection accessor is expected not to wrap its argument in a +higher-order fashion, analogous to the constraint on projections in +make-flat-contract;

  • the #:exercise keyword argument is omitted because it is not +relevant for flat contracts.

Changed in version 6.0.1.13 of package base: Added the #:list-contract? argument.
Changed in version 6.1.1.4: Allow generate to return contract-random-generate-fail.
Changed in version 6.90.0.30: Added the #:equivalent argument.
Changed in version 7.1.0.10: Added the #:collapsible-late-neg-projection argument.

procedure

(contract-property? v)  boolean?

  v : any/c

procedure

(chaperone-contract-property? v)  boolean?

  v : any/c

procedure

(flat-contract-property? v)  boolean?

  v : any/c
These predicates detect whether a value is a contract property, +chaperone contract property, or a +flat contract property, respectively.

8.7.3 Obligation Information in Check Syntax

Check Syntax in DrRacket shows obligation information for +contracts according to syntax-propertys that the contract combinators +leave in the expanded form of the program. These properties indicate +where contracts appear in the source and where the positive and negative +positions of the contracts appear.

To make Check Syntax show obligation information for your new contract +combinators, use the following properties (some helper macros and functions +are below):

  • +
    'racket/contract:contract : (vector/c symbol? (listof syntax?) (listof syntax?))
    This property should be attached to the result of a transformer + that implements a contract combinator. It signals to Check Syntax + that this is where a contract begins.

    The first element in the + vector should be a unique (in the sense of eq?) value + that Check Syntax can use a tag to match up this contract with + its subpieces (specified by the two following syntax properties).

    The second and third elements of the vector are syntax objects + from pieces of the contract, and Check Syntax will color them. + The first list should contain subparts that are the responsibility + of parties (typically modules) that provide implementations of the contract. + The second list should contain subparts that are the + responsibility of clients.

    For example, in (->* () #:pre #t any/c #:post #t), + the ->* and the #:post should be in the first + list and #:pre in the second list.

  • +
    'racket/contract:negative-position : symbol?
    This property should be attached to sub-expressions of + a contract combinator that are expected to be other contracts. + The value of the property should be the key (the first element from + the vector for the 'racket/contract:contract property) + indicating which contract this is.

    This property should be used when the expression’s value is a contract + that clients are responsible for.

  • +
    'racket/contract:positive-position : symbol?
    This form is just like 'racket/contract:negative-position, + except that it should be used when the expression’s value is + a contract that the original party should be responsible for.

  • +
    'racket/contract:contract-on-boundary : symbol?
    The presence of this property tells Check Syntax that it + should start coloring from this point. It expects the expression + to be a contract + (and, thus, to have the 'racket/contract:contract property); + this property indicates that this contract is on a (module) boundary.

    (The value of the property is not used.)

  • +
    'racket/contract:internal-contract : symbol?
    Like 'racket/contract:contract-on-boundary, the presence + of this property triggers coloring, but this is meant for use + when the party (module) containing the contract (regardless of whether + or not this module exports anything matching the contract) + can be blamed for violating the contract. This comes into play + for ->i contracts, since the contract itself has + access to values under contract via the dependency.

syntax

(define/final-prop header body ...)

 
header = main-id
  | (main-id id ...)
  | (main-id id ... . id)
The same as (define header body ...), except that uses of + main-id in the header are annotated + with the 'racket/contract:contract property + (as above).

syntax

(define/subexpression-pos-prop header body ...)

 
header = main-id
  | (main-id id ...)
  | (main-id id ... . id)
The same as (define header body ...), except that uses of + main-id in the header are annotated + with the 'racket/contract:contract property + (as above) and arguments are annotated with the + 'racket/contract:positive-position property.

8.7.4 Utilities for Building New Combinators

procedure

(contract-stronger? c1 c2)  boolean?

  c1 : contract?
  c2 : contract?
Returns #t if the contract c1 accepts either fewer + or the same set of values that c2 does.

Chaperone contracts and flat contracts that are the same + (i.e., where c1 is equal? to c2) are + considered to always be stronger than each other.

This function is conservative, so it may return #f when + c1 does, in fact, accept fewer values.

Examples:
> (contract-stronger? integer? integer?)

#t

> (contract-stronger? (between/c 25 75) (between/c 0 100))

#t

> (contract-stronger? (between/c 0 100) (between/c 25 75))

#f

> (contract-stronger? (between/c -10 0) (between/c 0 10))

#f

> (contract-stronger? (λ (x) (and (real? x) (<= x 0)))
                      (λ (x) (and (real? x) (<= x 100))))

#f

procedure

(contract-equivalent? c1 c2)  boolean?

  c1 : contract?
  c2 : contract?
Returns #t if the contract c1 accepts the same + set of values that c2 does.

Chaperone contracts and flat contracts that are the same + (i.e., where c1 is equal? to c2) are + considered to always be equivalent to each other.

This function is conservative, so it may return #f when + c1 does, in fact, accept the same set of values that c2 does.

Examples:
> (contract-equivalent? integer? integer?)

#t

> (contract-equivalent? (non-empty-listof integer?)
                        (cons/c integer? (listof integer?)))

#t

> (contract-equivalent? (λ (x) (and (real? x) (and (number? x) (>= (sqr x) 0))))
                        (λ (x) (and (real? x) (real? x))))

#f

Added in version 6.90.0.30 of package base.

procedure

(contract-first-order-passes? contract v)  boolean?

  contract : contract?
  v : any/c
Returns a boolean indicating whether the first-order tests +of contract pass for v.

If it returns #f, the contract is guaranteed not to +hold for that value; if it returns #t, the contract +may or may not hold. If the contract is a first-order +contract, a result of #t guarantees that the +contract holds.

See also contract-first-order-okay-to-give-up? and +contract-first-order-try-less-hard.

procedure

(contract-first-order c)  (-> any/c boolean?)

  c : contract?
Produces the first-order test used by or/c to match values to +higher-order contracts.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Byte_and_String_Input.html b/clones/docs.racket-lang.org/reference/Byte_and_String_Input.html new file mode 100644 index 00000000..8638c093 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Byte_and_String_Input.html @@ -0,0 +1,180 @@ + +13.2 Byte and String Input

13.2 Byte and String Input

procedure

(read-char [in])  (or/c char? eof-object?)

  in : input-port? = (current-input-port)
Reads a single character from inwhich may involve reading +several bytes to UTF-8-decode them into a character (see +Ports); a minimal number of bytes are read/peeked to +perform the decoding. If no bytes are available before an end-of-file, +then eof is returned.

Examples:
> (let ([ip (open-input-string "S2")])
    (print (read-char ip))
    (newline)
    (print (read-char ip))
    (newline)
    (print (read-char ip)))

#\S

#\2

#<eof>

> (let ([ip (open-input-bytes #"\316\273")])
    ; The byte string contains UTF-8-encoded content:
    (print (read-char ip)))

#\λ

procedure

(read-byte [in])  (or/c byte? eof-object?)

  in : input-port? = (current-input-port)
Reads a single byte from in. If no bytes are available before +an end-of-file, then eof is returned.

Examples:
> (let ([ip (open-input-string "a")])
    ; The two values in the following list should be the same.
    (list (read-byte ip) (char->integer #\a)))

'(97 97)

> (let ([ip (open-input-string (string #\λ))])
    ; This string has a two byte-encoding.
    (list (read-byte ip) (read-byte ip) (read-byte ip)))

'(206 187 #<eof>)

procedure

(read-line [in mode])  (or/c string? eof-object?)

  in : input-port? = (current-input-port)
  mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'linefeed
Returns a string containing the next line of bytes from in.

Characters are read from in until a line separator or an +end-of-file is read. The line separator is not included in the result +string (but it is removed from the port’s stream). If no characters +are read before an end-of-file is encountered, eof is +returned.

The mode argument determines the line separator(s). It +must be one of the following symbols:

  • 'linefeed breaks lines on linefeed characters.

  • 'return breaks lines on return characters.

  • 'return-linefeed breaks lines on +return-linefeed combinations. If a return character is not followed +by a linefeed character, it is included in the result string; +similarly, a linefeed that is not preceded by a return is included +in the result string.

  • 'any breaks lines on any of a return +character, linefeed character, or return-linefeed combination. If a +return character is followed by a linefeed character, the two are +treated as a combination.

  • 'any-one breaks lines on either a return or +linefeed character, without recognizing return-linefeed +combinations.

Return and linefeed characters are detected after the conversions that +are automatically performed when reading a file in text mode. For +example, reading a file in text mode on Windows automatically +changes return-linefeed combinations to a linefeed. Thus, when a file +is opened in text mode, 'linefeed is usually the appropriate +read-line mode.

Examples:
> (let ([ip (open-input-string "x\ny\n")])
    (read-line ip))

"x"

> (let ([ip (open-input-string "x\ny\n")])
    (read-line ip 'return))

"x\ny\n"

> (let ([ip (open-input-string "x\ry\r")])
    (read-line ip 'return))

"x"

> (let ([ip (open-input-string "x\r\ny\r\n")])
    (read-line ip 'return-linefeed))

"x"

> (let ([ip (open-input-string "x\r\ny\nz")])
    (list (read-line ip 'any) (read-line ip 'any)))

'("x" "y")

> (let ([ip (open-input-string "x\r\ny\nz")])
    (list (read-line ip 'any-one) (read-line ip 'any-one)))

'("x" "")

procedure

(read-bytes-line [in mode])  (or/c bytes? eof-object?)

  in : input-port? = (current-input-port)
  mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'linefeed
Like read-line, but reads bytes and produces a byte string.

procedure

(read-string amt [in])  (or/c string? eof-object?)

  amt : exact-nonnegative-integer?
  in : input-port? = (current-input-port)

To read an entire port as a string, use port->string.

Returns a string containing the next amt characters from +in.

If amt is 0, then the empty string is +returned. Otherwise, if fewer than amt characters are +available before an end-of-file is encountered, then the returned +string will contain only those characters before the end-of-file; that +is, the returned string’s length will be less than amt. (A +temporary string of size amt is allocated while reading the +input, even if the size of the result is less than amt +characters.) If no characters are available before an end-of-file, +then eof is returned.

If an error occurs during reading, some characters may be lost; that +is, if read-string successfully reads some characters before +encountering an error, the characters are dropped.

Example:
> (let ([ip (open-input-string "supercalifragilisticexpialidocious")])
    (read-string 5 ip))

"super"

procedure

(read-bytes amt [in])  (or/c bytes? eof-object?)

  amt : exact-nonnegative-integer?
  in : input-port? = (current-input-port)

To read an entire port as bytes, use port->bytes.

Like read-string, but reads bytes and produces a byte string.

Example:
> (let ([ip (open-input-bytes
                    (bytes 6
                           115 101 99 114 101
                           116))])
    (define length (read-byte ip))
    (bytes->string/utf-8 (read-bytes length ip)))

"secret"

procedure

(read-string! str [in start-pos end-pos])

  (or/c exact-nonnegative-integer? eof-object?)
  str : (and/c string? (not/c immutable?))
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (string-length str)
Reads characters from in like read-string, but puts +them into str starting from index start-pos +(inclusive) up to end-pos (exclusive). Like +substring, the exn:fail:contract exception is raised if +start-pos or end-pos is out-of-range for +str.

If the difference between start-pos and end-pos is +0, then 0 is returned and str is not +modified. If no bytes are available before an end-of-file, then +eof is returned. Otherwise, the return value is the number of +characters read. If m characters are read and +m<end-pos-start-pos, then str is +not modified at indices start-pos+m through +end-pos.

Example:
> (let ([buffer (make-string 10 #\_)]
        [ip (open-input-string "cketRa")])
    (printf "~s\n" buffer)
    (read-string! buffer ip 2 6)
    (printf "~s\n" buffer)
    (read-string! buffer ip 0 2)
    (printf "~s\n" buffer))

"__________"

"__cket____"

"Racket____"

procedure

(read-bytes! bstr [in start-pos end-pos])

  (or/c exact-nonnegative-integer? eof-object?)
  bstr : bytes?
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like read-string!, but reads bytes, puts them into a byte +string, and returns the number of bytes read.

Example:
> (let ([buffer (make-bytes 10 (char->integer #\_))]
        [ip (open-input-string "cketRa")])
    (printf "~s\n" buffer)
    (read-bytes! buffer ip 2 6)
    (printf "~s\n" buffer)
    (read-bytes! buffer ip 0 2)
    (printf "~s\n" buffer))

#"__________"

#"__cket____"

#"Racket____"

procedure

(read-bytes-avail! bstr [in start-pos end-pos])

  (or/c exact-nonnegative-integer? eof-object? procedure?)
  bstr : bytes?
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like read-bytes!, but returns without blocking after having +read the immediately available bytes, and it may return a procedure for +a “special” result. The read-bytes-avail! procedure blocks +only if no bytes (or specials) are yet available. Also unlike +read-bytes!, read-bytes-avail! never drops bytes; if +read-bytes-avail! successfully reads some bytes and then +encounters an error, it suppresses the error (treating it roughly like +an end-of-file) and returns the read bytes. (The error will be +triggered by future reads.) If an error is encountered before any +bytes have been read, an exception is raised.

When in produces a special value, as described in +Custom Ports, the result is a procedure of four +arguments. The four arguments correspond to the location of the +special value within the port, as described in +Custom Ports. If the procedure is called more than once +with valid arguments, the exn:fail:contract exception is raised. If +read-bytes-avail! returns a special-producing procedure, then +it does not place characters in bstr. Similarly, +read-bytes-avail! places only as many bytes into bstr +as are available before a special value in the port’s stream.

procedure

(read-bytes-avail!* bstr 
  [in 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? eof-object? procedure?)
  bstr : bytes?
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like read-bytes-avail!, but returns 0 immediately if +no bytes (or specials) are available for reading and the end-of-file +is not reached.

procedure

(read-bytes-avail!/enable-break bstr 
  [in 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? eof-object? procedure?)
  bstr : bytes?
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like read-bytes-avail!, but breaks are enabled during the +read (see also Breaks). If breaking is disabled +when read-bytes-avail!/enable-break is called, and if the +exn:break exception is raised as a result of the call, then +no bytes will have been read from in.

procedure

(peek-string amt skip-bytes-amt [in])  (or/c string? eof-object?)

  amt : exact-nonnegative-integer?
  skip-bytes-amt : exact-nonnegative-integer?
  in : input-port? = (current-input-port)
Similar to read-string, except that the returned characters +are peeked: preserved in the port for future reads and peeks. (More precisely, undecoded +bytes are left for future reads and peeks.) The skip-bytes-amt argument +indicates a number of bytes (not characters) in the input +stream to skip before collecting characters to return; thus, in total, +the next skip-bytes-amt bytes plus amt characters +are inspected.

For most kinds of ports, inspecting skip-bytes-amt bytes and +amt characters requires at least +skip-bytes-amt+amt bytes of memory overhead +associated with the port, at least until the bytes/characters are +read. No such overhead is required when peeking into a string port +(see String Ports), a pipe port (see +Pipes), or a custom port with a specific peek +procedure (depending on how the peek procedure is implemented; see +Custom Ports).

If a port produces eof mid-stream, attempts to skip beyond the +eof for a peek always produce eof until the eof is +read.

procedure

(peek-bytes amt skip-bytes-amt [in])  (or/c bytes? eof-object?)

  amt : exact-nonnegative-integer?
  skip-bytes-amt : exact-nonnegative-integer?
  in : input-port? = (current-input-port)
Like peek-string, but peeks bytes and produces a byte string.

procedure

(peek-string! str 
  skip-bytes-amt 
  [in 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? eof-object?)
  str : (and/c string? (not/c immutable?))
  skip-bytes-amt : exact-nonnegative-integer?
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (string-length str)
Like read-string!, but for peeking, and with a +skip-bytes-amt argument like peek-string.

procedure

(peek-bytes! bstr 
  skip-bytes-amt 
  [in 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? eof-object?)
  bstr : (and/c bytes? (not/c immutable?))
  skip-bytes-amt : exact-nonnegative-integer?
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like peek-string!, but peeks bytes, puts them into a byte +string, and returns the number of bytes read.

procedure

(peek-bytes-avail! bstr 
  skip-bytes-amt 
  [progress 
  in 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? eof-object? procedure?)
  bstr : (and/c bytes? (not/c immutable?))
  skip-bytes-amt : exact-nonnegative-integer?
  progress : (or/c progress-evt? #f) = #f
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like read-bytes-avail!, but for peeking, and with two extra +arguments. The skip-bytes-amt argument is as in +peek-bytes. The progress argument must be either +#f or an event produced by +port-progress-evt for in.

To peek, peek-bytes-avail! blocks until finding an +end-of-file, at least one byte (or special) past the skipped bytes, or +until a non-#f progress becomes ready. Furthermore, +if progress is ready before bytes are peeked, no bytes are +peeked or skipped, and progress may cut short the skipping +process if it becomes available during the peek attempt. Furthermore, +progress is checked even before determining whether the port +is still open.

The result of peek-bytes-avail! is 0 only in the +case that progress becomes ready before bytes are peeked.

procedure

(peek-bytes-avail!* bstr 
  skip-bytes-amt 
  [progress 
  in 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? eof-object? procedure?)
  bstr : (and/c bytes? (not/c immutable?))
  skip-bytes-amt : exact-nonnegative-integer?
  progress : (or/c progress-evt? #f) = #f
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like read-bytes-avail!*, but for peeking, and with +skip-bytes-amt and progress arguments like +peek-bytes-avail!. Since this procedure never blocks, it may +return before even skip-bytes-amt bytes are available from the +port.

procedure

(peek-bytes-avail!/enable-break bstr 
  skip-bytes-amt 
  [progress 
  in 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? eof-object? procedure?)
  bstr : (and/c bytes? (not/c immutable?))
  skip-bytes-amt : exact-nonnegative-integer?
  progress : (or/c progress-evt? #f) = #f
  in : input-port? = (current-input-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like read-bytes-avail!/enable-break, but for peeking, and +with skip-bytes-amt and progress arguments like +peek-bytes-avail!.

procedure

(read-char-or-special [in 
  special-wrap 
  source-name]) 
  (or/c char? eof-object? any/c)
  in : input-port? = (current-input-port)
  special-wrap : (or/c (any/c -> any/c) #f) = #f
  source-name : any/c = #f
Like read-char, but if the input port returns a +special value (through a value-generating procedure in a custom +port, where source-name is provided to the procedure; see +Custom Ports and Special Comments for details), +then the result of applying special-wrap to the +special value is returned. A #f value for +special-wrap is treated the same as the identity function.

Changed in version 6.8.0.2 of package base: Added the special-wrap and +source-name arguments.

procedure

(read-byte-or-special [in 
  special-wrap 
  source-name]) 
  (or/c byte? eof-object? any/c)
  in : input-port? = (current-input-port)
  special-wrap : (or/c (any/c -> any/c) #f) = #f
  source-name : any/c = #f
Like read-char-or-special, but reads and returns a byte +instead of a character.

Changed in version 6.8.0.2 of package base: Added the special-wrap and +source-name arguments.

procedure

(peek-char [in skip-bytes-amt])  (or/c char? eof-object?)

  in : input-port? = (current-input-port)
  skip-bytes-amt : exact-nonnegative-integer? = 0
Like read-char, but peeks instead of reading, and skips +skip-bytes-amt bytes (not characters) at the start of the +port.

procedure

(peek-byte [in skip-bytes-amt])  (or/c byte? eof-object?)

  in : input-port? = (current-input-port)
  skip-bytes-amt : exact-nonnegative-integer? = 0
Like peek-char, but peeks and returns a byte instead of a +character.

procedure

(peek-char-or-special [in 
  skip-bytes-amt 
  special-wrap 
  source-name]) 
  (or/c char? eof-object? any/c)
  in : input-port? = (current-input-port)
  skip-bytes-amt : exact-nonnegative-integer? = 0
  special-wrap : (or/c (any/c -> any/c) #f 'special) = #f
  source-name : any/c = #f
Like peek-char, but if the input port returns a non-byte +value after skip-bytes-amt byte positions, then the result +depends on special-wrap:

  • If special-wrap is #f, then the special value +is returned (as for read-char-or-special).

  • If special-wrap is a procedure, then it is applied the + special value to produce the result (as for + read-char-or-special).

  • If special-wrap is 'special, then +'special is returned in place of the special +value—without calling the special-value procedure that is +returned by the input-port implementation.

Changed in version 6.8.0.2 of package base: Added the special-wrap and +source-name arguments.
Changed in version 6.90.0.16: Added 'special as an option +for special-wrap.

procedure

(peek-byte-or-special [in 
  skip-bytes-amt 
  progress 
  special-wrap 
  source-name]) 
  (or/c byte? eof-object? any/c)
  in : input-port? = (current-input-port)
  skip-bytes-amt : exact-nonnegative-integer? = 0
  progress : (or/c progress-evt? #f) = #f
  special-wrap : (or/c (any/c -> any/c) #f 'special) = #f
  source-name : any/c = #f
Like peek-char-or-special, but peeks and returns a byte +instead of a character, and it supports a progress argument +like peek-bytes-avail!.

Changed in version 6.8.0.2 of package base: Added the special-wrap and +source-name arguments.
Changed in version 6.90.0.16: Added 'special as an option +for special-wrap.

Returns a synchronizable event (see Events) that +becomes ready for synchronization after any subsequent read +from in or after in is closed. After the event +becomes ready, it remains ready. The synchronization result of a progress event is the progress event itself.

procedure

(port-provides-progress-evts? in)  boolean

  in : input-port?
Returns #t if port-progress-evt can return an event +for in. All built-in kinds of ports support progress events, +but ports created with make-input-port (see +Custom Ports) may not.

procedure

(port-commit-peeked amt progress evt [in])  boolean?

  amt : exact-nonnegative-integer?
  progress : progress-evt?
  evt : evt?
  in : input-port? = (current-input-port)
Attempts to commit as read the first amt previously peeked +bytes, non-byte specials, and eofs from in, or the +first eof or special value peeked from +in. Mid-stream eofs can be +committed, but an eof when the port is exhausted does not +necessarily commit, since it does not correspond to data in the stream.

The read commits only if progress does not become ready first +(i.e., if no other process reads from in first), and only if +evt is chosen by a sync within +port-commit-peeked (in which case the event result is +ignored); the evt must be either a channel-put event, +channel, semaphore, semaphore-peek event, always event, or never +event. Suspending the thread that calls port-commit-peeked +may or may not prevent the commit from proceeding.

The result from port-commit-peeked is #t if data has been +committed, and #f otherwise.

If no data has been peeked from in and progress is +not ready, then exn:fail:contract exception is raised. If fewer than +amt items have been peeked at the current start of +in’s stream, then only the peeked items are committed as +read. If in’s stream currently starts at an eof or +a non-byte special value, then only the eof or special value +is committed as read.

If progress is not a result of port-progress-evt +applied to in, then exn:fail:contract exception is raised.

procedure

(byte-ready? [in])  boolean?

  in : input-port? = (current-input-port)
Returns #t if (read-byte in) would not block (at the +time that byte-ready? was called, at least). Equivalent to +(and (sync/timeout 0 in) #t).

The byte-ready? and char-ready? functions are +appropriate for relatively few applications, because ports are meant +to support streaming data among concurrent producers and consumers; +the fact that a byte or character is not ready in some instant does +not necessarily mean that the producer is finished supplying data. +(Also, if a port has multiple consumers, data might get consumed +between the time that a given process uses byte-ready? to +poll the port and the time that it reads data from the port.) Using +byte-ready? makes sense if you are implementing your own +scheduler or if you know that the port’s implementation and use are +particularly constrained.

procedure

(char-ready? [in])  boolean?

  in : input-port? = (current-input-port)
Returns #t if (read-char in) would not block (at the +time that char-ready? was called, at least). Depending on the +initial bytes of the stream, multiple bytes may be needed to form a +UTF-8 encoding.

See byte-ready? for a note on how byte-ready? and +char-ready? are rarely the right choice.

procedure

(progress-evt? v)  boolean?

  v : any/c
(progress-evt? evt in)  boolean?
  evt : progress-evt?
  in : input-port?
With one argument, returns #t is v is a progress evt +for some input port, #f otherwise.

With two arguments, returns #t if evt is a progress +event for in, #f otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Byte_and_String_Output.html b/clones/docs.racket-lang.org/reference/Byte_and_String_Output.html new file mode 100644 index 00000000..c024f38f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Byte_and_String_Output.html @@ -0,0 +1,64 @@ + +13.3 Byte and String Output

13.3 Byte and String Output

procedure

(write-char char [out])  void?

  char : char?
  out : output-port? = (current-output-port)
Writes a single character to out; more precisely, the bytes +that are the UTF-8 encoding of char are written to +out.

procedure

(write-byte byte [out])  void?

  byte : byte?
  out : output-port? = (current-output-port)
Writes a single byte to out.

procedure

(newline [out])  void?

  out : output-port? = (current-output-port)
The same as (write-char #\newline out).

procedure

(write-string str [out start-pos end-pos])

  exact-nonnegative-integer?
  str : string?
  out : output-port? = (current-output-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (string-length str)
Writes characters to out from str starting from +index start-pos (inclusive) up to end-pos +(exclusive). Like substring, the exn:fail:contract exception is raised +if start-pos or end-pos is out-of-range for +str.

The result is the number of characters written to out, which +is always (- end-pos start-pos).

If str is mutable, mutations after write-string +returns do not affect the characters written to out. (This +independence from mutation is not a special property of +write-string, but instead generally true of output +functions.)

procedure

(write-bytes bstr [out start-pos end-pos])

  exact-nonnegative-integer?
  bstr : bytes?
  out : output-port? = (current-output-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like write-string, but writes bytes instead of characters.

procedure

(write-bytes-avail bstr    
  [out    
  start-pos    
  end-pos])  exact-nonnegative-integer?
  bstr : bytes?
  out : output-port? = (current-output-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like write-bytes, but returns without blocking after writing +as many bytes as it can immediately flush. It blocks only if no bytes +can be flushed immediately. The result is the number of bytes written +and flushed to out; if start-pos is the same as +end-pos, then the result can be 0 (indicating a +successful flush of any buffered data), otherwise the result is between +1 and (- end-pos start-pos), inclusive.

The write-bytes-avail procedure never drops bytes; if +write-bytes-avail successfully writes some bytes and then +encounters an error, it suppresses the error and returns the number of +written bytes. (The error will be triggered by future writes.) If an +error is encountered before any bytes have been written, an exception +is raised.

procedure

(write-bytes-avail* bstr 
  [out 
  start-pos 
  end-pos]) 
  (or/c exact-nonnegative-integer? #f)
  bstr : bytes?
  out : output-port? = (current-output-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like write-bytes-avail, but never blocks, returns #f +if the port contains buffered data that cannot be written immediately, +and returns 0 if the port’s internal buffer (if any) is +flushed but no additional bytes can be written immediately.

procedure

(write-bytes-avail/enable-break bstr 
  [out 
  start-pos 
  end-pos]) 
  exact-nonnegative-integer?
  bstr : bytes?
  out : output-port? = (current-output-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like write-bytes-avail, except that breaks are enabled during +the write. The procedure provides a guarantee about the interaction of +writing and breaks: if breaking is disabled when +write-bytes-avail/enable-break is called, and if the +exn:break exception is raised as a result of the call, then +no bytes will have been written to out. See also +Breaks.

procedure

(write-special v [out])  boolean?

  v : any/c
  out : output-port? = (current-output-port)
Writes v directly to out if the port supports +special writes, or raises exn:fail:contract if the port does +not support special write. The result is always #t, +indicating that the write succeeded.

procedure

(write-special-avail* v [out])  boolean?

  v : any/c
  out : output-port? = (current-output-port)
Like write-special, but without blocking. If v +cannot be written immediately, the result is #f without +writing v, otherwise the result is #t and v +is written.

procedure

(write-bytes-avail-evt bstr    
  [out    
  start-pos    
  end-pos])  evt?
  bstr : bytes?
  out : output-port? = (current-output-port)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Similar to write-bytes-avail, but instead of writing bytes +immediately, it returns a synchronizable event (see +Events). The out must support atomic writes, as +indicated by port-writes-atomic?.

Synchronizing on the object starts a write from bstr, and the +event becomes ready when bytes are written (unbuffered) to the +port. If start-pos and end-pos are the same, then +the synchronization result is 0 when the port’s internal +buffer (if any) is flushed, otherwise the result is a positive exact +integer. If the event is not selected in a synchronization, then no +bytes will have been written to out.

procedure

(write-special-evt v [out])  evt?

  v : any/c
  out : output-port? = (current-output-port)
Similar to write-special, but instead of writing the special +value immediately, it returns a synchronizable event (see +Events). The out must support atomic writes, as +indicated by port-writes-atomic?.

Synchronizing on the object starts a write of the special value, and +the event becomes ready when the value is written (unbuffered) to the +port. If the event is not selected in a synchronization, then no value +will have been written to out.

procedure

(port-writes-atomic? out)  boolean?

  out : output-port?
Returns #t if write-bytes-avail/enable-break can +provide an exclusive-or guarantee (break or write, but not both) for +out, and if the port can be used with procedures like +write-bytes-avail-evt. Racket’s file-stream ports, pipes, +string ports, and TCP ports all support atomic writes; ports created +with make-output-port (see Custom Ports) may +support atomic writes.

procedure

(port-writes-special? out)  boolean?

  out : output-port?
Returns #t if procedures like write-special can +write arbitrary values to the port. Racket’s file-stream ports, +pipes, string ports, and TCP ports all reject special values, but +ports created with make-output-port (see +Custom Ports) may support them.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Command-Line_Parsing.html b/clones/docs.racket-lang.org/reference/Command-Line_Parsing.html new file mode 100644 index 00000000..a2467400 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Command-Line_Parsing.html @@ -0,0 +1,152 @@ + +15.9 Command-Line Parsing

15.9 Command-Line Parsing

The bindings documented in this section are provided by the racket/cmdline and racket libraries, but not racket/base.

syntax

(command-line optional-name-expr optional-argv-expr
              flag-clause ...
              finish-clause)
 
optional-name-expr = 
  | #:program name-expr
     
optional-argv-expr = 
  | #:argv argv-expr
     
flag-clause = #:multi flag-spec ...
  | #:once-each flag-spec ...
  | #:once-any flag-spec ...
  | #:final flag-spec ...
  | #:usage-help string ...
  | #:help-labels string ...
  | #:ps string ...
     
flag-spec = (flags id ... help-spec body ...+)
  | (flags => handler-expr help-expr)
     
flags = flag-string
  | (flag-string ...+)
     
help-spec = string
  | (string-expr ...+)
     
finish-clause = 
  | #:args arg-formals body ...+
  | #:handlers handlers-exprs
     
arg-formals = rest-id
  | (arg ...)
  | (arg ...+ . rest-id)
     
arg = id
  | [id default-expr]
     
handlers-exprs = finish-expr arg-strings-expr
  | finish-expr arg-strings-expr help-expr
  | 
finish-expr arg-strings-expr help-expr
unknown-expr
Parses a command line according to the specification in the +flag-clauses.

The name-expr, if provided, should produce a path or string +to be used as the program name for reporting errors when the +command-line is ill-formed. It defaults to (find-system-path 'run-file). When a path is provided, only the last element of the +path is used to report an error.

The argv-expr, if provided, must evaluate to a list or a +vector of strings. It defaults to +(current-command-line-arguments).

The command-line is disassembled into flags, each possibly with +flag-specific arguments, followed by (non-flag) +arguments. Command-line strings starting with - or ++ are parsed as flags, but arguments to flags are never +parsed as flags, and integers and decimal numbers that start with +- or + are not treated as flags. Non-flag +arguments in the command-line must appear after all flags and the +flags’ arguments. No command-line string past the first non-flag +argument is parsed as a flag. The built-in -- flag signals the +end of command-line flags; any command-line string past the -- +flag is parsed as a non-flag argument.

A #:multi, #:once-each, #:once-any, or +#:final clause introduces a set of command-line flag +specifications. The clause tag indicates how many times the flag can +appear on the command line:

  • #:multi Each flag specified in the set can be +represented any number of times on the command line; i.e., the flags +in the set are independent and each flag can be used multiple times.

  • #:once-each Each flag specified in the set can be +represented once on the command line; i.e., the flags in the set are +independent, but each flag should be specified at most once. If a +flag specification is represented in the command line more than once, +the exn:fail exception is raised.

  • #:once-any Only one flag specified in the set can +be represented on the command line; i.e., the flags in the set are +mutually exclusive. If the set is represented in the command line +more than once, the exn:fail exception is raised.

  • #:final Like #:multi, except that no +argument after the flag is treated as a flag. Note that multiple +#:final flags can be specified if they have short names; for +example, if -a is a #:final flag, then -aa combines +two instances of -a in a single command-line argument.

A normal flag specification has four parts:

  • flags a flag string, or a set of flag strings. If +a set of flags is provided, all of the flags are equivalent. Each +flag string must be of the form +"-x" or +"+x" for some +character x, or +"--x" or +"++x" for some +sequence of characters x. An x cannot +contain only digits or digits plus a single decimal point, since +simple (signed) numbers are not treated as flags. In addition, the +flags "--", "-h", and "--help" are +predefined and cannot be changed.

  • ids — identifier that are bound to the flag’s +arguments. The number of identifiers determines how many arguments +can be provided on the command line with the flag, and the names of +these identifiers will appear in the help message describing the +flag. The ids are bound to string values in the +bodys for handling the flag.

  • help-spec a string or sequence of strings that +describes the flag. This string is used in the help message generated +by the handler for the built-in -h (or --help) flag. A +single literal string can be provided, or any number of expressions +that produce strings; in the latter case, strings after the first one +are displayed on subsequent lines.

  • bodys — expressions that are evaluated when one of +the flags appears on the command line. The flags are parsed +left-to-right, and each sequence of bodys is evaluated as +the corresponding flag is encountered. When the bodys are +evaluated, the preceding ids are bound to the arguments +provided for the flag on the command line.

A flag specification using => escapes to a more general +method of specifying the handler and help strings. In this case, the +handler procedure and help string list returned by +handler-expr and help-expr are used as in the +table argument of parse-command-line.

A #:usage-help clause inserts text lines immediately after +the usage line. Each string in the clause provides a separate line +of text.

A #:help-labels clause inserts text lines into the help table +of command-line flags. Each string in the clause provides a separate +line of text.

A #:ps clause inserts text lines at the end of the help +output. Each string in the clause provides a separate +line of text.

After the flag clauses, a final clause handles command-line arguments +that are not parsed as flags:

  • Supplying no finish clause is the same as supplying +#:args () (void).

  • For an #:args finish clause, identifiers in +arg-formals are bound to the leftover command-line strings +in the same way that identifiers are bound for a lambda +expression. Thus, specifying a single id (without +parentheses) collects all of the leftover arguments into a list. The +effective arity of the arg-formals specification determines +the number of extra command-line arguments that the user can provide, +and the names of the identifiers in arg-formals are used in +the help string. When the command-line is parsed, if the number of +provided arguments cannot be matched to identifiers in +arg-formals, the exn:fail exception is raised. Otherwise, +args clause’s bodys are evaluated to handle the +leftover arguments, and the result of the last body is the +result of the command-line expression.

  • A #:handlers finish clause escapes to a more general +method of handling the leftover arguments. In this case, the values +of the expressions are used like the last two to four arguments +parse-command-line.

Example:

(define verbose-mode (make-parameter #f))
(define profiling-on (make-parameter #f))
(define optimize-level (make-parameter 0))
(define link-flags (make-parameter null))
 
(define file-to-compile
  (command-line
   #:program "compiler"
   #:once-each
   [("-v" "--verbose") "Compile with verbose messages"
                       (verbose-mode #t)]
   [("-p" "--profile") "Compile with profiling"
                       (profiling-on #t)]
   #:once-any
   [("-o" "--optimize-1") "Compile with optimization level 1"
                          (optimize-level 1)]
   ["--optimize-2"        (; show help on separate lines
                           "Compile with optimization level 2,"
                           "which includes all of level 1")
                          (optimize-level 2)]
   #:multi
   [("-l" "--link-flags") lf ; flag takes one argument
                          "Add a flag <lf> for the linker"
                          (link-flags (cons lf (link-flags)))]
   #:args (filename) ; expect one command-line argument: <filename>
   ; return the argument as a filename to compile
   filename))

procedure

(parse-command-line name    
  argv    
  table    
  finish-proc    
  arg-help-strs    
  [help-proc    
  unknown-proc])  any
  name : (or/c string? path?)
  argv : (or/c (listof string?) (vectorof string?))
  table : (listof (cons/c symbol? list?))
  finish-proc : ((list?) () #:rest list? . ->* . any)
  arg-help-strs : (listof string?)
  help-proc : (string? . -> . any) = (lambda (str) ....)
  unknown-proc : (string? . -> . any) = (lambda (str) ...)
Parses a command-line using the specification in table. For +an overview of command-line parsing, see the command-line +form, which provides a more convenient notation for most purposes.

The table argument to this procedural form encodes the +information in command-line’s clauses, except for the +args clause. Instead, arguments are handled by the +finish-proc procedure, and help information about non-flag +arguments is provided in arg-help-strs. In addition, the +finish-proc procedure receives information accumulated while +parsing flags. The help-proc and unknown-proc +arguments allow customization that is not possible with +command-line.

When there are no more flags, finish-proc is called with a +list of information accumulated for command-line flags (see below) and +the remaining non-flag arguments from the command-line. The arity of +finish-proc determines the number of non-flag arguments +accepted and required from the command-line. For example, if +finish-proc accepts either two or three arguments, then +either one or two non-flag arguments must be provided on the +command-line. The finish-proc procedure can have any arity +(see procedure-arity) except 0 or a list of +0s (i.e., the procedure must at least accept one or more +arguments).

The arg-help-strs argument is a list of strings identifying +the expected (non-flag) command-line arguments, one for each +argument. If an arbitrary number of arguments are allowed, the last +string in arg-help-strs represents all of them.

The help-proc procedure is called with a help string if the +-h or --help flag is included on the command line. If an +unknown flag is encountered, the unknown-proc procedure is +called just like a flag-handling procedure (as described below); it +must at least accept one argument (the unknown flag), but it may also +accept more arguments. The default help-proc displays the +string and exits and the default unknown-proc raises the +exn:fail exception.

A table is a list of flag specification sets. Each set is +represented as a pair of two items: a mode symbol and a list of either +help strings or flag specifications. A mode symbol is one of +'once-each, 'once-any, 'multi, +'final, 'help-labels, 'usage-help, or +'ps with the same meanings as the corresponding clause tags +in command-line. For the 'help-labels, +'usage-help or 'ps mode, a list of help strings is +provided. For the other modes, a list of flag specifications is +provided, where each specification maps a number of flags to a single +handler procedure. A specification is a list of three items:

  • A list of strings for the flags defined by the spec. See +command-line for information about the format of flag +strings.

  • A procedure to handle the flag and its arguments when one of +the flags is found on the command line. The arity of this handler +procedure determines the number of arguments consumed by the flag: +the handler procedure is called with a flag string plus the next few +arguments from the command line to match the arity of the handler +procedure. The handler procedure must accept at least one argument to +receive the flag. If the handler accepts arbitrarily many arguments, +all of the remaining arguments are passed to the handler. A handler +procedure’s arity must either be a number or an +arity-at-least value.

    The return value from the handler is added to a list that is +eventually passed to finish-proc. If the handler returns +#<void>, no value is added onto this list. For all +non-#<void> values returned by handlers, the order of the +values in the list is the same as the order of the arguments on the +command-line.

  • A non-empty list for constructing help information for the +spec. The first element of the list describes the flag; it can be a +string or a non-empty list of strings, and in the latter case, each +string is shown on its own line. Additional elements of the main +list must be strings to name the expected arguments for the flag. The +number of extra help strings provided for a spec must match the +number of arguments accepted by the spec’s handler procedure.

The following example is the same as the core example for +command-line, translated to the procedural form:

(parse-command-line "compile" (current-command-line-arguments)
  `((once-each
     [("-v" "--verbose")
      ,(lambda (flag) (verbose-mode #t))
      ("Compile with verbose messages")]
     [("-p" "--profile")
      ,(lambda (flag) (profiling-on #t))
      ("Compile with profiling")])
    (once-any
     [("-o" "--optimize-1")
      ,(lambda (flag) (optimize-level 1))
      ("Compile with optimization level 1")]
     [("--optimize-2")
      ,(lambda (flag) (optimize-level 2))
      (("Compile with optimization level 2,"
        "which implies all optimizations of level 1"))])
    (multi
     [("-l" "--link-flags")
      ,(lambda (flag lf) (link-flags (cons lf (link-flags))))
      ("Add a flag <lf> for the linker" "lf")]))
   (lambda (flag-accum file) file)
   '("filename"))
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Delayed_Evaluation.html b/clones/docs.racket-lang.org/reference/Delayed_Evaluation.html new file mode 100644 index 00000000..c881d181 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Delayed_Evaluation.html @@ -0,0 +1,59 @@ + +10.3 Delayed Evaluation

10.3 Delayed Evaluation

The bindings documented in this section are provided by the racket/promise and racket libraries, but not racket/base.

A promise encapsulates an expression to be evaluated on +demand via force. After a promise has been forced, +every later force of the promise produces the same result.

procedure

(promise? v)  boolean?

  v : any/c
Returns #t if v is a promise, #f +otherwise.

syntax

(delay body ...+)

Creates a promise that, when forced, evaluates the +bodys to produce its value. The result is then cached, so +further uses of force produce the cached value immediately. +This includes multiple values and exceptions.

syntax

(lazy body ...+)

Like delay, if the last body produces a promise when +forced, then this promise is forced, too, to obtain a value. +In other words, this form creates a composable promise, where the +computation of its body is “attached” to the computation of the +following promise, and a single force iterates through the +whole chain, tail-calling each step.

Note that the last body of this form must produce a single +value, but the value can itself be a delay promise that +returns multiple values.

The lazy form is useful for implementing lazy libraries and +languages, where tail calls can be wrapped in a promise.

procedure

(force v)  any

  v : any/c
If v is a promise, then the promise is forced to obtain a +value. If the promise has not been forced before, then the result is +recorded in the promise so that future forces on the promise +produce the same value (or values). If forcing the promise raises an +exception, then the exception is similarly recorded so that forcing +the promise will raise the same exception every time.

If v is forced again before the original call to +force returns, then the exn:fail exception is raised.

If v is not a promise, then it is returned as the result.

procedure

(promise-forced? promise)  boolean?

  promise : promise?
Returns #t if promise has been forced.

procedure

(promise-running? promise)  boolean?

  promise : promise?
Returns #t if promise is currently being forced. +(Note that a promise can be either running or forced but not both.)

10.3.1 Additional Promise Kinds

syntax

(delay/name body ...+)

Creates a “call-by-name” promise that is similar to +delay-promises, except that the resulting value is not +cached. This kind of promise is essentially a thunk that is wrapped +in a way that force recognizes.

If a delay/name promise forces itself, no exception is +raised, the promise is never considered “running” or “forced” in +the sense of promise-running? and promise-forced?.

procedure

(promise/name? promise)  boolean?

  promise : any/c
Returns #t if promise is a promise created with delay/name. +

Added in version 6.3 of package base.

syntax

(delay/strict body ...+)

Creates a “strict” promise: it is evaluated immediately, and the +result is wrapped in a promise value. Note that the body can evaluate +to multiple values, and forcing the resulting promise will return these +values.

syntax

(delay/sync body ...+)

Produces a promise where an attempt to force the promise by a +thread other than one currently running the promise causes the +force to block until a result is available. This kind of +promise is also a synchronizable event for use with +sync; syncing on the promise does not force +it, but merely waits until a value is forced by another thread. +The synchronization result is #<void>.

If a promise created by delay/sync is forced on a thread that +is already running the promise, an exception is raised in the same way +as for promises created with delay.

syntax

(delay/thread body/option ...+)

 
body/option = body
  | #:group thread-group-expr
Like delay/sync, but begins the computation immediately on a +newly created thread. The thread is created under the thread +group specified by thread-group-expr, which defaults to +(make-thread-group). A #:group specification can +appear at most once.

Exceptions raised by the bodys are caught as usual and raised +only when the promise is forced. Unlike delay/sync, +if the thread running body terminates without producing a result +or exception, force of the promise raises an exception (instead +of blocking).

syntax

(delay/idle body/option ...+)

 
body/option = body
  | #:wait-for wait-evt-expr
  | #:work-while while-evt-expr
  | #:tick tick-secs-expr
  | #:use use-ratio-expr
Like delay/thread, but with the following differences:

  • the computation does not start until the event produced by +wait-evt-expr is ready, where the default is +(system-idle-evt);

  • the computation thread gets to work only when the process is +otherwise idle as determined by while-evt-expr, which +also defaults to (system-idle-evt);

  • the thread is allowed to run only periodically: out of every +tick-secs-expr (defaults to 0.2) seconds, the +thread is allowed to run use-ratio-expr (defaults to +0.12) of the time proportionally; i.e., the thread +runs for (* tick-secs-expr use-ratio-expr) seconds.

If the promise is forced before the computation is done, it +runs the rest of the computation immediately without waiting on events +or periodically restricting evaluation.

A #:wait-for, #:work-while, #:tick, or +#:use specification can appear at most once.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Equality.html b/clones/docs.racket-lang.org/reference/Equality.html new file mode 100644 index 00000000..61268e99 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Equality.html @@ -0,0 +1,202 @@ + +4.1 Equality
8.6

4.1 Equality

Equality is the concept of whether two values are “the same.” Racket supports +a few different kinds of equality by default, although equal? is +preferred for most uses.

procedure

(equal? v1 v2)  boolean?

  v1 : any/c
  v2 : any/c
Two values are equal? if and only if they are eqv?, +unless otherwise specified for a particular datatype.

Datatypes with further specification of equal? include +strings, byte strings, pairs, mutable pairs, vectors, boxes, hash +tables, and inspectable structures. In the last six cases, equality +is recursively defined; if both v1 and v2 contain +reference cycles, they are equal when the infinite unfoldings of the +values would be equal. See also gen:equal+hash and +prop:impersonator-of.

Examples:
> (equal? 'yes 'yes)

#t

> (equal? 'yes 'no)

#f

> (equal? (* 6 7) 42)

#t

> (equal? (expt 2 100) (expt 2 100))

#t

> (equal? 2 2.0)

#f

> (let ([v (mcons 1 2)]) (equal? v v))

#t

> (equal? (mcons 1 2) (mcons 1 2))

#t

> (equal? (integer->char 955) (integer->char 955))

#t

> (equal? (make-string 3 #\z) (make-string 3 #\z))

#t

> (equal? #t #t)

#t

procedure

(equal-always? v1 v2)  boolean?

  v1 : any/c
  v2 : any/c
Indicates whether v1 and v2 are equal and will always stay + equal independent of mutations. Generally, for to values to be equal-always, corresponding + immutable values within v1 and v2 must be equal?, + while corresponding mutable values within them must be eq?.

Two values v1 and v2 are equal-always? if and only + if there exists a third value v3 such that v1 and + v2 are both chaperones of v3, meaning + (chaperone-of? v1 v3) and (chaperone-of? v2 v3) are both + true.

For values that include no chaperones or other impersonators, + v1 and v2 can be considered equal-always + if they are equal?, except that corresponding mutable + vectors, boxes, hash tables, strings, byte strings, mutable pairs, and + mutable structures within + v1 and v2 must be eq?, and equality on structures + can be specialized for equal-always? through gen:equal-mode+hash.

Examples:
> (equal-always? 'yes 'yes)

#t

> (equal-always? 'yes 'no)

#f

> (equal-always? (* 6 7) 42)

#t

> (equal-always? (expt 2 100) (expt 2 100))

#t

> (equal-always? 2 2.0)

#f

> (equal-always? (list 1 2) (list 1 2))

#t

> (let ([v (mcons 1 2)]) (equal-always? v v))

#t

> (equal-always? (mcons 1 2) (mcons 1 2))

#f

> (equal-always? (integer->char 955) (integer->char 955))

#t

> (equal-always? (make-string 3 #\z) (make-string 3 #\z))

#f

> (equal-always? (string->immutable-string (make-string 3 #\z))
                 (string->immutable-string (make-string 3 #\z)))

#t

> (equal-always? #t #t)

#t

Added in version 8.5.0.3 of package base.

procedure

(eqv? v1 v2)  boolean?

  v1 : any/c
  v2 : any/c
Two values are eqv? if and only if they are eq?, +unless otherwise specified for a particular datatype.

The number and character datatypes are the only ones for which +eqv? differs from eq?. Two numbers are eqv? when +they have the same exactness, precision, and are both equal and non-zero, both ++0.0, both +0.0f0, both -0.0, +both -0.0f0, both +nan.0, or both ++nan.fconsidering real and imaginary components separately +in the case of complex numbers. Two characters are eqv? when +their char->integer results are equal.

Generally, eqv? is identical to equal? except that the former +cannot recursively compare the contents of compound data types (such as lists +and structs) and cannot be customized by user-defined data types. The use of +eqv? is lightly discouraged in favor of equal?.

Examples:
> (eqv? 'yes 'yes)

#t

> (eqv? 'yes 'no)

#f

> (eqv? (* 6 7) 42)

#t

> (eqv? (expt 2 100) (expt 2 100))

#t

> (eqv? 2 2.0)

#f

> (let ([v (mcons 1 2)]) (eqv? v v))

#t

> (eqv? (mcons 1 2) (mcons 1 2))

#f

> (eqv? (integer->char 955) (integer->char 955))

#t

> (eqv? (make-string 3 #\z) (make-string 3 #\z))

#f

> (eqv? #t #t)

#t

procedure

(eq? v1 v2)  boolean?

  v1 : any/c
  v2 : any/c
Return #t if v1 and v2 refer to the same +object, #f otherwise. As a special case among numbers, +two fixnums that are = are also the same according +to eq?. See also Object Identity and Comparisons.

Examples:
> (eq? 'yes 'yes)

#t

> (eq? 'yes 'no)

#f

> (eq? (* 6 7) 42)

#t

> (eq? (expt 2 100) (expt 2 100))

#f

> (eq? 2 2.0)

#f

> (let ([v (mcons 1 2)]) (eq? v v))

#t

> (eq? (mcons 1 2) (mcons 1 2))

#f

> (eq? (integer->char 955) (integer->char 955))

#t

> (eq? (make-string 3 #\z) (make-string 3 #\z))

#f

> (eq? #t #t)

#t

procedure

(equal?/recur v1 v2 recur-proc)  boolean?

  v1 : any/c
  v2 : any/c
  recur-proc : (any/c any/c -> any/c)
Like equal?, but using recur-proc for recursive +comparisons (which means that reference cycles are not handled +automatically). Non-#f results from recur-proc are +converted to #t before being returned by +equal?/recur.

Examples:
> (equal?/recur 1 1 (lambda (a b) #f))

#t

> (equal?/recur '(1) '(1) (lambda (a b) #f))

#f

> (equal?/recur '#(1 1 1) '#(1 1.2 3/4)
                (lambda (a b) (<= (abs (- a b)) 0.25)))

#t

procedure

(equal-always?/recur v1 v2 recur-proc)  boolean?

  v1 : any/c
  v2 : any/c
  recur-proc : (any/c any/c -> any/c)
Like equal-always?, but using recur-proc for recursive +comparisons (which means that reference cycles are not handled +automatically). Non-#f results from recur-proc are +converted to #t before being returned by +equal-always?/recur.

Examples:
> (equal-always?/recur 1 1 (lambda (a b) #f))

#t

> (equal-always?/recur '(1) '(1) (lambda (a b) #f))

#f

> (equal-always?/recur (vector-immutable 1 1 1) (vector-immutable 1 1.2 3/4)
                       (lambda (a b) (<= (abs (- a b)) 0.25)))

#t

4.1.1 Object Identity and Comparisons

The eq? operator compares two values, returning +#t when the values refer to the same object. This form +of equality is suitable for comparing objects that support imperative +update (e.g., to determine that the effect of modifying an object +through one reference is visible through another reference). Also, an +eq? test evaluates quickly, and eq?-based hashing +is more lightweight than equal?-based hashing in hash tables.

In some cases, however, eq? is unsuitable as a comparison +operator, because the generation of objects is not clearly +defined. In particular, two applications of + to the same two +exact integers may or may not produce results that are eq?, +although the results are always equal?. Similarly, evaluation +of a lambda form typically generates a new procedure +object, but it may re-use a procedure object previously +generated by the same source lambda form.

The behavior of a datatype with respect to eq? is generally +specified with the datatype and its associated procedures.

4.1.2 Equality and Hashing

All comparable values have at least one hash code an arbitrary +integer (more specifically a fixnum) computed by applying a hash function +to the value. The defining property of these hash codes is that equal +values have equal hash codes. Note that the reverse is not true: two unequal +values can still have equal hash codes. Hash codes are useful for various +indexing and comparison operations, especially in the implementation of +hash tables. See Hash Tables for more information.

procedure

(equal-hash-code v)  fixnum?

  v : any/c
Returns a hash code consistent with equal?. For any two calls +with equal? values, the returned number is the same. A hash code is +computed even when v contains a cycle through pairs, vectors, boxes, +and/or inspectable structure fields. Additionally, user-defined data types can +customize how this hash code is computed by implementing +gen:equal+hash or gen:equal-mode+hash.

For any v that could be produced by read, if v2 is +produced by read for the same input characters, the +(equal-hash-code v) is the same as (equal-hash-code v2) +even if v and v2 do not exist at the same time (and therefore +could not be compared by calling equal?).

Changed in version 6.4.0.12 of package base: Strengthened guarantee for readable values.

procedure

(equal-secondary-hash-code v)  fixnum?

  v : any/c
Like equal-hash-code, but computes a secondary hash code +suitable for use in double hashing.

procedure

(equal-always-hash-code v)  fixnum?

  v : any/c
Returns a hash code consistent with equal-always?. For any two +calls with equal-always? values, the returned number is the same.

As equal-always-hash-code traverses v, immutable +values within v are hashed with equal-hash-code, +while mutable values within v are hashed with eq-hash-code.

procedure

(equal-always-secondary-hash-code v)  fixnum?

  v : any/c
Like equal-always-hash-code, but computes a secondary hash code +suitable for use in double hashing.

procedure

(eq-hash-code v)  fixnum?

  v : any/c
Returns a hash code consistent with eq?. For any two calls with +eq? values, the returned number is the same.

Equal fixnums are always eq?.

procedure

(eqv-hash-code v)  fixnum?

  v : any/c
Returns a hash code consistent with eqv?. For any two calls +with eqv? values, the returned number is the same.

4.1.3 Implementing Equality for Custom Types

A generic interface (see Generic Interfaces) for types that can +be compared for equality using equal?. The following methods must be +implemented:

  • equal-proc : (-> any/c any/c (-> any/c any/c boolean?) any/c) +tests whether the first two arguments are equal, where both values are +instances of the structure type to which the generic interface is associated +(or a subtype of the structure type).

    The third argument is an equal? predicate to use for +recursive equality checks; use the given predicate instead of +equal? to ensure that data cycles are handled +properly and to work with equal?/recur (but beware +that an arbitrary function can be provided to +equal?/recur for recursive checks, which means that +arguments provided to the predicate might be exposed to +arbitrary code).

    The equal-proc is called for a pair of structures +only when they are not eq?, and only when they both +have a gen:equal+hash value inherited from the same +structure type. With this strategy, the order in which +equal? receives two structures does not matter. It +also means that, by default, a structure sub-type inherits the +equality predicate of its parent, if any.

  • hash-proc : (-> any/c (-> any/c exact-integer?) exact-integer?) +computes a hash code for the given structure, like equal-hash-code. +The first argument is an instance of the structure type (or one of its +subtypes) to which the generic interface is associated.

    The second argument is an equal-hash-code-like procedure to use for +recursive hash-code computation; use the given procedure instead of +equal-hash-code to ensure that data cycles are handled properly.

    Although the result of hash-proc can be any exact +integer, it will be truncated for most purposes to a fixnum +(e.g., for the result of equal-hash-code). Roughly, +truncation uses bitwise-and to take the lower bits of the +number. Thus, variation in the hash-code computation should be +reflected in the fixnum-compatible bits of hash-proc’s +result. Consumers of a hash code are expected to use variation +within the fixnum range appropriately, and producers are not +responsible to reflect variation in hash codes across the full +range of bits that fit within a fixnum.

  • hash2-proc : (-> any/c (-> any/c exact-integer?) exact-integer?) +computes a secondary hash code for the given structure. This procedure is +like hash-proc, but analogous to +equal-secondary-hash-code.

Take care to ensure that hash-proc and hash2-proc +are consistent with equal-proc. Specifically, +hash-proc and hash2-proc should produce the same +value for any two structures for which equal-proc produces a +true value.

The equal-proc is not only used for +equal?, it is also used for equal?/recur, +and impersonator-of?. Furthermore, if the structure type +has no mutable fields, equal-proc is used for equal-always?, and +chaperone-of?. Likewise hash-proc and +hash2-proc are used for +equal-always-hash-code and +equal-always-secondary-hash-code, respectively, when +the structure type has no mutable fields. +Instances of these methods should follow the guidelines in +Honest Custom Equality to implement all of these +operations reasonably. In particular, these methods should +not access mutable data unless the struct is declared +mutable.

When a structure type has no gen:equal+hash or +gen:equal-mode+hash implementation, then +transparent structures (i.e., structures with an inspector that +is controlled by the current inspector) are equal? +when they are instances of the same structure type (not counting +sub-types), and when they have equal? field values. For +transparent structures, equal-hash-code and +equal-secondary-hash-code (in the case of no mutable fields) +derive hash code using the field +values. For a transparent structure type with at least one mutable field, +equal-always? is the same as eq?, and an +equal-secondary-hash-code result is based only on eq-hash-code. +For opaque structure types, equal? is the same as +eq?, and equal-hash-code and +equal-secondary-hash-code results are based only on +eq-hash-code. If a structure has a prop:impersonator-of +property, then the prop:impersonator-of property takes precedence over +gen:equal+hash if the property value’s procedure returns a +non-#f value when applied to the structure.

Examples:
(define (farm=? farm1 farm2 recursive-equal?)
  (and (= (farm-apples farm1)
          (farm-apples farm2))
       (= (farm-oranges farm1)
          (farm-oranges farm2))
       (= (farm-sheep farm1)
          (farm-sheep farm2))))
 
(define (farm-hash-code farm recursive-equal-hash)
  (+ (* 10000 (farm-apples farm))
     (* 100 (farm-oranges farm))
     (* 1 (farm-sheep farm))))
 
(define (farm-secondary-hash-code farm recursive-equal-hash)
  (+ (* 10000 (farm-sheep farm))
     (* 100 (farm-apples farm))
     (* 1 (farm-oranges farm))))
 
(struct farm (apples oranges sheep)
  #:methods gen:equal+hash
  [(define equal-proc farm=?)
   (define hash-proc  farm-hash-code)
   (define hash2-proc farm-secondary-hash-code)])
 
(define eastern-farm (farm 5 2 20))
(define western-farm (farm 18 6 14))
(define northern-farm (farm 5 20 20))
(define southern-farm (farm 18 6 14))

 

> (equal? eastern-farm western-farm)

#f

> (equal? eastern-farm northern-farm)

#f

> (equal? western-farm southern-farm)

#t

A generic interface (see Generic Interfaces) for types that + may specify differences between equal? and equal-always?. + The following methods must be implemented:

The hash-mode-proc implementation is used both for a + primary hash code and secondary hash code.

When implementing these methods, follow the guidelines in + Honest Custom Equality. In particular, these + methods should only access mutable data if the “mode” argument + is true to indicate equal? or impersonator-of?.

Implementing gen:equal-mode+hash is most useful for types that + specify differences between equal? and equal-always?, such + as a structure type that wraps mutable data with getter and setter procedures: +

Examples:
> (define (get gs) ((getset-getter gs)))
> (define (set gs new) ((getset-setter gs) new))
> (struct getset (getter setter)
     #:methods gen:equal-mode+hash
     [(define (equal-mode-proc self other rec mode)
        (and mode (rec (get self) (get other))))
      (define (hash-mode-proc self rec mode)
        (if mode (rec (get self)) (eq-hash-code self)))])
> (define x 1)
> (define y 2)
> (define gsx (getset (lambda () x) (lambda (new) (set! x new))))
> (define gsy (getset (lambda () y) (lambda (new) (set! y new))))
> (equal? gsx gsy)

#f

> (equal-always? gsx gsy)

#f

> (set gsx 3)
> (set gsy 3)
> (equal? gsx gsy)

#t

> (equal-always? gsx gsy)

#f

> (equal-always? gsx gsx)

#t

Added in version 8.5.0.3 of package base.

A structure type property (see Structure Type Properties) + that supplies an equality predicate and hashing functions for a structure + type. Using the prop:equal+hash property is an alternative to + using the gen:equal+hash or gen:equal-mode+hash + generic interface.

A prop:equal+hash property value is a list of either three + procedures (list equal-proc hash-proc hash2-proc) or two + procedures (list equal-mode-proc hash-mode-proc):

When implementing these methods, follow the guidelines in +Honest Custom Equality. In particular, these +methods should only access mutable data if the struct is +declared mutable or the mode is true.

Changed in version 8.5.0.3 of package base: Added support for two-procedure values to customize equal-always?.

4.1.4 Honest Custom Equality

Since the equal-proc or equal-mode-proc +is used for more than just equal?, instances of +them should follow certain guidelines to make sure that they work +correctly for equal-always?, chaperone-of?, +and impersonator-of?.

Due to the differences between these operations, avoid +calling equal? within them. Instead, use the third +argument to “recur” on the pieces, which allows +equal?/recur to work properly, lets the other +operations behave in their own distinct ways on the pieces, +and enables some cycle detection.

good

(define (equal-proc self other rec)
  (rec (fish-size self) (fish-size other)))

bad

(define (equal-proc self other rec)
  (equal? (fish-size self) (fish-size other)))

The operations equal? and equal-always? +should be symmetric, so equal-proc instances +should not change their answer when the arguments swap:

good

(define (equal-proc self other rec)
  (rec (fish-size self) (fish-size other)))

bad

(define (equal-proc self other rec)
  (<= (fish-size self) (fish-size other)))

However, the operations chaperone-of? and +impersonator-of? are not symmetric, so when +calling the third argument to “recur” on pieces, pass the +pieces in the same order they came in:

good

(define (equal-proc self other rec)
  (rec (fish-size self) (fish-size other)))

bad

(define (equal-proc self other rec)
  (rec (fish-size other) (fish-size self)))

Mutable structs will only use the custom equality for +equal? and impersonator-of?, so that +equal-always? and chaperone-of? don’t +change on mutation. Structs that represent mutable data +should either be declared mutable, or use +equal-mode-proc from gen:equal-mode+hash +instead of equal-proc from gen:equal+hash, +and only access mutable data when the mode is true:

good

(struct mcell (value) #:mutable
  #:methods gen:equal+hash
  [(define (equal-proc self other rec)
     (rec (mcell-value self)
          (mcell-value other)))
   (define (hash-proc self rec)
     (+ (eq-hash-code struct:mcell)
        (rec (mcell-value self))))
   (define (hash2-proc self rec)
     (+ (eq-hash-code struct:mcell)
        (rec (mcell-value self))))])

bad

(struct mcell (box)
  ; not declared mutable,
  ; but represents mutable data anyway
  #:methods gen:equal+hash
  [(define (equal-proc self other rec)
     (rec (unbox (mcell-box self))
          (unbox (mcell-box other))))
   (define (hash-proc self rec)
     (+ (eq-hash-code struct:mcell)
        (rec (unbox (mcell-value self)))))
   (define (hash2-proc self rec)
     (+ (eq-hash-code struct:mcell)
        (rec (unbox (mcell-value self)))))])

also good

(struct mcell (value) #:mutable
  ; only accesses mutable data when mode is true
  #:methods gen:equal-mode+hash
  [(define (equal-mode-proc self other rec mode)
     (and mode
          (rec (mcell-value self)
               (mcell-value other))))
   (define (hash-mode-proc self rec mode)
     (if mode
         (+ (eq-hash-code struct:mcell)
            (rec (mcell-value self)))
         (eq-hash-code self)))])

still bad

(struct mcell (value) #:mutable
  ; accesses mutable data ignoring mode
  #:methods gen:equal-mode+hash
  [(define (equal-mode-proc self other rec mode)
     (rec (mcell-value self)
          (mcell-value other)))
   (define (hash-mode-proc self rec mode)
     (+ (eq-hash-code struct:mcell)
        (rec (mcell-value self))))])

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Exiting.html b/clones/docs.racket-lang.org/reference/Exiting.html new file mode 100644 index 00000000..3f0c0d62 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Exiting.html @@ -0,0 +1,19 @@ + +10.7 Exiting

10.7 Exiting

procedure

(exit [v])  any

  v : any/c = #t
Passes v to the current exit handler. If the exit +handler does not escape or terminate the thread, #<void> is +returned.

parameter

(exit-handler)  (any/c . -> . any)

(exit-handler proc)  void?
  proc : (any/c . -> . any)
A parameter that determines the current exit handler. The +exit handler is called by exit.

The default exit handler in the Racket executable +takes any argument, calls plumber-flush-all on the original plumber, +and shuts down the OS-level Racket process. The +argument is used as the OS-level exit code if it is an exact integer +between 1 and 255 (which normally means +“failure”); otherwise, the exit code is 0, (which normally +means “success”).

parameter

(executable-yield-handler)  (byte? . -> . any)

(executable-yield-handler proc)  void?
  proc : (byte? . -> . any)
A parameter that determines a procedure to be called as the Racket +process is about to exit normally. The procedure associated with this +parameter is not called when exit (or, more precisely, the +default exit handler) is used to exit early. The argument to +the handler is the status code that is returned to the system on exit. +The default executable-yield handler simply returns #<void>.

The scheme/gui/base library sets this parameter to +wait until all frames are closed, timers stopped, and queued events +handled in the main eventspace. See scheme/gui/base +for more information.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Expanding_Top-Level_Forms.html b/clones/docs.racket-lang.org/reference/Expanding_Top-Level_Forms.html new file mode 100644 index 00000000..6fa35ac8 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Expanding_Top-Level_Forms.html @@ -0,0 +1,51 @@ + +12.9 Expanding Top-Level Forms

12.9 Expanding Top-Level Forms

procedure

(expand top-level-form [insp])  syntax?

  top-level-form : any/c
  insp : inspector? = (current-code-inspector)
Expands all non-primitive syntax in top-level-form, and +returns a syntax object for the expanded form that contains only core +forms, matching the grammar specified by Fully Expanded Programs.

Before top-level-form is expanded, its lexical context is +enriched with namespace-syntax-introduce, just as for +eval. Use syntax->datum to convert the returned +syntax object into a printable datum.

If insp is not the original code inspector (i.e., the +value of (current-code-inspector) when Racket starts), then +the result syntax object is tainted.

Here’s an example of using expand on a module:

(parameterize ([current-namespace (make-base-namespace)])
 (expand
  (datum->syntax
   #f
   '(module foo scheme
      (define a 3)
      (+ a 4)))))

Here’s an example of using expand on a non-top-level form:

(define-namespace-anchor anchor)
(parameterize ([current-namespace
                (namespace-anchor->namespace anchor)])
 (expand
  (datum->syntax
   #f
   '(delay (+ 1 2)))))

Changed in version 8.2.0.4 of package base: Added the insp argument and tainting.

procedure

(expand-syntax stx [insp])  syntax?

  stx : syntax?
  insp : inspector? = (current-code-inspector)
Like (expand stx insp), except that the argument must be a +syntax object, and its lexical context is not enriched before +expansion.

Changed in version 8.2.0.4 of package base: Added the insp argument and tainting.

procedure

(expand-once top-level-form [insp])  syntax?

  top-level-form : any/c
  insp : inspector? = (current-code-inspector)
Partially expands top-level-form and returns a syntax object +for the partially-expanded expression. Due to limitations in the +expansion mechanism, some context information may be lost. In +particular, calling expand-once on the result may produce a +result that is different from expansion via expand.

Before top-level-form is expanded, its lexical context is +enriched with namespace-syntax-introduce, as for +eval.

The insp argument determines whether the result is +tainted, the same as for expand.

Changed in version 8.2.0.4 of package base: Added the insp argument and tainting.

procedure

(expand-syntax-once stx [insp])  syntax?

  stx : syntax?
  insp : inspector? = (current-code-inspector)
Like (expand-once stx), except that the argument +must be a syntax object, and its lexical context is not +enriched before expansion.

Changed in version 8.2.0.4 of package base: Added the insp argument and tainting.

procedure

(expand-to-top-form top-level-form [insp])  syntax?

  top-level-form : any/c
  insp : inspector? = (current-code-inspector)
Partially expands top-level-form to reveal the outermost +syntactic form. This partial expansion is mainly useful for detecting +top-level uses of begin. Unlike the result of +expand-once, expanding the result of +expand-to-top-form with expand produces the same +result as using expand on the original syntax.

Before stx-or-sexpr is expanded, its lexical context is +enriched with namespace-syntax-introduce, as for +eval.

The insp argument determines whether the result is +tainted, the same as for expand.

Changed in version 8.2.0.4 of package base: Added the insp argument and tainting.

procedure

(expand-syntax-to-top-form stx [insp])  syntax?

  stx : syntax?
  insp : inspector? = (current-code-inspector)
Like (expand-to-top-form stx), except that the argument must +be a syntax object, and its lexical context is not enriched +before expansion.

Changed in version 8.2.0.4 of package base: Added the insp argument and tainting.

12.9.1 Information on Expanded Modules

Information for an expanded module declaration is stored in a +set of syntax properties (see Syntax Object Properties) attached +to the syntax object:

  • 'module-body-context a syntax +object whose lexical information corresponds to the inside of +the module, so it includes the expansion’s outside-edge scope +and its inside-edge scope; that is, the syntax object +simulates an identifier that is present in the original module body +and inaccessible to manipulation by any macro, so that its lexical +information includes bindings for the module’s imports and +definitions.

    Added in version 6.4.0.1 of package base.

  • 'module-body-inside-context a syntax +object whose lexical information corresponds to an identifier +that starts with no lexical context and is moved into the macro, so +that it includes only the expansions’s inside-edge scope.

    Added in version 6.4.0.1 of package base.

  • 'module-body-context-simple? a boolean, +where #t indicates that the bindings of the module’s body +(as recorded in the lexical information of the value of the +'module-body-inside-context property) can be directly +reconstructed from modules directly imported into the module, +including imported for-syntax, for-meta, and for-template.

    Added in version 6.4.0.1 of package base.

Changed in version 7.0 of package base: Removed 'module-variable-provides, +'module-syntax-provides, +'module-indirect-provides, +and 'module-indirect-for-meta-provides +properties.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Filesystem.html b/clones/docs.racket-lang.org/reference/Filesystem.html new file mode 100644 index 00000000..a279771c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Filesystem.html @@ -0,0 +1,850 @@ + +15.2 Filesystem
On this page:
15.2.1 Locating Paths
find-system-path
path-list-string->path-list
find-executable-path
15.2.2 Files
file-exists?
link-exists?
file-or-directory-type
delete-file
rename-file-or-directory
file-or-directory-modify-seconds
file-or-directory-permissions
file-or-directory-stat
file-or-directory-identity
file-size
copy-file
make-file-or-directory-link
current-force-delete-permissions
15.2.3 Directories
current-directory
current-directory-for-user
current-drive
directory-exists?
make-directory
delete-directory
directory-list
filesystem-root-list
15.2.4 Detecting Filesystem Changes
filesystem-change-evt?
filesystem-change-evt
filesystem-change-evt-cancel
15.2.5 Declaring Paths Needed at Run Time
define-runtime-path
define-runtime-paths
define-runtime-path-list
define-runtime-module-path-index
runtime-require
define-runtime-module-path
runtime-paths
15.2.6 More File and Directory Utilities
file->string
file->bytes
file->value
file->list
file->lines
file->bytes-lines
display-to-file
write-to-file
display-lines-to-file
copy-directory/  files
delete-directory/  files
find-files
pathlist-closure
fold-files
make-directory*
make-parent-directory*
make-temporary-file
make-temporary-directory
make-temporary-file*
make-temporary-directory*
call-with-atomic-output-file
get-preference
put-preferences
preferences-lock-file-mode
make-handle-get-preference-locked
call-with-file-lock/  timeout
make-lock-file-name
file-type-bits
socket-type-bits
symbolic-link-type-bits
regular-file-type-bits
block-device-type-bits
directory-type-bits
character-device-type-bits
fifo-type-bits
set-user-id-bit
set-group-id-bit
sticky-bit
user-permission-bits
user-read-bit
user-write-bit
user-execute-bit
group-permission-bits
group-read-bit
group-write-bit
group-execute-bit
other-permission-bits
other-read-bit
other-write-bit
other-execute-bit

15.2 Filesystem

15.2.1 Locating Paths

procedure

(find-system-path kind)  path?

  kind : symbol?
Returns a machine-specific path for a standard type of path specified +by kind, which must be one of the following:

  • 'home-dir the current user’s home +directory.

    On all platforms, if the PLTUSERHOME environment +variable is defined as a complete path, then the path is used +as the user’s home directory.

    On Unix and Mac OS, when PLTUSERHOME does not apply, +the user’s home directory is determined by +expanding the path "~", which is expanded by first checking +for a HOME environment variable. If none is defined, +the USER and LOGNAME environment +variables are consulted (in that order) to find a user name, and then +system files are consulted to locate the user’s home directory.

    On Windows, when PLTUSERHOME does not apply, +the user’s home directory is the user-specific profile +directory as determined by the Windows registry. If the registry +cannot provide a directory for some reason, the value of the +USERPROFILE environment variable is used instead, as +long as it refers to a directory that exists. If USERPROFILE +also fails, the directory is the one specified by the +HOMEDRIVE and HOMEPATH environment +variables. If those environment variables are not defined, or if the +indicated directory still does not exist, the directory containing +the current executable is used as the home directory.

  • 'pref-dir the standard directory for +storing the current user’s preferences. The preferences directory +might not exist.

    On Unix, the preferences directory is normally the "racket" +subdirectory of the path specified by +XDG_CONFIG_HOME, or ".config/racket" in the +user’s home directory if XDG_CONFIG_HOME is not set +to an absolute path or if PLTUSERHOME is set. Either way, if +that directory does not exist but a ".racket" directory +exists in the user’s home directory, then that directory is +the preference directory, instead.

    On Windows, the preferences directory is "Racket" in the +user’s home directory if determined by PLTUSERHOME, +otherwise in the user’s application-data folder as specified by the +Windows registry; the application-data folder is usually +"Application Data" in the user’s profile directory.

    On Mac OS, the preferences directory is +"Library/Preferences" in the user’s home directory.

  • 'pref-file a file that contains a +symbol-keyed association list of preference values. The file’s +directory path always matches the result returned for +'pref-dir. The file name is "racket-prefs.rktd" on Unix +and Windows, and it is "org.racket-lang.prefs.rktd" on Mac OS. +The file’s directory might not exist. See also +get-preference.

  • 'temp-dir the standard directory for +storing temporary files. On Unix and Mac OS, this is the directory +specified by the TMPDIR environment variable, if it +is defined, otherwise it is the first path that exists among +"/var/tmp", "/usr/tmp", and "/tmp". On +Windows, the result is the directory specified by the +TMP or TEMP environment variable, +if it is defined, otherwise it is the current directory.

  • 'init-dir the directory containing the +initialization file used by the Racket executable.

    On Unix, the initialization directory is the same as the result +returned for 'pref-dirunless that directory does not +exist and a ".racketrc" file exists in the user’s home +directory, in which case the home directory is the initialization +directory.

    On Windows, the initialization directory is the same as the +user’s home directory.

    On Mac OS, the initialization directory is "Library/Racket" +in the user’s home directoryunless no +"racketrc.rktl" exists there and a ".racketrc" file +does exist in the home directory, in which case the home directory is +the initialization directory.

  • 'init-file the file loaded at start-up by +the Racket executable. The directory part of the +path is the same path as returned for 'init-dir.

    On Windows, the file part of the name is +"racketrc.rktl".

    On Unix and Mac OS, the file part of the name is +"racketrc.rktl"unless the path returned for +'init-dir is the user’s home directory, in which case +the file part of the name is ".racketrc".

  • 'config-dir a directory for +the installation’s configuration. This directory is specified by the +PLTCONFIGDIR environment variable, and it can be +overridden by the --config or -G command-line flag. If no +environment variable or flag is specified, or if the value is not a +legal path name, then this directory defaults to an +"etc" directory relative to the current executable. +If the result of (find-system-path 'config-dir) is a +relative path, it is relative to the current executable. +The directory might not exist.

  • 'host-config-dir like +'config-dir, but when cross-platform build mode has been +selected (through the -C or --cross argument to +racket; see Command Line), the result refers to a +directory for the current system’s installation, instead of for the +target system.

  • 'addon-dir a directory for +user-specific Racket configuration, packages, and extension. +This directory is specified by the +PLTADDONDIR environment variable, and it can be +overridden by the --addon or -A command-line flag. If no +environment variable or flag is specified, or if the value is not a +legal path name, then this directory defaults to a platform-specific +locations. The directory might not exist.

    On Unix, the default is normally the "racket" subdirectory +of the path specified by XDG_DATA_HOME, or +".local/share/racket" in the user’s home directory if +XDG_CONFIG_HOME is not set to an absolute path or if +PLTUSERHOME is set. If that directory does not exists but a +".racket" directory exists in the user’s home directory, +that the ".racket" directory path is the default, instead.

    On Windows, the default is the same as the 'pref-dir directory.

    On Mac OS, the default is "Library/Racket" within the +user’s home directory.

  • 'cache-dir a directory for storing +user-specific caches. The directory might not exist.

    On Unix, the cache directory is normally the "racket" +subdirectory of the path specified by +XDG_CACHE_HOME, or ".cache/racket" in the +user’s home directory if XDG_CACHE_HOME is not set to +an absolute path or if PLTUSERHOME is set. If that directory +does not exist but a ".racket" directory exists in the home +directory, then the ".racket" directory is the cache +directory, instead.

    On Windows, the cache directory is the same as the result returned +for 'addon-dir.

    On Mac OS, the cache directory is "Library/Caches/Racket" +within the user’s home directory.

  • 'doc-dir the standard directory for +storing the current user’s documents. On Unix, it’s +the user’s home directory. On Windows, it is the user’s +home directory if determined by PLTUSERHOME, otherwise it +is the user’s documents folder as specified by the Windows registry; +the documents folder is usually "My Documents" in the user’s +home directory. On Mac OS, it’s the "Documents" directory +in the user’s home directory.

  • 'desk-dir the directory for the current user’s +desktop. On Unix, it’s the user’s home directory. On +Windows, it is the user’s home directory if determined by +PLTUSERHOME, otherwise it is the user’s desktop folder as +specified by the Windows registry; the desktop folder is usually +"Desktop" in the user’s home directory. On Mac OS, it is +"Desktop" in the user’s home directory

  • 'sys-dir the directory containing the +operating system for Windows. On Unix and Mac OS, the +result is "/".

  • 'exec-file the path of the Racket +executable as provided by the operating system for the current +invocation. For some operating systems, the path can be relative.

    For GRacket, the executable path is the name of a GRacket +executable.

  • 'run-file the path of the current +executable; this may be different from result for +'exec-file because an alternate path was provided through a +--name or -N command-line flag to the Racket +(or GRacket) executable, or because an embedding executable +installed an alternate path. In particular a “launcher” script +created by make-racket-launcher sets this path to the +script’s path.

  • 'collects-dir a path to the main +collection of libraries (see Libraries and Collections). If this path is +relative, then it is relative to the executable as reported by +(find-system-path 'exec-file)though the latter could be a +soft-link or relative to the user’s executable search path, so that +the two results should be combined with +find-executable-path. The 'collects-dir path is +normally embedded in the Racket executable, but it can be +overridden by the --collects or -X command-line flag.

  • 'host-collects-dir like +'collects-dir, but when cross-platform build mode has been +selected (through the -C or --cross argument to +racket; see Command Line), the result refers to a +directory for the current system’s installation, instead of for the +target system. In cross-platform build mode, collection +files are normally read from the target system’s installation, +but some tasks require current-system directories (such as +the one that holds foreign libraries) that are configured relative +to the main library-collection path.

  • 'orig-dir the current directory at +start-up, which can be useful in converting a relative-path result +from (find-system-path 'exec-file) or +(find-system-path 'run-file) to a complete path.

Changed in version 6.0.0.3 of package base: Added PLTUSERHOME.
Changed in version 6.9.0.1: Added 'host-config-dir +and 'host-collects-dir.
Changed in version 7.8.0.9: Added 'cache-dir, and changed +to use XDG directories as preferred on Unix +with the previous paths as a fallback, and +with similar adjustments for Mac OS.

procedure

(path-list-string->path-list str 
  default-path-list) 
  (listof (or/c path? 'same))
  str : (or/c string? bytes?)
  default-path-list : (listof (or/c path? 'same))
Parses a string or byte string containing a list of paths, and returns +a list of paths. On Unix and Mac OS, paths in a path-list string are +separated by a :; on Windows, paths are separated by a +;, and all "s in the string are discarded. Whenever the path +list contains an empty path, the list +default-path-list is spliced into the returned list of +paths. Parts of str that do not form a valid path are not +included in the returned list. The given str must not contain +a nul character or nul byte.

Changed in version 8.0.0.10 of package base: Changed to allow 'same in +default-path-list.

procedure

(find-executable-path program    
  [related    
  deepest?])  (or/c path? #f)
  program : path-string?
  related : (or/c path-string? #f) = #f
  deepest? : any/c = #f
Finds a path for the executable program, returning +#f if the path cannot be found.

On Windows, if program is not found and it has no file +extension, then the search starts over with ".exe" added to +program, and the result is #f only if the path with +".exe" also cannot be found. The result includes the +extension ".exe" if only program with the extension +is found.

If related is not #f, then it must be a relative +path string, and the path found for program must be such +that the file or directory related exists in the same +directory as the executable. The result is then the full path for the +found related, instead of the path for the executable.

This procedure is used by the Racket executable to find the +standard library collection directory (see Libraries and Collections). In +this case, program is the name used to start Racket and +related is "collects". The related +argument is used because, on Unix and Mac OS, program may +involve a sequence of soft links; in this case, +related determines which link in the chain is relevant.

If related is not #f, then when +find-executable-path does not find a program +that is a link to another file path, the search can continue with the +destination of the link. Further links are inspected until +related is found or the end of the chain of links is +reached. If deepest? is #f (the default), then the +result corresponds to the first path in a chain of links for which +related is found (and further links are not actually +explored); otherwise, the result corresponds to the last link in the +chain for which related is found.

If program is a pathless name, +find-executable-path gets the value of the +PATH environment variable; if this environment +variable is defined, find-executable-path tries each path in +PATH as a prefix for program using the search +algorithm described above for path-containing +programs. If the PATH environment variable is +not defined, program is prefixed with the current +directory and used in the search algorithm above. (On Windows, the +current directory is always implicitly the first item in +PATH, so find-executable-path checks the current +directory first on Windows.)

Changed in version 8.1.0.7 of package base: Added search with ".exe" +on Windows.

15.2.2 Files

procedure

(file-exists? path)  boolean?

  path : path-string?
Returns #t if a file (not a directory) path exists, +#f otherwise.

On Windows, file-exists? reports #t for all +variations of the special filenames (e.g., "LPT1", +"x:/baddir/LPT1").

procedure

(link-exists? path)  boolean?

  path : path-string?
Returns #t if a link path exists, +#f otherwise.

The predicates file-exists? or directory-exists? +work on the final destination of a link or series of links, while +link-exists? only follows links to resolve the base part of +path (i.e., everything except the last name in the +path).

This procedure never raises the exn:fail:filesystem +exception.

On Windows, link-exists? reports #t for both +symbolic links and junctions.

Changed in version 6.0.1.12 of package base: Added support for links on Windows.

procedure

(file-or-directory-type path [must-exist?])

  (or/c 'file 'directory 'link 'directory-link #f)
  path : path-string?
  must-exist? : any/c = #f
Reports whether path refers to a file, directory, link, or +directory link (in the case of Windows; see also +make-file-or-directory-link), assuming that path can +be accessed.

If path cannot be accessed, the result is #f if +must-exist? is #f, otherwise the +exn:fail:filesystem exception is raised.

Added in version 7.8.0.5 of package base.

procedure

(delete-file path)  void?

  path : path-string?
Deletes the file with path path if it exists, otherwise the +exn:fail:filesystem exception is raised. If path is a link, the link +is deleted rather than the destination of the link.

On Windows, if an initial attempt to delete the file fails with a +permission error and the value of +current-force-delete-permissions is true, then +delete-file attempts to change the file’s permissions (to +allow writes) and then delete the file; the permission change followed +by deletion is a non-atomic sequence, with no attempt to revert a +permission change if the deletion fails.

On Windows, delete-file can delete a symbolic link, but not +a junction. Use delete-directory to delete a junction.

On Windows, beware that if a file is deleted while it remains in use +by some process (e.g., a background search indexer), then the file’s +content will eventually go away, but the file’s name remains occupied +until the file is no longer used. As long as the name remains +occupied, attempts to open, delete, or replace the file will trigger a +permission error (as opposed to a file-exists error). A common +technique to avoid this pitfall is to move the file to a generated +temporary name before deleting it. See also +delete-directory/files.

Changed in version 6.1.1.7 of package base: Changed Windows behavior to use +current-force-delete-permissions.

procedure

(rename-file-or-directory old    
  new    
  [exists-ok?])  void?
  old : path-string?
  new : path-string?
  exists-ok? : any/c = #f
Renames the file or directory with path oldif it +exists—to the path new. If the file or directory is not +renamed successfully, the exn:fail:filesystem exception is raised.

This procedure can be used to move a file/directory to a different +directory (on the same filesystem) as well as rename a file/directory within +a directory. Unless exists-ok? is provided as a true value, +new cannot refer to an existing file or directory, but the +check is not atomic with the rename operation on Unix and Mac OS. Even if +exists-ok? is true, new cannot refer to an existing +file when old is a directory, and vice versa.

If new exists and is replaced, the replacement is atomic +on Unix and Mac OS, but it is not guaranteed to be atomic on +Windows. Furthermore, if new exists and is opened by any +process for reading or writing, then attempting to replace it will +typically fail on Windows. See also call-with-atomic-output-file.

If old is a link, the link is renamed rather than the +destination of the link, and it counts as a file for replacing any +existing new.

On Windows, beware that a directory cannot be renamed if any file +within the directory is open. That constraint is particularly +problematic if a search indexer is running in the background (as in +the default Windows configuration). A possible workaround is to +combine copy-directory/files and +delete-directory/files, since the latter can deal with open +files, although that sequence is obviously not atomic and temporarily +duplicates files.

procedure

(file-or-directory-modify-seconds path    
  [secs-n])  exact-integer?
  path : path-string?
  secs-n : #f = #f
(file-or-directory-modify-seconds path    
  secs-n)  void?
  path : path-string?
  secs-n : exact-integer?
(file-or-directory-modify-seconds path    
  [secs-n    
  fail-thunk])  any
  path : path-string?
  secs-n : (or/c exact-integer? #f) = #f
  fail-thunk : (-> any)
   = (lambda () (raise (make-exn:fail:filesystem ....)))
Returns +the file or directory’s last modification date in seconds +since the epoch (see also Time) when +secs-n is not provided or is #f.

For FAT filesystems on Windows, directories do not have modification +dates. Therefore, the creation date is returned for a directory, but +the modification date is returned for a file.

If secs-n is provided and not #f, the access and +modification times of path are set to the given time.

On error (e.g., if no such file exists), then fail-thunk is +called (through a tail call) to produce the result of the +file-or-directory-modify-seconds call. If fail-thunk is +not provided, an error raises exn:fail:filesystem.

procedure

(file-or-directory-permissions path [mode])

  (listof (or/c 'read 'write 'execute))
  path : path-string?
  mode : #f = #f
(file-or-directory-permissions path mode)  (integer-in 0 65535)
  path : path-string?
  mode : 'bits
(file-or-directory-permissions path mode)  void
  path : path-string?
  mode : (integer-in 0 65535)
When given one argument or #f as the second argument, returns +a list containing 'read, 'write, +and/or 'execute to indicate permission the given file +or directory path by the current user and group. On Unix and Mac OS, +permissions are checked for the current effective user instead of the +real user.

If 'bits is supplied as the second argument, the result is a +platform-specific integer encoding of the file or directory properties +(mostly permissions), and the result is independent of the current +user and group. The lowest nine bits of the encoding are somewhat +portable, reflecting permissions for the file or directory’s owner, +members of the file or directory’s group, or other users:

  • #o400 : owner has read permission

  • #o200 : owner has write permission

  • #o100 : owner has execute permission

  • #o040 : group has read permission

  • #o020 : group has write permission

  • #o010 : group has execute permission

  • #o004 : others have read permission

  • #o002 : others have write permission

  • #o001 : others have execute permission

See also user-read-bit, etc. On Windows, permissions from +all three (owner, group, and others) are always the same, and read and +execute permission are always available. On Unix and Mac OS, +higher bits have a platform-specific meaning.

If an integer is supplied as the second argument, it is used as an +encoding of properties (mostly permissions) to install for the file.

In all modes, the exn:fail:filesystem exception is raised on error (e.g., if no +such file exists).

procedure

(file-or-directory-stat path [as-link?])

  (and/c (hash/c symbol? any/c) hash-eq?)
  path : path-string?
  as-link? : boolean? = #f
Returns a hash with the following keys and values, +where each value currently is a nonnegative exact integer:

  • 'device-id : device ID

  • 'inode : inode number

  • 'mode : mode bits (see below)

  • 'hardlink-count : number of hard links

  • 'user-id : numeric user ID of owner

  • 'group-id : numeric group ID of owner

  • 'device-id-for-special-file : device ID (if special file)

  • 'size : size of file or symbolic link in bytes

  • 'block-size : size of filesystem blocks

  • 'block-count : number of used filesystem blocks

  • 'access-time-seconds : last access time in seconds +since the epoch

  • 'modify-time-seconds : last modification time in +seconds since the epoch

  • 'change-time-seconds : last status change time in +seconds since the epoch

  • 'creation-time-seconds : creation time in seconds since +the epoch

  • 'access-time-nanoseconds : last access time in +nanoseconds since the epoch

  • 'modify-time-nanoseconds : last modification time in +nanoseconds since the epoch

  • 'change-time-nanoseconds : last status change time in +nanoseconds since the epoch

  • 'creation-time-nanoseconds : creation time in +nanoseconds since the epoch

If as-link? is a true value, then if path refers to a +symbolic link, the stat information of the link is returned instead of the stat +information of the referenced filesystem item.

The mode bits are the bits for permissions and other data, as returned from the +Posix stat/lstat functions or the Windows _wstat64 function, +respectively. To select portions of the bit pattern, use the constants +user-read-bit, etc.

Depending on the operating system and filesystem, the “nanoseconds” +timestamps may have less than nanoseconds precision. For example, in one +environment a timestamp may be 1234567891234567891 (nanoseconds +precision) and in another environment 1234567891000000000 (seconds +precision).

Values that aren’t available for a platform/filesystem combination may be set +to 0. For example, this applies to the 'user-id and +'group-id keys on Windows. Also, Posix platforms provide the status +change timestamp, but not the creation timestamp; for Windows it’s the +opposite.

If as-link? is #f and path isn’t accessible, +the exn:fail:filesystem exception is raised. This exception is also raised if +as-link? is a true value and path can’t be resolved, i.e., is +a dangling link.

Added in version 8.3.0.7 of package base.

procedure

(file-or-directory-identity path [as-link?])

  exact-positive-integer?
  path : path-string?
  as-link? : any/c = #f
Returns a number that represents the identity of +path in terms of the device and file or directory that it +accesses. This function can be used to check whether two paths +correspond to the same filesystem entity under the assumption that the +path’s entity selection does not change.

If as-link? is a true value, then if path refers to +a filesystem link, the identity of the link is returned instead of the +identity of the referenced file or directory (if any).

procedure

(file-size path)  exact-nonnegative-integer?

  path : path-string?
Returns the (logical) size of the specified file in bytes. On Mac +OS, this size excludes the resource-fork size. On error (e.g., if no +such file exists), the exn:fail:filesystem exception is raised.

procedure

(copy-file src dest [exists-ok?])  void?

  src : path-string?
  dest : path-string?
  exists-ok? : any/c = #f
Creates the file dest as a copy of src, if +dest does not already exist. If dest already exists +and exists-ok? is #f, the copy fails with +exn:fail:filesystem:exists? exception is raised; otherwise, if dest +exists, its content is replaced with the content of src. File +permissions are transferred from src to dest; on Windows, +the modification time of src is also transferred to dest. If +src refers to a link, the target of the link is copied, +rather than the link itself; if dest refers to a link and +exists-ok? is true, the target of the link is updated.

procedure

(make-file-or-directory-link to path)  void?

  to : path-string?
  path : path-string?
Creates a link path to to. The +creation will fail if path already exists. The to +need not refer to an existing file or directory, and to is +not expanded before writing the link. If the link is not created +successfully,the exn:fail:filesystem exception is raised.

On Windows XP and earlier, the exn:fail:unsupported exception is raised. On +later versions of Windows, the creation of links tends to be +disallowed by security policies. Windows distinguishes between file +and directory links, and a directory link is created only if +to parses syntactically as a directory (see +path->directory-path). Furthermore, a relative-path link is +parsed specially by the operating system; see Windows Paths +for more information. When make-file-or-directory-link +succeeds, it creates a symbolic link as opposed to a junction or hard +link. Beware that directory links must be deleted using +delete-directory instead of delete-file.

Changed in version 6.0.1.12 of package base: Added support for links on Windows.

A parameter that determines on Windows whether +delete-file and delete-directory attempt to change a +file or directory’s permissions to delete it. The default value is +#t.

15.2.3 Directories

See also: rename-file-or-directory, +file-or-directory-modify-seconds, +file-or-directory-permissions.

parameter

(current-directory)  (and/c path? complete-path?)

(current-directory path)  void?
  path : path-string?
A parameter that determines the current directory for resolving +relative paths.

When the parameter procedure is called to set the current directory, +the path argument is cleansed using cleanse-path, +simplified using simplify-path, and then converted to a +directory path with path->directory-path; cleansing and +simplification raise an exception if the path is ill-formed. Thus, the +current value of current-directory is always a cleansed, +simplified, complete, directory path.

The path is not checked for existence when the parameter is set.

On Unix and Mac OS, the initial value of the parameter for a Racket +process is taken from the PWD environment +variable—if the value of the environment variable identifies the +same directory as the operating system’s report of the current +directory.

Like current-directory, but for use only by +srcloc->string for reporting paths relative to a +directory.

Normally, current-directory-for-user should stay at its +initial value, reflecting the directory where a user started a +process. A tool such as DrRacket, however, implicitly lets a user +select a directory (for the file being edited), in which case updating +current-directory-for-user makes sense.

procedure

(current-drive)  path?

Returns the current drive name Windows. For other platforms, the +exn:fail:unsupported exception is raised. The current drive is always the drive +of the current directory.

procedure

(directory-exists? path)  boolean?

  path : path-string?
Returns #t if path refers to a directory, +#f otherwise.

procedure

(make-directory path [permissions])  void?

  path : path-string?
  permissions : (integer-in 0 65535) = #o777
Creates a new directory with the path path. If the directory +is not created successfully, the exn:fail:filesystem exception is raised.

The permissions argument specifies the permissions of the +created directory, where an integer representation of permissions is +treated the same as for file-or-directory-permissions. On +Unix and Mac OS, these permissions bits are combined with the +process’s umask. On Windows, permissions is not used.

Changed in version 8.3.0.5 of package base: Added the permissions argument.

procedure

(delete-directory path)  void?

  path : path-string?
Deletes an existing directory with the path path. If the +directory is not deleted successfully, the +exn:fail:filesystem exception is raised.

On Windows, if an initial attempt to delete the directory fails with a +permission error and the value of current-force-delete-permissions +is true, then delete-file attempts to change the +directory’s permissions (to allow writes) and then delete the +directory; the permission change followed by deletion is a non-atomic +sequence, with no attempt to revert a permission change if the deletion +fails.

Changed in version 6.1.1.7 of package base: Changed Windows behavior to use +current-force-delete-permissions.

procedure

(directory-list [path #:build? build?])  (listof path?)

  path : path-string? = (current-directory)
  build? : any/c = #f

See also the in-directory sequence constructor.

Returns a list of all files and directories in the directory specified +by path. If build? is #f, the resulting +paths are all path elements; otherwise, the individual results +are combined with path using build-path. +On Windows, an element of the result list may start with +\\?\REL\\.

The resulting paths are always sorted using path<?.

procedure

(filesystem-root-list)  (listof path?)

Returns a list of all current root directories. Obtaining this list +can be particularly slow on Windows.

15.2.4 Detecting Filesystem Changes

Many operating systems provide notifications for filesystem changes, +and those notifications are reflected in Racket by filesystem +change events.

procedure

(filesystem-change-evt? v)  boolean?

  v : any/c
Returns #t if v is a filesystem change +event, #f otherwise.

procedure

(filesystem-change-evt path [failure-thunk])

  (or/c filesystem-change-evt? any)
  path : path-string?
  failure-thunk : (or/c (-> any) #f) = #f
Creates a filesystem change event, which is a +synchronizable event that becomes ready for +synchronization after a change to path:

  • If path refers to a file, the event becomes +ready for synchronization when the file’s content or +attributes change, or when the file is deleted.

  • If path refers to a directory, the event becomes +ready for synchronization if a file or subdirectory is +added, renamed, or removed within the directory.

The event also becomes ready for synchronization if +it is passed to filesystem-change-evt-cancel.

Finally, depending on the precision of information available from the +operating system, the event may become ready for +synchronization under other circumstances. For example, on +Windows, an event for a file becomes ready when any file changes +within in the same directory as the file.

After a filesystem change event becomes ready for +synchronization, it stays ready for synchronization. The +event’s synchronization result is the event itself.

If the current platform does not support filesystem-change +notifications, then the exn:fail:unsupported exception is raised if +failure-thunk is not provided as a procedure, or failure-thunk is +called in tail position if provided. Similarly, if there is any +operating-system error when creating the event (such as a non-existent +file), then the exn:fail:filesystem exception is raised or failure-thunk +is called.

Creation of a filesystem change event allocates resources at the +operating-system level. The resources are released at latest when the +event is sychronized and ready for synchronization, when the +event is canceled with filesystem-change-evt-cancel, or when +the garbage collector determine that the filesystem change event is +unreachable. See also system-type in 'fs-change mode.

A filesystem change event is placed under the management of the +current custodian when it is created. If the custodian +is shut down, filesystem-change-evt-cancel is applied to the +event.

Changed in version 7.3.0.8 of package base: Allow #f for failure-thunk.

Causes evt to become immediately ready for +synchronization, whether it was ready or not before, and releases the +resources (at the operating-system level) for tracking filesystem +changes.

15.2.5 Declaring Paths Needed at Run Time

The bindings documented in this section are provided by the racket/runtime-path library, not racket/base or racket.

The racket/runtime-path library provides forms for +accessing files and directories at run time using a path that are +usually relative to an enclosing source file. Unlike using +collection-path, define-runtime-path exposes each +run-time path to tools like the executable and distribution creators, +so that files and directories needed at run time are carried along in +a distribution.

In addition to the bindings described below, +racket/runtime-path provides #%datum in +phase level 1, since string constants are often used as +compile-time expressions with define-runtime-path.

syntax

(define-runtime-path id maybe-runtime?-id expr)

 
maybe-runtime?-id = 
  | #:runtime?-id runtime?-id
Uses expr as both a compile-time (i.e., phase 1) +expression and a run-time (i.e., phase 0) expression. In either +context, expr should produce a path, a string that represents +a path, a list of the form (list 'lib str ...+), or a list +of the form (list 'so str) or (list 'so str vers). +If runtime?-id is provided, then it is bound in the context +of expr to #f for the compile-time instance of +expr and #t for the run-time instance of expr.

For run time, id is bound to a path that is based on the +result of expr. The path is normally computed by taking a +relative path result from expr and adding it to a path for +the enclosing file (which is computed as described below). However, +tools like the executable creator can also arrange (by colluding with +racket/runtime-path) to have a different base path +substituted in a generated executable. If expr produces an +absolute path, it is normally returned directly, but again may be +replaced by an executable creator. In all cases, the executable +creator preserves the relative locations of all paths within a given +package (treating paths outside of any package as being together). +When expr produces a relative or absolute path, then the path +bound to id is always an absolute path.

If expr produces a list of the form (list 'lib str ...+), the value bound to id is an absolute path. The path +refers to a collection-based file similar to using the value as a +module path.

If expr produces a list of the form (list 'so str) +or (list 'so str vers), +the value bound to id can be either str or an +absolute path; it is an absolute path when searching in the +Racket-specific shared-object library directories (as determined by +get-lib-search-dirs) locates the path. In this way, shared-object +libraries that are installed specifically for Racket get carried +along in distributions. The search tries each directory in order; +within a directory, the search tries using str directly, +then it tries adding each version specified by verswhich defaults +to '(#f)along with +a platform-specific shared-library extension—as produced by +(system-type 'so-suffix). A vers +can be a string, or it can be a list of strings and #f.

If expr produces a list of the form (list 'share str), the value bound to id can be either str or +an absolute path; it is an absolute path when searching in the +directories reported by find-user-share-dir and +find-share-dir (in that order) locates the path. In this way, +files that are installed in Racket’s "share" directory get +carried along in distributions.

If expr produces a list of the form (list 'module module-path var-ref) or (list 'so str (list str-or-false ...)), the value bound to id is a +module path index, where module-path is treated as +relative (if it is relative) to the module that is the home of the +variable reference var-ref, where var-ref +can be #f if module-path is absolute. In an +executable, the corresponding module is carried along, including all +of its dependencies.

For compile-time, the expr result is used by an executable +creator—but not the result when the containing module is +compiled. Instead, expr is preserved in the module as a +compile-time expression (in the sense of +begin-for-syntax). Later, at the time that an executable is +created, the compile-time portion of the module is executed (again), +and the result of expr is the file or directory to be included with the +executable. The reason for the extra compile-time execution is that +the result of expr might be platform-dependent, so the result +should not be stored in the (platform-independent) bytecode form of +the module; the platform at executable-creation time, however, is the +same as at run time for the executable. Note that expr is +still evaluated at run time; consequently, avoid procedures like +collection-path, which depends on the source installation, +and instead use relative paths and forms like (list 'lib str ...+).

If a path is needed only on some platforms and not on others, use +define-runtime-path-list with an expr that produces an +empty list on platforms where the path is not needed.

Beware that if expr produces the path of a directory when +creating an executable, the directory’s full content (including any +subdirectories) is included with the executable or eventual +distribution.

Also beware that define-runtime-path in a phase level other +than 0 does not cooperate properly with an executable creator. To work +around that limitation, put define-runtime-path in a separate +module—perhaps a submodule created by modulethen +export the definition, and then the module containing the definition +can be required into any phase level. Using +define-runtime-path in a phase level other than 0 +logs a warning at expansion time.

The enclosing path for a define-runtime-path is determined as +follows from the define-runtime-path syntactic form:

In the latter two cases, the path is normally preserved in +(platform-specific) byte form, but if the enclosing path corresponds to a +result of collection-file-path, then the path is record as +relative to the corresponding module path.

Changed in version 6.0.1.6 of package base: Preserve relative paths only within a package.
Changed in version 7.5.0.7: Added support for 'share in expr.

Examples:

; Access a file "data.txt" at run-time that is originally
; located in the same directory as the module source file:
(define-runtime-path data-file "data.txt")
(define (read-data)
  (with-input-from-file data-file
    (lambda ()
      (read-bytes (file-size data-file)))))
 
; Load a platform-specific shared object (using ffi-lib)
; that is located in a platform-specific sub-directory of the
; module's source directory:
(define-runtime-path libfit-path
  (build-path "compiled" "native" (system-library-subpath #f)
              (path-replace-suffix "libfit"
                                   (system-type 'so-suffix))))
(define libfit (ffi-lib libfit-path))
 
; Load a platform-specific shared object that might be installed
; as part of the operating system, or might be installed
; specifically for Racket:
(define-runtime-path libssl-so
  (case (system-type)
    [(windows) '(so "ssleay32")]
    [else '(so "libssl")]))
(define libssl (ffi-lib libssl-so))

Changed in version 6.4 of package base: Added #:runtime?-id.

syntax

(define-runtime-paths (id ...) maybe-runtime?-id expr)

Like define-runtime-path, but declares and binds multiple +paths at once. The expr should produce as many values as +ids.

syntax

(define-runtime-path-list id maybe-runtime?-id expr)

Like define-runtime-path, but expr should produce a +list of paths.

syntax

(define-runtime-module-path-index id maybe-runtime?-id module-path-expr)

Similar to define-runtime-path, but id is bound to a +module path index that encapsulates the result of +module-path-expr relative to the enclosing module.

Use define-runtime-module-path-index to bind a module path that is +passed to a reflective function like dynamic-require while +also creating a module dependency for building and distributing +executables.

syntax

(runtime-require module-path)

Similar to define-runtime-module-path-index, but creates the +distribution dependency without binding a module path index. When +runtime-require is used multiple times within a module with +the same module-path, all but the first use expands to an +empty begin.

syntax

(define-runtime-module-path id module-path)

Similar to define-runtime-path, but id is bound to a +resolved module path. The resolved module path for +id corresponds to module-path (with the same syntax +as a module path for require), which can be relative to the +enclosing module.

The define-runtime-module-path-index form is usually +preferred, because it creates a weaker link to the referenced module. +Unlike define-runtime-module-path-index, the +define-runtime-module-path form creates a for-label +dependency from an enclosing module to module-path. Since the +dependency is merely for-label, module-path is not +instantiated or visited when the enclosing module is +instantiated or visited (unless such a dependency is +created by other requires), but the code for the referenced +module is loaded when the enclosing module is loaded.

syntax

(runtime-paths module-path)

This form is mainly for use by tools such as executable builders. It +expands to a quoted list containing the run-time paths declared by +module-path, returning the compile-time results of the +declaration exprs, except that paths are converted to byte +strings. The enclosing module must require (directly or indirectly) +the module specified by module-path, which is an unquoted +module path. The resulting list does not include module paths +bound through define-runtime-module-path.

15.2.6 More File and Directory Utilities

 (require racket/file) package: base
The bindings documented in this section are provided by the racket/file and racket libraries, but not racket/base.

procedure

(file->string path [#:mode mode-flag])  string?

  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
Reads all characters from path and returns them as a string. +The mode-flag argument is the same as for +open-input-file.

procedure

(file->bytes path [#:mode mode-flag])  bytes?

  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
Reads all characters from path and returns them as a +byte string. The mode-flag argument is the same as +for open-input-file.

procedure

(file->value path [#:mode mode-flag])  any

  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
Reads a single S-expression from path using read. +The mode-flag argument is the same as for +open-input-file.

procedure

(file->list path [proc #:mode mode-flag])  (listof any/c)

  path : path-string?
  proc : (input-port? . -> . any/c) = read
  mode-flag : (or/c 'binary 'text) = 'binary
Repeatedly calls proc to consume the contents of +path, until eof is produced. The mode-flag +argument is the same as for open-input-file.

procedure

(file->lines path    
  [#:mode mode-flag    
  #:line-mode line-mode])  (listof string?)
  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
  line-mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'any
Read all characters from path, breaking them into lines. The +line-mode argument is the same as the second argument to +read-line, but the default is 'any instead of +'linefeed. The mode-flag argument is the same as for +open-input-file.

procedure

(file->bytes-lines path    
  [#:mode mode-flag    
  #:line-mode line-mode])  (listof bytes?)
  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
  line-mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'any
Like file->lines, but reading bytes and collecting them into +lines like read-bytes-line.

procedure

(display-to-file v    
  path    
  [#:mode mode-flag    
  #:exists exists-flag])  void?
  v : any/c
  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update
      'replace 'truncate 'truncate/replace)
   = 'error
Uses display to print v to path. The mode-flag and +exists-flag arguments are the same as for +open-output-file.

procedure

(write-to-file v    
  path    
  [#:mode mode-flag    
  #:exists exists-flag])  void?
  v : any/c
  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update
      'replace 'truncate 'truncate/replace)
   = 'error
Like display-to-file, but using write instead of display.

procedure

(display-lines-to-file lst    
  path    
  [#:separator separator    
  #:mode mode-flag    
  #:exists exists-flag])  void?
  lst : list?
  path : path-string?
  separator : any/c = #"\n"
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update
      'replace 'truncate 'truncate/replace)
   = 'error
Displays each element of lst to path, adding +separator after each element. The mode-flag and +exists-flag arguments are the same as for +open-output-file.

procedure

(copy-directory/files 
  src 
  dest 
  #:keep-modify-seconds? keep-modify-seconds? 
  #:preserve-links? preserve-links?) 
  void?
  src : path-string?
  dest : path-string?
  keep-modify-seconds? : #f
  preserve-links? : #f
Copies the file or directory src to dest, raising +exn:fail:filesystem if the file or directory cannot be +copied, possibly because dest exists already. If src +is a directory, the copy applies recursively to the directory’s +content. If a source is a link and preserve-links? is #f, +the target of the link is copied rather than the link itself; if +preserve-links? is #t, the link is copied.

If keep-modify-seconds? is #f, then file copies +keep only the properties kept by copy-file. If +keep-modify-seconds? is true, then each file copy also keeps +the modification date of the original.

Changed in version 6.3 of package base: Added the #:preserve-links? argument.

procedure

(delete-directory/files path    
  #:must-exist? must-exist?)  void?
  path : path-string?
  must-exist? : #t
Deletes the file or directory specified by path, raising +exn:fail:filesystem if the file or directory cannot be +deleted. If path is a directory, then +delete-directory/files is first applied to each file and +directory in path before the directory is deleted.

If must-exist? is true, then exn:fail:filesystem is +raised if path does not exist. If must-exist? is +false, then delete-directory/files succeeds if path +does not exist (but a failure is possible if path initially +exists and is removed by another thread or process before +delete-directory/files deletes it).

On Windows, delete-directory/files attempts to move a file +into the temporary-file directory before deleting it, which avoids +problems caused by deleting a file that is currently open (e.g., by a +search indexer running as a background process). If the move attempt +fails (e.g., because the temporary directory is on a different drive +than the file), then the file is deleted directly with +delete-file.

Changed in version 7.0 of package base: Added Windows-specific file deletion.

procedure

(find-files 
  predicate 
  [start-path] 
  #:skip-filtered-directory? skip-filtered-directory? 
  #:follow-links? follow-links?) 
  (listof path?)
  predicate : (path? . -> . any/c)
  start-path : (or/c path-string? #f) = #f
  skip-filtered-directory? : #f
  follow-links? : #f
Traverses the filesystem starting at start-path and creates a +list of all files and directories for which predicate returns +true. If start-path is #f, then the traversal starts +from (current-directory). In the resulting list, each +directory precedes its content.

The predicate procedure is called with a single argument for +each file or directory. If start-path is #f, the +argument is a pathname string that is relative to the current +directory. Otherwise, it is a path building on +start-path. Consequently, supplying +(current-directory) for start-path is different from +supplying #f, because predicate receives complete +paths in the former case and relative paths in the latter. Another +difference is that predicate is not called for the current +directory when start-path is #f.

If skip-filtered-directory? is true, then when +predicate returns #f for a directory, the +directory’s content is not traversed.

If follow-links? is true, the find-files traversal +follows links, and links are not included in the result. If +follow-links? is #f, then links are not followed, +and links are included in the result.

If start-path does not refer to an existing file or +directory, then predicate will be called exactly once with +start-path as the argument.

The find-files procedure raises an exception if it encounters +a directory for which directory-list fails.

Changed in version 6.3.0.11 of package base: Added the +#:skip-filtered-directory? +argument.

procedure

(pathlist-closure path-list 
  [#:path-filter path-filter 
  #:follow-links? follow-links?]) 
  (listof path?)
  path-list : (listof path-string?)
  path-filter : (or/c #f (path? . -> . any/c)) = #f
  follow-links? : any/c = #f
Given a list of paths, either absolute or relative to the current +directory, returns a list such that

  • if a nested path is given, all of its ancestors are also +included in the result (but the same ancestor is not added +twice);

  • if a path refers to directory, all of its descendants are also +included in the result, except as omitted by path-filter;

  • ancestor directories appear before their descendants in the +result list, as long as they are not misordered in the given +path-list.

If path-filter is a procedure, then it is applied to each +descendant of a directory. If path-filter returns +#f, then the descendant (and any of its descendants, in the +case of a subdirectory) are omitted from the result.

If follow-links? is true, then the traversal of directories +and files follows links, and the link paths are not included in the +result. If follow-links? is #f, then the result list +includes paths to link and the links are not followed.

Changed in version 6.3.0.11 of package base: Added the #:path-filter argument.

procedure

(fold-files proc    
  init-val    
  [start-path    
  follow-links?])  any
  proc : 
(or/c (path? (or/c 'file 'dir 'link) any/c
        . -> . any/c)
      (path? (or/c 'file 'dir 'link) any/c
        . -> . (values any/c any/c)))
  init-val : any/c
  start-path : (or/c path-string? #f) = #f
  follow-links? : any/c = #t
Traverses the filesystem starting at start-path, calling +proc on each discovered file, directory, and link. If +start-path is #f, then the traversal starts from +(current-directory).

The proc procedure is called with three arguments for each +file, directory, or link:

  • If start-path is #f, the first argument is a +pathname string that is relative to the current directory. Otherwise, +the first argument is a pathname that starts with +start-path. Consequently, supplying +(current-directory) for start-path is different +from supplying #f, because proc receives complete +paths in the former case and relative paths in the latter. Another +difference is that proc is not called for the current +directory when start-path is #f.

  • The second argument is a symbol, either 'file, +'dir, or 'link. The second argument can be +'link when follow-links? is #f, +in which case the filesystem traversal does not follow links. If +follow-links? is #t, then proc +will only get a 'link as a second argument when it +encounters a dangling symbolic link (one that does not resolve to an +existing file or directory).

  • The third argument is the accumulated result. For the first +call to proc, the third argument is init-val. For the +second call to proc (if any), the third argument is the result +from the first call, and so on. The result of the last call to +proc is the result of fold-files.

The proc argument is used in an analogous way to the +procedure argument of foldl, where its result is used as the +new accumulated result. There is an exception for the case of a +directory (when the second argument is 'dir): in this case +the procedure may return two values, the second indicating whether the +recursive scan should include the given directory or not. If it +returns a single value, the directory is scanned. In the cases of +files or links (when the second argument is 'file or +'link), a second value is permitted but ignored.

If the start-path is provided but no such path exists, or if +paths disappear during the scan, then an exception is raised.

procedure

(make-directory* path)  void?

  path : path-string?
Creates directory specified by path, creating intermediate +directories as necessary, and never failing if path exists +already.

If path is a relative path and the current directory does not +exist, then make-directory* will not create the current +directory, because it considers only explicit elements of +path.

procedure

(make-parent-directory* path)  void?

  path : path-string?
Creates the parent directory of the path specified by path, +creating intermediate directories as necessary, and never failing if +an ancestor of path exists already.

If path is a filesystem root or a relative path with a single +path element, then no directory is created. Like +make-directory*, if path is a relative path and the +current directory does not exist, then make-parent-directory* +will not create it.

Added in version 6.1.1.3 of package base.

procedure

(make-temporary-file [template 
  #:copy-from copy-from 
  #:base-dir base-dir 
  compat-copy-from 
  compat-base-dir]) 
  (and/c path? complete-path?)
  template : string? = "rkttmp~a"
  copy-from : (or/c path-string? #f 'directory) = #f
  base-dir : (or/c path-string? #f) = #f
  compat-copy-from : (or/c path-string? #f 'directory)
   = copy-from
  compat-base-dir : (or/c path-string? #f) = base-dir
Creates a new temporary file and returns its path. +Instead of merely generating a fresh file name, the file is +actually created; this prevents other threads or processes from +picking the same temporary name.

The template argument must be a format string +suitable for use with format and one additional +string argument (which will contain only digits). By +default, if template produces a relative path, it +is combined with the result of +(find-system-path 'temp-dir) using +build-path; alternatively, template may +produce an absolute path, in which case +(find-system-path 'temp-dir) is not consulted. If +base-dir is provided and non-#false, +template must not produce a complete path, +and base-dir will be used instead of +(find-system-path 'temp-dir). Using +base-dir is generally more reliable than including +directory components in template: it avoids subtle +bugs from manipulating paths as string and eleminates the +need to sanitize format escape sequences.

On Windows, template may produce an absolute path +which is not a complete path (see Windows Paths) +when base-dir is absent or #f (in which +case it will be resolved relative to +(current-directory)) or if base-dir is a +drive specification (in which case it will be used as with +build-path). If base-dir is any other kind +of path, it is an error for template to produce an +absolute path.

When the template argument is not provided, if +there is source location information for the callsite of +make-temporary-file, a template string is generated +based on the source location: the default is +"rkttmp~a" only when no source location information +is available (e.g. if make-temporary-file is used +in a higher-order position).

If copy-from is provided as path, the temporary file +is created as a copy of the named file (using copy-file). If +copy-from is #f, the temporary file is +created as empty. As a special case, for backwards compatibility, +if copy-from is 'directory, +then the temporary “file” is created as a directory: +for clarity, prefer make-temporary-directory for creating +temporary directories.

When a temporary file is created, it is not opened for reading or +writing when the path is returned. The client program calling +make-temporary-file is expected to open the file with the +desired access and flags (probably using the 'truncate flag; +see open-output-file) and to delete it when it is no longer +needed.

The by-position arguments compat-copy-from and +compat-base-dir are for backwards compatibility: +if provided, they take precedence over the #:copy-from and +#:base-dir keyword variants. +Supplying by-position arguments prevents make-temporary-file +from generating a template using the source location.

Changed in version 8.4.0.3 of package base: Added the #:copy-from and #:base-dir arguments.

procedure

(make-temporary-directory [template 
  #:base-dir base-dir]) 
  (and/c path? complete-path?)
  template : string? = "rkttmp~a"
  base-dir : (or/c path-string? #f) = #f
Like make-temporary-file, but + creates a directory, rather than a regular file.

As with make-temporary-file, if the + template argument is not provided, a template + string is generated from the source location of the call to + make-temporary-directory when possible: the default + is "rkttmp~a" only when no source location + information is available.

Added in version 8.4.0.3 of package base.

procedure

(make-temporary-file* prefix 
  suffix 
  [#:copy-from copy-from 
  #:base-dir base-dir]) 
  (and/c path? complete-path?)
  prefix : bytes?
  suffix : bytes?
  copy-from : (or/c path-string? #f) = #f
  base-dir : (or/c path-string? #f) = #f

procedure

(make-temporary-directory* prefix 
  suffix 
  [#:base-dir base-dir]) 
  (and/c path? complete-path?)
  prefix : bytes?
  suffix : bytes?
  base-dir : (or/c path-string? #f) = #f
Like make-temporary-file and +make-temporary-directory, respectively, but, rather +than using a template for format, the path is based +on (bytes-append prefix generated suffix), where +generated is a byte string chosen by the +implementation to produce a unique path. If there is source +location information for the callsite of +make-temporary-file* or +make-temporary-directory*, generated will +incorporate that information. The resulting path is combined +with base-dir as with make-temorary-file.

Added in version 8.4.0.3 of package base.

procedure

(call-with-atomic-output-file 
  file 
  proc 
  [#:security-guard security-guard 
  #:rename-fail-handler rename-fail-handler]) 
  any
  file : path-string?
  proc : ([port output-port?] [tmp-path path?]  . -> . any)
  security-guard : (or/c #f security-guard?) = #f
  rename-fail-handler : (or/c #f (exn:fail:filesystem? path> . -> . any))
   = #f
Opens a temporary file for writing in the same directory as +file, calls proc to write to the temporary file, and +then atomically (except on Windows) moves the temporary file in place of file. +The move simply uses rename-file-or-directory on Unix +and Mac OS, and it uses rename-file-or-directory on Windows +if rename-fail-handler is provided; otherwise, on Windows, +the moves uses an extra rename step (see below) on Windows +to avoid problems due to concurrent readers of file.

The proc function is called with an output port for the +temporary file, plus the path of the temporary file. The result of +proc is the result of call-with-atomic-output-file.

The call-with-atomic-output-file function arranges to delete +temporary files on exceptions.

Windows prevents programs from deleting or replacing files that are +open, but it allows renaming of open files. Therefore, on Windows, +call-with-atomic-output-file by default creates a second +temporary file extra-tmp-file, renames file to +extra-tmp-file, renames the temporary file written by +proc to file, and finally deletes +extra-tmp-file. Since that process is not atomic, however, +rename-file-or-directory is used if +rename-fail-handler is provided, where +rename-file-or-directory has some chance of being atomic, +since that the source and destination of the moves will be in the same +directory; any filesystem exception while attempting to rename the +file is send to rename-fail-handler, which can +re-raise the exception or simply return to try again, perhaps +after a delay. In addition to a filesystem exception, the +rename-fail-handler procedure also receives the temporary +file path to be moved to path. The +rename-fail-handler argument is used only on Windows.

Changed in version 7.1.0.6 of package base: Added the #:rename-fail-handler argument.

procedure

(get-preference name    
  [failure-thunk    
  flush-mode    
  filename    
  #:use-lock? use-lock?    
  #:timeout-lock-there timeout-lock-there    
  #:lock-there lock-there])  any
  name : symbol?
  failure-thunk : (-> any) = (lambda () #f)
  flush-mode : any/c = 'timestamp
  filename : (or/c string-path? #f) = #f
  use-lock? : any/c = #t
  timeout-lock-there : (or/c (path? . -> . any) #f) = #f
  lock-there : (or/c (path? . -> . any) #f)
   = 
(make-handle-get-preference-locked
 0.01 name failure-thunk flush-mode filename
 #:lock-there timeout-lock-there)
Extracts a preference value from the file designated by +(find-system-path 'pref-file), or by filename if it +is provided and is not #f. In the former case, if the +preference file doesn’t exist, get-preferences attempts to +read an old preferences file, and then a +"racket-prefs.rktd" file in the configuration directory +(as reported by find-config-dir), instead. If none of those +files exists, the preference set is empty.

The preference file should contain a list of symbol–value lists +written with the default parameter settings. Keys +starting with racket:, mzscheme:, mred:, +and plt: in any letter case are reserved for use by Racket +implementors. If the preference file does not contain a list +of symbol–value lists, an error is logged via log-error +and failure-thunk is called.

The result of get-preference is the value associated with +name if it exists in the association list, or the result of +calling failure-thunk otherwise.

Preference settings are cached (weakly) across calls to +get-preference, using (path->complete-path filename) +as a cache key. If flush-mode is provided as #f, the +cache is used instead of re-consulting the preferences file. If +flush-mode is provided as 'timestamp (the default), +then the cache is used only if the file has a timestamp that is the +same as the last time the file was read. Otherwise, the file is +re-consulted.

On platforms for which preferences-lock-file-mode returns +'file-lock and when use-lock? is true, +preference-file reading is guarded by a lock; multiple readers can +share the lock, but writers take the lock exclusively. If the +preferences file cannot be read because the lock is unavailable, +lock-there is called on the path of the lock file; if +lock-there is #f, an exception is raised. The +default lock-there handler retries about 5 times (with +increasing delays between each attempt) before trying +timeout-lock-there, and the default timeout-lock-there +triggers an exception.

See also put-preferences. For a more elaborate preference +system, see preferences:get.

Old preferences files: When a +filename is not provided and the file indicated by +(find-system-path 'pref-file) does not exist, the following +paths are checked for compatibility with old versions of Racket:

procedure

(put-preferences names    
  vals    
  [locked-proc    
  filename])  void?
  names : (listof symbol?)
  vals : list?
  locked-proc : (or/c #f (path? . -> . any)) = #f
  filename : (or/c #f path-string?) = #f
Installs a set of preference values and writes all current values to +the preference file designated by (find-system-path 'pref-file), or filename if it is supplied and not +#f.

The names argument supplies the preference names, and +vals must have the same length as names. Each +element of vals must be an instance of a built-in data type +whose write output is readable (i.e., the +print-unreadable parameter is set to #f while +writing preferences).

Current preference values are read from the preference file before +updating, and a write lock is held starting before the file +read, and lasting until after the preferences file is updated. The +lock is implemented by the existence of a file in the same directory +as the preference file; see preferences-lock-file-mode for +more information. If the directory of the preferences file does +not already exist, it is created.

If the write lock is already held, then +locked-proc is called with a single argument: the path of the lock +file. The default locked-proc (used when the locked-proc +argument is #f) reports an error; an alternative +thunk might wait a while and try again, or give the user the choice to +delete the lock file (in case a previous update attempt encountered +disaster and locks are implemented by the presence of the lock file).

If filename is #f or not supplied, and the +preference file does not already exist, then values read from the +"defaults" collection (if any) are written for preferences +that are not mentioned in names.

procedure

(preferences-lock-file-mode)  (or/c 'exists 'file-lock)

Reports the way that the lock file is used to implement +preference-file locking on the current platform.

The 'exists mode is currently used on all platforms except +Windows. In 'exists mode, the existence of the lock file +indicates that a write lock is held, and readers need no lock (because +the preferences file is atomically updated via +rename-file-or-directory).

The 'file-lock mode is currently used on Windows. In +'file-lock mode, shared and exclusive locks (in the sense of +port-try-file-lock?) on the lock file reflect reader and +writer locks on the preference-file content. (The preference file +itself is not locked, because a lock would interfere with replacing +the file via rename-file-or-directory.)

procedure

(make-handle-get-preference-locked delay 
  name 
  [failure-thunk 
  flush-mode 
  filename 
  #:lock-there lock-there 
  #:max-delay max-delay]) 
  (path-string? . -> . any)
  delay : real?
  name : symbol?
  failure-thunk : (-> any) = (lambda () #f)
  flush-mode : any/c = 'timestamp
  filename : (or/c path-string? #f) = #f
  lock-there : (or/c (path? . -> . any) #f) = #f
  max-delay : real? = 0.2
Creates a procedure suitable for use as the #:lock-there +argument to get-preference, where the name, +failure-thunk, flush-mode, and filename +are all passed on to get-preference by the result procedure +to retry the preferences lookup.

Before calling get-preference, the result procedure uses +(sleep delay) to pause. Then, if (* 2 delay) is less +than max-delay, the result procedure calls +make-handle-get-preference-locked to generate a new retry +procedure to pass to get-preference, but with a +delay of (* 2 delay). If (* 2 delay) is not +less than max-delay, then get-preference is called +with the given lock-there, instead.

procedure

(call-with-file-lock/timeout filename    
  kind    
  thunk    
  failure-thunk    
  [#:lock-file lock-file    
  #:delay delay    
  #:max-delay max-delay])  any
  filename : (or/c path-string? #f)
  kind : (or/c 'shared 'exclusive)
  thunk : (-> any)
  failure-thunk : (-> any)
  lock-file : (or/c #f path-string?) = #f
  delay : (and/c real? (not/c negative?)) = 0.01
  max-delay : (and/c real? (not/c negative?)) = 0.2
Obtains a lock for the filename lock-file and then calls +thunk. The filename argument specifies a file path +prefix that is used only to generate the lock filename when +lock-file is #f. Specifically, when +lock-file is #f, then +call-with-file-lock/timeout uses make-lock-file-name +to build the lock filename. If the lock file does not yet exist, it is +created; beware that the lock file is not deleted by +call-with-file-lock/timeout.

When thunk returns, +call-with-file-lock/timeout releases the lock, returning the result of +thunk. The call-with-file-lock/timeout function will retry +after delay seconds and continue retrying with exponential backoff +until delay reaches max-delay. If +call-with-file-lock/timeout fails to obtain the lock, +failure-thunk is called in tail position. The kind argument +specifies whether the lock is 'shared or 'exclusive +in the sense of port-try-file-lock?.

Examples:
> (call-with-file-lock/timeout filename 'exclusive
    (lambda () (printf "File is locked\n"))
    (lambda () (printf "Failed to obtain lock for file\n")))

File is locked

> (call-with-file-lock/timeout #f 'exclusive
    (lambda ()
      (call-with-file-lock/timeout filename 'shared
        (lambda () (printf "Shouldn't get here\n"))
        (lambda () (printf "Failed to obtain lock for file\n"))))
    (lambda () (printf "Shouldn't get here either\n"))
    #:lock-file (make-lock-file-name filename))

Failed to obtain lock for file

procedure

(make-lock-file-name path)  path?

  path : (or path-string? path-for-some-system?)
(make-lock-file-name dir name)  path?
  dir : (or path-string? path-for-some-system?)
  name : path-element?
Creates a lock filename by prepending "_LOCK" on Windows +(i.e., when cross-system-type reports 'windows) or +".LOCK" on other platforms to the file portion of the path.

Example:
> (make-lock-file-name "/home/george/project/important-file")

#<path:/home/george/project/.LOCKimportant-file>

value

file-type-bits : #o170000

value

socket-type-bits : #o140000

value

symbolic-link-type-bits : #o120000

value

regular-file-type-bits : #o100000

value

block-device-type-bits : #o060000

value

directory-type-bits : #o040000

value

character-device-type-bits : #o020000

value

fifo-type-bits : #o010000

value

set-user-id-bit : #o004000

value

set-group-id-bit : #o002000

value

sticky-bit : #o001000

value

user-permission-bits : #o000700

value

user-read-bit : #o000400

value

user-write-bit : #o000200

value

user-execute-bit : #o000100

value

group-permission-bits : #o000070

value

group-read-bit : #o000040

value

group-write-bit : #o000020

value

group-execute-bit : #o000010

value

other-permission-bits : #o000007

value

other-read-bit : #o000004

value

other-write-bit : #o000002

value

other-execute-bit : #o000001

Constants that are useful with file-or-directory-permissions, +file-or-directory-stat and bitwise operations such as +bitwise-ior, and bitwise-and.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Generating_A_Unit_from_Context.html b/clones/docs.racket-lang.org/reference/Generating_A_Unit_from_Context.html new file mode 100644 index 00000000..ffc0dd48 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Generating_A_Unit_from_Context.html @@ -0,0 +1,9 @@ + +7.5 Generating A Unit from Context

7.5 Generating A Unit from Context

syntax

(unit-from-context tagged-sig-spec)

Creates a unit that implements an interface using bindings in the +enclosing environment. The generated unit is essentially the same as

(unit
  (import)
  (export tagged-sig-spec)
  (define id expr) ...)

for each id that must be defined to satisfy the exports, and +each corresponding expr produces the value of id in +the environment of the unit-from-context expression. (The unit +cannot be written as above, however, since each id definition +within the unit shadows the binding outside the unit form.)

See unit for the grammar of tagged-sig-spec.

syntax

(define-unit-from-context id tagged-sig-spec)

Like unit-from-context, in that a unit is constructed from +the enclosing environment, and like define-unit, in that +id is bound to static information to be used later with inference.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Generators.html b/clones/docs.racket-lang.org/reference/Generators.html new file mode 100644 index 00000000..0e37e513 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Generators.html @@ -0,0 +1,49 @@ + +4.16.3 Generators
4.16.3 Generators

A generator is a procedure that returns a sequence of +values, incrementing the sequence each time that the generator is +called. In particular, the generator form implements a +generator by evaluating a body that calls yield to return +values from the generator.

 (require racket/generator) package: base

procedure

(generator? v)  boolean?

  v : any/c
Return #t if v is a generator, +#f otherwise.

syntax

(generator formals body ...+)

 
formals = (id ...)
  | (id ...+ . rest-id)
  | rest-id
Creates a generator, where formals specify the arguments. +Keyword and optional arguments are not supported. This is the same as the +formals of a single case-lambda clause.

For the first call to a generator, the arguments are bound to the +formals and evaluation of body starts. During the +dynamic extent of body, the generator can return +immediately using the yield function. A second call to the +generator resumes at the yield call, producing the +arguments of the second call as the results of the yield, +and so on. The eventual results of body are supplied to an +implicit final yield; after that final yield, +calling the generator again returns the same values, but all such +calls must provide 0 arguments to the generator.

Examples:
> (define g (generator ()
              (let loop ([x '(a b c)])
                (if (null? x)
                    0
                    (begin
                      (yield (car x))
                      (loop (cdr x)))))))
> (g)

'a

> (g)

'b

> (g)

'c

> (g)

0

> (g)

0

procedure

(yield v ...)  any

  v : any/c
Returns vs from a generator, saving the point of execution +inside a generator (i.e., within the dynamic extent of a +generator body) to be resumed by the next call to the +generator. The results of yield are the arguments that are +provided to the next call of the generator.

When not in the dynamic extent of a generator, +infinite-generator, or in-generator body, +yield raises exn:fail after evaluating its +exprs.

Examples:
> (define my-generator (generator () (yield 1) (yield 2 3 4)))
> (my-generator)

1

> (my-generator)

2

3

4

Examples:
> (define pass-values-generator
    (generator ()
      (let* ([from-user (yield 2)]
             [from-user-again (yield (add1 from-user))])
        (yield from-user-again))))
> (pass-values-generator)

2

> (pass-values-generator 5)

6

> (pass-values-generator 12)

12

syntax

(infinite-generator body ...+)

Like generator, but repeats evaluation of the +bodys when the last body completes without +implicitly yielding.

Examples:
> (define welcome
    (infinite-generator
      (yield 'hello)
      (yield 'goodbye)))
> (welcome)

'hello

> (welcome)

'goodbye

> (welcome)

'hello

> (welcome)

'goodbye

syntax

(in-generator maybe-arity body ...+)

 
maybe-arity = 
  | #:arity arity-k
Produces a sequence that encapsulates the generator +formed by (generator () body ...+). The values produced by +the generator form the elements of the sequence, except for the last +value produced by the generator (i.e., the values produced by +returning).

Example:
> (for/list ([i (in-generator
                  (let loop ([x '(a b c)])
                    (when (not (null? x))
                      (yield (car x))
                      (loop (cdr x)))))])
    i)

'(a b c)

If in-generator is used immediately with a for (or +for/list, etc.) binding’s right-hand side, then its result +arity (i.e., the number of values in each element of the sequence) +can be inferred. Otherwise, if the generator produces multiple +values for each element, its arity should be declared with an +#:arity arity-k clause; the arity-k must be a +literal, exact, non-negative integer.

Examples:
> (let ([g (in-generator
            (let loop ([n 3])
              (unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))])
    (let-values ([(not-empty? next) (sequence-generate g)])
      (let loop () (when (not-empty?) (next) (loop))) 'done))

stop?: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 1

  given: 2

> (let ([g (in-generator #:arity 2
            (let loop ([n 3])
              (unless (zero? n) (yield n (add1 n)) (loop (sub1 n)))))])
    (let-values ([(not-empty? next) (sequence-generate g)])
      (let loop () (when (not-empty?) (next) (loop))) 'done))

'done

To use an existing generator as a sequence, use in-producer +with a stop-value known for the generator:

> (define abc-generator (generator ()
                         (for ([x '(a b c)])
                            (yield x))))
> (for/list ([i (in-producer abc-generator (void))])
    i)

'(a b c)

> (define my-stop-value (gensym))
> (define my-generator (generator ()
                         (let loop ([x (list 'a (void) 'c)])
                           (if (null? x)
                               my-stop-value
                               (begin
                                 (yield (car x))
                                 (loop (cdr x)))))))
> (for/list ([i (in-producer my-generator my-stop-value)])
    i)

'(a #<void> c)

procedure

(generator-state g)  symbol?

  g : generator?
Returns a symbol that describes the state of the generator.

  • 'fresh The generator has been freshly created and +has not been called yet.

  • 'suspended Control within the generator has been +suspended due to a call to yield. The generator can +be called.

  • 'running The generator is currently executing.

  • 'done The generator has executed its entire +body and will continue to produce the same result as from +the last call.

Examples:
> (define my-generator (generator () (yield 1) (yield 2)))
> (generator-state my-generator)

'fresh

> (my-generator)

1

> (generator-state my-generator)

'suspended

> (my-generator)

2

> (generator-state my-generator)

'suspended

> (my-generator)
> (generator-state my-generator)

'done

> (define introspective-generator (generator () ((yield 1))))
> (introspective-generator)

1

> (introspective-generator
   (lambda () (generator-state introspective-generator)))

'running

> (generator-state introspective-generator)

'done

> (introspective-generator)

'running

procedure

(sequence->generator s)  (-> any)

  s : sequence?
Converts a sequence to a generator. The generator +returns the next element of the sequence each time the generator is +invoked, where each element of the sequence must be a single +value. When the sequence ends, the generator returns #<void> +as its final result.

procedure

(sequence->repeated-generator s)  (-> any)

  s : sequence?
Like sequence->generator, but when s has no +further values, the generator starts the sequence again (so that the +generator never stops producing values).

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Interactive_Help.html b/clones/docs.racket-lang.org/reference/Interactive_Help.html new file mode 100644 index 00000000..6900d3fa --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Interactive_Help.html @@ -0,0 +1,22 @@ + +18.3 Interactive Help

18.3 Interactive Help

 (require racket/help) package: base
The bindings documented in this section are provided by the racket/help and racket/init libraries, which means that they are available when the Racket executable is started with no command-line arguments. They are not provided by racket/base or racket.

syntax

help

(help string ...)
(help id)
(help id #:from module-path)
(help #:search datum ...)
For general help, see the main documentation page.

The help form searches the documentation and opens a web +browser (using the user’s selected browser) to display the results.

See net/sendurl for information on how +the user’s browser is launched to display help information.

A simple help or (help) form opens the main +documentation page.

The (help string ...) form—using literal strings, as +opposed to expressions that produce strings—performs a +string-matching search. For example,

(help "web browser" "firefox")

searches the documentation index for references that include the +phrase “web browser” or “firefox.”

A (help id) form looks for documentation specific to the +current binding of id. For example,

(require net/url)
(help url->string)

opens a web browser to show the documentation for url->string +from the net/url library.

For the purposes of help, a for-label require +introduces a binding without actually executing the +net/url library—for cases when you want to check +documentation, but cannot or do not want to run the providing module.

(require racket/gui) ; does not work in racket
(require (for-label racket/gui)) ; ok in racket
(help frame%)

If id has no for-label and normal binding, then help +lists all libraries that are known to export a binding for +id.

The (help id #:from module-path) variant is similar to +(help id), but using only the exports of +module-path. (The module-path module is required +for-label in a temporary namespace.)

(help frame% #:from racket/gui) ; equivalent to the above

The (help #:search datum ...) form is similar to +(help string ...), where any non-string form of +datum is converted to a string using display. No +datum is evaluated as an expression.

For example,

(help #:search "web browser" firefox)

also searches the documentation index for references that include the +phrase “web browser” or “firefox.”

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Kernel_Forms_and_Functions.html b/clones/docs.racket-lang.org/reference/Kernel_Forms_and_Functions.html new file mode 100644 index 00000000..c6284552 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Kernel_Forms_and_Functions.html @@ -0,0 +1,25 @@ + +18.8 Kernel Forms and Functions
8.6

18.8 Kernel Forms and Functions

 #lang racket/kernel package: base
The racket/kernel library +is a cross-phase persistent module that provides a minimal set of syntactic +forms and functions.

“Minimal” means that racket/kernel includes only +forms that are built into the Racket compiler and only functions that +are built into the run-time system. Currently, the set of bindings is +not especially small, nor is it particularly well-defined, since the +set of built-in functions can change frequently. Use +racket/kernel with care, and beware that its use can +create compatibility problems.

The racket/kernel module exports all of the bindings in the +grammar of fully expanded programs (see Fully Expanded Programs), +but it provides #%plain-lambda as lambda and λ, +#%plain-app as #%app, and +#%plain-module-begin as #%module-begin. Aside from +#%datum (which expands to quote), +racket/kernel provides no other syntactic bindings.

The racket/kernel module also exports many of the function +bindings from racket/base, and it exports a few other +functions that are not exported by racket/base because +racket/base exports improved variants. The exact set +of function bindings exported by racket/kernel is unspecified +and subject to change across versions.

The racket/kernel/init +library re-provides all of racket/kernel. It also +provides #%top-interaction, which makes +racket/kernel/init useful with the -I +command-line flag for racket.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Lazy_Data-structure_Contracts.html b/clones/docs.racket-lang.org/reference/Lazy_Data-structure_Contracts.html new file mode 100644 index 00000000..9012e60d --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Lazy_Data-structure_Contracts.html @@ -0,0 +1,28 @@ + +8.4 Lazy Data-structure Contracts

8.4 Lazy Data-structure Contracts

syntax

(contract-struct id (field-id ...))

NOTE: This library is deprecated; use struct, instead. Lazy struct contracts no longer require a separate +struct declaration; instead struct/dc +and struct/c work directly with +struct and define-struct.

Like struct, but with two differences: +they do not +define field mutators, and they define two contract constructors: +id/c and id/dc. The +first is a procedure that accepts as many arguments as there are +fields and returns a contract for struct values whose fields match the +arguments. The second is a syntactic form that also produces contracts +on the structs, but the contracts on later fields may depend on the +values of earlier fields.

The generated contract combinators are lazy: they only verify +the contract holds for the portion of some data structure that is +actually inspected. More precisely, a lazy data structure contract is +not checked until a selector extracts a field of a struct.

(id/dc field-spec ...)
 
field-spec = [field-id contract-expr]
  | [field-id (field-id ...) contract-expr]

In each field-spec case, the first field-id +specifies which field the contract applies to; the fields must be +specified in the same order as the original +contract-struct. The first case is for when the +contract on the field does not depend on the value of any other +field. The second case is for when the contract on the field does +depend on some other fields, and the parenthesized field-ids +indicate which fields it depends on; these dependencies can only be to +earlier fields.

syntax

(define-contract-struct id (field-id ...))

NOTE: This library is deprecated; use struct, instead. Lazy struct contracts no longer require a separate +struct declaration; instead struct/dc +and struct/c work directly with +struct and define-struct.

Like contract-struct, but where the constructor’s name is +make-id, much like define-struct.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Legacy_Contracts.html b/clones/docs.racket-lang.org/reference/Legacy_Contracts.html new file mode 100644 index 00000000..764b83ed --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Legacy_Contracts.html @@ -0,0 +1,7 @@ + +8.11 Legacy Contracts

8.11 Legacy Contracts

procedure

(make-proj-contract name proj first-order)  contract?

  name : any/c
  proj : 
(or/c (-> any/c
          any/c
          (list/c any/c any/c)
          contact?
          (-> any/c any/c))
      (-> any/c
          any/c
          (list/c any/c any/c)
          contact?
          boolean?
          (-> any/c any/c)))
  first-order : (-> any/c boolean?)
Builds a contract using an old interface.

Modulo errors, it is equivalent to: +
(make-contract
 #:name name
 #:first-order first-order
 #:projection
 (cond
   [(procedure-arity-includes? proj 5)
    (lambda (blame)
      (proj (blame-positive blame)
            (blame-negative blame)
            (list (blame-source blame) (blame-value blame))
            (blame-contract blame)
            (not (blame-swapped? blame))))]
   [(procedure-arity-includes? proj 4)
    (lambda (blame)
      (proj (blame-positive blame)
            (blame-negative blame)
            (list (blame-source blame) (blame-value blame))
            (blame-contract blame)))]))

procedure

(raise-contract-error val    
  src    
  pos    
  name    
  fmt    
  arg ...)  any/c
  val : any/c
  src : any/c
  pos : any/c
  name : any/c
  fmt : string?
  arg : any/c
Calls raise-blame-error after building a blame struct from +the val, src, pos, and name arguments. +The fmt string and following arguments are passed to +format and used as the string in the error message.

procedure

(contract-proc c)

  
(->* (symbol? symbol? (or/c syntax? (list/c any/c any/c)))
     (boolean?)
     (-> any/c any))
  c : contract?
Constructs an old-style projection from a contract.

The resulting function accepts the information that is in a blame +struct and returns a projection function that checks the contract.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Locations____variable-reference.html b/clones/docs.racket-lang.org/reference/Locations____variable-reference.html new file mode 100644 index 00000000..cd1c6ed5 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Locations____variable-reference.html @@ -0,0 +1,18 @@ + +3.6 Locations: #%variable-reference

3.6 Locations: #%variable-reference

Produces an opaque variable reference value representing the +location of id, which must be bound as a variable. If +no id is supplied, the resulting value refers to an +“anonymous” variable defined within the enclosing context (i.e., +within the enclosing module, or at the top level if the form is not +inside a module).

When (#%top . id) is used, then the variable reference refers +to the same variable as (#%top . id). Note that +(#%top . id) is not allowed if id is locally bound +or within a module if id is bound as a transformer.

A variable reference can be used with +variable-reference->empty-namespace, +variable-reference->resolved-module-path, and +variable-reference->namespace, but facilities like +define-namespace-anchor and +namespace-anchor->namespace wrap those to provide a clearer +interface. A variable reference is also useful to low-level +extensions; see Inside: Racket C API.

Changed in version 8.2.0.7 of package base: Changed #%top treatment to be +consistent with #%top by itself.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Macros.html b/clones/docs.racket-lang.org/reference/Macros.html new file mode 100644 index 00000000..fff28fda --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Macros.html @@ -0,0 +1,6 @@ + +12 Macros
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Manipulating_Paths.html b/clones/docs.racket-lang.org/reference/Manipulating_Paths.html new file mode 100644 index 00000000..21bc5657 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Manipulating_Paths.html @@ -0,0 +1,237 @@ + +15.1.1 Manipulating Paths
15.1.1 Manipulating Paths

procedure

(path? v)  boolean?

  v : any/c
Returns #t if v is a path value for the current +platform (not a string, and not a path for a different platform), +#f otherwise.

procedure

(path-string? v)  boolean?

  v : any/c
Returns #t if v is either a path +or string: either a path for the current platform or a +non-empty string without nul characters. Returns #f +otherwise.

procedure

(path-for-some-system? v)  boolean?

  v : any/c
Returns #t if v is a path value for some platform +(not a string), #f otherwise.

procedure

(string->path str)  path?

  str : string?
Produces a path whose byte-string encoding is +(string->bytes/locale str (char->integer #\?)) on Unix and Mac OS +or (string->bytes/utf-8 str) on Windows.

Beware that the current locale might not encode every string, in which +case string->path can produce the same path for different +strs. See also string->path-element, which should be +used instead of string->path when a string represents a +single path element. For information on how strings and byte +strings encode paths, see Unix Path Representation and +Windows Path Representation.

See also string->some-system-path, and see +Unix Path Representation and Windows Path Representation for information +on how strings encode paths.

Changed in version 6.1.1.1 of package base: Changed Windows conversion to always use UTF-8.

procedure

(bytes->path bstr [type])  path?

  bstr : bytes?
  type : (or/c 'unix 'windows) = (system-path-convention-type)
Produces a path (for some platform) whose byte-string encoding is +bstr, where bstr must not contain a nul byte. The +optional type specifies the convention to use for the path.

For converting relative path elements from literals, use instead +bytes->path-element, which applies a suitable encoding for +individual elements.

For information on how byte strings encode paths, see +Unix Path Representation and Windows Path Representation.

procedure

(path->string path)  string?

  path : path?
Produces a string that represents path by decoding +path’s byte-string encoding using the current locale +on Unix and Mac OS and by using UTF-8 on Windows. In the former case, +? is used in the result string where encoding fails, and if +the encoding result is the empty string, then the result is +"?".

The resulting string is suitable for displaying to a user, +string-ordering comparisons, etc., but it is not suitable for +re-creating a path (possibly modified) via string->path, +since decoding and re-encoding the path’s byte string may lose +information.

Furthermore, for display and sorting based on individual path elements +(such as pathless file names), use path-element->string, +instead, to avoid special encodings use to represent some relative +paths. See Windows Paths for specific information about +the conversion of Windows paths.

See also some-system-path->string.

Changed in version 6.1.1.1 of package base: Changed Windows conversion to always use UTF-8.

procedure

(path->bytes path)  bytes?

  path : path-for-some-system?
Produces path’s byte-string representation. No information is +lost in this translation, so that (bytes->path (path->bytes path) (path-convention-type path)) always produces a path that is +equal? to path. The path argument can be a +path for any platform.

Conversion to and from byte values is useful for marshaling and +unmarshaling paths, but manipulating the byte form of a path is +generally a mistake. In particular, the byte string may start with a +\\?\REL encoding for Windows paths. Instead of +path->bytes, use split-path and +path-element->bytes to manipulate individual path elements.

For information on how byte strings encode paths, see +Unix Path Representation and Windows Path Representation.

procedure

(string->path-element str 
  [false-on-non-element?]) 
  (or/c (and/c path? path-element?) #f)
  str : string?
  false-on-non-element? : any/c = #f
Like string->path, except that str corresponds to a +single relative element in a path, and it is encoded as necessary to +convert it to a path. See Unix and Mac OS Paths and +Windows Paths for more information on the conversion of +paths.

If str does not correspond to any path element +(e.g., it is an absolute path, or it can be split), or if it +corresponds to an up-directory or same-directory indicator on +Unix and Mac OS, then either #f is returned or exn:fail:contract exception is raised. +A #f is returned only when false-on-non-element? +is true.

Like path->string, information can be lost from +str in the locale-specific conversion to a path.

Changed in version 8.1.0.6 of package base: Added the false-on-non-element? argument.

procedure

(bytes->path-element bstr 
  [type 
  false-on-non-element?]) 
  (or/c path-element? #f)
  bstr : bytes?
  type : (or/c 'unix 'windows) = (system-path-convention-type)
  false-on-non-element? : any/c = #f
Like bytes->path, except that bstr corresponds to a +single relative element in a path. In terms of conversions, +restrictions on bstr, and the treatment of false-on-non-element?, +bytes->path-element is like string->path-element.

The bytes->path-element procedure is generally the best +choice for reconstructing a path based on another path (where the +other path is deconstructed with split-path and +path-element->bytes) when ASCII-level manipulation of +path elements is necessary.

Changed in version 8.1.0.6 of package base: Added the false-on-non-element? argument.

procedure

(path-element->string path)  string?

  path : path-element?
Like path->string, except that trailing path separators are +removed (as by split-path). On Windows, any +\\?\REL encoding prefix is also removed; see +Windows Paths for more information.

The path argument must be such that split-path +applied to path would return 'relative as its first +result and a path as its second result, otherwise the +exn:fail:contract exception is raised.

The path-element->string procedure is generally the best +choice for presenting a pathless file or directory name to a user.

procedure

(path-element->bytes path)  bytes?

  path : path-element?
Like path->bytes, except that any encoding prefix is removed, +etc., as for path-element->string.

For any reasonable locale, consecutive ASCII characters in the printed +form of path are mapped to consecutive byte values that match +each character’s code-point value, and a leading or trailing ASCII +character is mapped to a leading or trailing byte, respectively. The +path argument can be a path for any platform.

The path-element->bytes procedure is generally the right +choice (in combination with split-path) for extracting the +content of a path to manipulate it at the ASCII level (then +reassembling the result with bytes->path-element and +build-path).

procedure

(path<? a-path b-path ...)  boolean?

  a-path : path?
  b-path : path?
Returns #t if the arguments are sorted, where the comparison +for each pair of paths is the same as using +path->bytes and bytes<?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(path-convention-type path)  (or/c 'unix 'windows)

  path : path-for-some-system?
Accepts a path value (not a string) and returns its convention +type.

procedure

(system-path-convention-type)  (or/c 'unix 'windows)

Returns the path convention type of the current platform: +'unix for Unix and Mac OS, 'windows for +Windows.

procedure

(build-path base sub ...)  path-for-some-system?

  base : (or/c path-string? path-for-some-system? 'up 'same)
  sub : 
(or/c (and/c (or/c path-string? path-for-some-system?)
             (not/c complete-path?))
      (or/c 'up 'same))
Creates a path given a base path and any number of sub-path +extensions. If base is an absolute path, the result is an +absolute path, otherwise the result is a relative path.

The base and each sub must be either a relative +path, the symbol 'up (indicating the relative parent +directory), or the symbol 'same (indicating the +relative current directory). For Windows paths, if base is a +drive specification (with or without a trailing slash) the first +sub can be an absolute (driveless) path. For all platforms, +the last sub can be a filename.

The base and sub arguments can be paths for +any platform. The platform for the resulting path is inferred from the +base and sub arguments, where string arguments imply +a path for the current platform. If different arguments are for +different platforms, the exn:fail:contract exception is raised. If no argument +implies a platform (i.e., all are 'up or 'same), the +generated path is for the current platform.

Each sub and base can optionally end in a directory +separator. If the last sub ends in a separator, it is +included in the resulting path.

If base or sub is an illegal path string (because it +is empty or contains a nul character), the +exn:fail:contract exception is raised.

The build-path procedure builds a path without +checking the validity of the path or accessing the filesystem.

See Unix and Mac OS Paths and Windows Paths for more +information on the construction of paths.

The following examples assume that the current directory is +"/home/joeuser" for Unix examples and "C:\Joe’s Files" for +Windows examples.

(define p1 (build-path (current-directory) "src" "racket"))
 ; Unix: p1 is "/home/joeuser/src/racket"
 ; Windows: p1 is "C:\\Joe's Files\\src\\racket"
(define p2 (build-path 'up 'up "docs" "Racket"))
 ; Unix: p2 is "../../docs/Racket"
 ; Windows: p2 is "..\\..\\docs\\Racket"
(build-path p2 p1)
 ; Unix and Windows: raises exn:fail:contract; p1 is absolute
(build-path p1 p2)
 ; Unix: is "/home/joeuser/src/racket/../../docs/Racket"
 ; Windows: is "C:\\Joe's Files\\src\\racket\\..\\..\\docs\\Racket"

procedure

(build-path/convention-type type    
  base    
  sub ...)  path-for-some-system?
  type : (or/c 'unix 'windows)
  base : (or/c path-string? path-for-some-system? 'up 'same)
  sub : 
(or/c (and/c (or/c path-string? path-for-some-system?)
             (not/c complete-path?))
      (or/c 'up 'same))
Like build-path, except a path convention type is specified +explicitly.

Note that, just as with build-path, any string arguments for either +base or sub will be implicitly converted into a path for the +current platform before being combined with the others. For this reason, you +cannot use this function to build paths from strings for any platform other +than the current one; in such attempts, type does not match the +inferred convention type for the strings and an exn:fail:contract exception is raised. +(To create paths for foreign platforms, see bytes->path.)

The usefulness of build-path/convention-type over build-path +is limited to cases where the sub-paths contain 'same or 'up +elements.

procedure

(absolute-path? path)  boolean?

  path : (or/c path? string? path-for-some-system?)
Returns #t if path is an absolute path, #f +otherwise. The path argument can be a path for any +platform. If path is not a legal path string (e.g., it +contains a nul character), #f is returned. This procedure +does not access the filesystem.

procedure

(relative-path? path)  boolean?

  path : (or/c path? string? path-for-some-system?)
Returns #t if path is a relative path, #f +otherwise. The path argument can be a path for any +platform. If path is not a legal path string (e.g., it +contains a nul character), #f is returned. This procedure +does not access the filesystem.

procedure

(complete-path? path)  boolean?

  path : (or/c path? string? path-for-some-system?)
Returns #t if path is a completely determined path +(not relative to a directory or drive), #f +otherwise. The path argument can be a path for any +platform. Note that for Windows paths, an absolute path can omit the +drive specification, in which case the path is neither relative nor +complete. If path is not a legal path string (e.g., it +contains a nul character), #f is returned.

This procedure does not access the filesystem.

Returns path as a complete path. If path is already +a complete path, it is returned as the result. Otherwise, +path is resolved with respect to the complete path +base. If base is not a complete path, the +exn:fail:contract exception is raised.

The path and base arguments can be paths for any +platform; if they are for different +platforms, the exn:fail:contract exception is raised.

This procedure does not access the filesystem.

Returns path if path syntactically refers to a +directory and ends in a separator, otherwise it returns an extended +version of path that specifies a directory and ends with a +separator. For example, on Unix and Mac OS, the path "x/y/" +syntactically refers to a directory and ends in a separator, but +"x/y" would be extended to "x/y/", and "x/.." would be +extended to "x/../". The path argument can be a path for +any platform, and the result will be for the same platform.

This procedure does not access the filesystem.

procedure

(resolve-path path)  path?

  path : path-string?
Cleanses path and returns a path that references the +same file or directory as path. If +path is a soft link to another path, then the referenced path +is returned (this may be a relative path with respect to the directory +owning path), otherwise path is returned (after +cleansing).

On Windows, the path for a link should be simplified syntactically, so +that an up-directory indicator removes a preceding path element +independent of whether the preceding element itself refers to a +link. For relative-paths links, the path should be parsed specially; +see Windows Paths for more information.

Changed in version 6.0.1.12 of package base: Added support for links on Windows.

Cleanses path (as described at the beginning of +this chapter) without consulting the filesystem.

Example:
> (let ([p (string->some-system-path "tiny//dancer" 'unix)])
    (cleanse-path p))

#<path:tiny/dancer>

procedure

(expand-user-path path)  path?

  path : path-string?
Cleanses path. In addition, on Unix and Mac OS, a +leading ~ is treated as user’s home directory and expanded; +the username follows the ~ (before a / or the end +of the path), where ~ by itself indicates the home directory +of the current user.

procedure

(simplify-path path [use-filesystem?])  path-for-some-system?

  path : (or/c path-string? path-for-some-system?)
  use-filesystem? : boolean? = #t
Eliminates redundant path separators (except for a single trailing +separator), up-directory .., and same-directory . +indicators in path, and changes / separators to +\ separators in Windows paths, such that the result +accesses the same file or directory (if it exists) as path.

In general, the pathname is normalized as much as possible—without +consulting the filesystem if use-filesystem? is #f, +and (on Windows) without changing the case of letters within the +path. If path syntactically refers to a directory, the +result ends with a directory separator.

When path is simplified other than just converting slashes +to backslashes and use-filesystem? is true +(the default), a complete path is returned. If path is +relative, it is resolved with respect to the current directory. +On Unix and Mac OS, up-directory indicators are removed taking into account soft links (so +that the resulting path refers to the same directory as before); +on Windows, up-directory indicators are removed by deleting a +preceding path element.

When use-filesystem? is #f, up-directory indicators +are removed by deleting a preceding path element, and the result can +be a relative path with up-directory indicators remaining at the +beginning of the path; up-directory indicators are dropped when they +refer to the parent of a root directory. Similarly, the result can be +the same as (build-path 'same) (but with a trailing +separator) if eliminating up-directory indicators leaves only +same-directory indicators.

The path argument can be a path for any platform when +use-filesystem? is #f, and the resulting path is for +the same platform.

The filesystem might be accessed when use-filesystem? is +true, but the source or simplified path might be a non-existent path. If +path cannot be simplified due to a cycle of links, the +exn:fail:filesystem exception is raised (but a successfully simplified path may +still involve a cycle of links if the cycle did not inhibit the +simplification).

See Unix and Mac OS Paths and Windows Paths for more +information on simplifying paths.

Example:
> (let ([p (string->some-system-path "tiny//in/my/head/../../../dancer" 'unix)])
    (simplify-path p #f))

#<path:tiny/dancer>

Returns path with “normalized” case characters. For Unix and Mac OS +paths, this procedure always returns the input path, because +filesystems for these platforms can be case-sensitive. For Windows +paths, if path does not start with \\?\, the +resulting string uses only lowercase letters, based on the current +locale. In addition, for Windows paths when the path does not start +with \\?\, all /s are converted to +\s, and trailing spaces and .s are removed.

The path argument can be a path for any platform, but beware +that local-sensitive decoding and conversion of the path may be +different on the current platform than for the path’s platform.

This procedure does not access the filesystem.

procedure

(split-path path)  
(or/c path-for-some-system? 'relative #f)
(or/c path-for-some-system? 'up 'same)
boolean?
  path : (or/c path-string? path-for-some-system?)
Deconstructs path into a smaller path and an immediate +directory or file name. Three values are returned:

  • base is either

    • a path,

    • 'relative if path is an immediate +relative directory or filename, or

    • #f if path is a root directory.

  • name is either +
    • a directory-name path,

    • a filename,

    • 'up if the last part of path specifies the parent +directory of the preceding path (e.g., .. on Unix), or

    • 'same if the last part of path specifies the +same directory as the preceding path (e.g., . on Unix).

  • must-be-dir? is #t if path explicitly +specifies a directory (e.g., with a trailing separator), #f +otherwise. Note that must-be-dir? does not specify whether +name is actually a directory or not, but whether path +syntactically specifies a directory.

Compared to path, redundant separators (if any) are removed +in the result base and name. If base is +#f, then name cannot be 'up or +'same. The path argument can be a path for any +platform, and resulting paths for the same platform.

This procedure does not access the filesystem.

See Unix and Mac OS Paths and Windows Paths for more +information on splitting paths.

procedure

(explode-path path)

  (listof (or/c path-for-some-system? 'up 'same))
  path : (or/c path-string? path-for-some-system?)
Returns the list of path elements that constitute path. If +path is simplified in the sense of simple-form-path, +then the result is always a list of paths, and the first element of +the list is a root.

The explode-path function computes its result in time +proportional to the length of path (unlike a loop in that +uses split-path, which must allocate intermediate paths).

procedure

(path-replace-extension path ext)  path-for-some-system?

  path : (or/c path-string? path-for-some-system?)
  ext : (or/c string? bytes?)
Returns a path that is the same as path, except that the +extension for the last element of the path (including the extension +separator) is changed to ext. If the last element of +path has no extension, then ext is added to the +path.

An extension is defined as a . that is not at the start of +the path element followed by any number of non-. +characters/bytes at the end of the path element, as long as the +path element is not a directory indicator like "..".

The path argument can be a path for any platform, and the +result is for the same platform. If path represents a root, +the exn:fail:contract exception is raised. The given ext typically +starts with ., but it is not required to start with an +extension separator.

Examples:
> (path-replace-extension "x/y.ss" #".rkt")

#<path:x/y.rkt>

> (path-replace-extension "x/y.ss" #"")

#<path:x/y>

> (path-replace-extension "x/y" #".rkt")

#<path:x/y.rkt>

> (path-replace-extension "x/y.tar.gz" #".rkt")

#<path:x/y.tar.rkt>

> (path-replace-extension "x/.racketrc" #".rkt")

#<path:x/.racketrc.rkt>

Added in version 6.5.0.3 of package base.

procedure

(path-add-extension path ext [sep])  path-for-some-system?

  path : (or/c path-string? path-for-some-system?)
  ext : (or/c string? bytes?)
  sep : (or/c string? bytes?) = #"_"
Similar to path-replace-extension, but any existing extension on +path is preserved by replacing the . before the extension +with sep, and then the ext is added +to the end.

Examples:
> (path-add-extension "x/y.ss" #".rkt")

#<path:x/y_ss.rkt>

> (path-add-extension "x/y" #".rkt")

#<path:x/y.rkt>

> (path-add-extension "x/y.tar.gz" #".rkt")

#<path:x/y.tar_gz.rkt>

> (path-add-extension "x/y.tar.gz" #".rkt" #".")

#<path:x/y.tar.gz.rkt>

> (path-add-extension "x/.racketrc" #".rkt")

#<path:x/.racketrc.rkt>

Added in version 6.5.0.3 of package base.
Changed in version 6.8.0.2: Added the sep optional argument.

procedure

(path-replace-suffix path ext)  path-for-some-system?

  path : (or/c path-string? path-for-some-system?)
  ext : (or/c string? bytes?)

NOTE: This function is deprecated; use path-replace-extension, instead.

Like path-replace-extension, but treats a leading . +in a path element as an extension separator.

procedure

(path-add-suffix path ext)  path-for-some-system?

  path : (or/c path-string? path-for-some-system?)
  ext : (or/c string? bytes?)

NOTE: This function is deprecated; use path-add-extension, instead.

Like path-add-extension, but treats a leading . +in a path element as an extension separator.

procedure

(reroot-path path root-path)  path-for-some-system?

  path : (or/c path-string? path-for-some-system?)
  root-path : (or/c path-string? path-for-some-system?)
Produces a path that extends root-path based on the complete +form of path.

If path is not already complete, is it completed via +path->complete-path, in which case path must be a +path for the current platform. The path argument is also +cleansed and case-normalized via normal-case-path. The +path is then appended to root-path; in the case of Windows +paths, a root letter drive becomes a letter path element, while a root +UNC path is prefixed with "UNC" as a path element and the +machine and volume names become path elements.

Examples:
> (reroot-path (bytes->path #"/home/caprica/baltar" 'unix)
               (bytes->path #"/earth" 'unix))

#<path:/earth/home/caprica/baltar>

> (reroot-path (bytes->path #"c:\\usr\\adama" 'windows)
               (bytes->path #"\\\\earth\\africa\\" 'windows))

#<windows-path:\\earth\africa\c\usr\adama>

> (reroot-path (bytes->path #"\\\\galactica\\cac\\adama" 'windows)
               (bytes->path #"s:\\earth\\africa\\" 'windows))

#<windows-path:s:\earth\africa\UNC\galactica\cac\adama>

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Module_Names_and_Loading.html b/clones/docs.racket-lang.org/reference/Module_Names_and_Loading.html new file mode 100644 index 00000000..5aae0174 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Module_Names_and_Loading.html @@ -0,0 +1,320 @@ + +14.4 Module Names and Loading

14.4 Module Names and Loading

14.4.1 Resolving Module Names

The syntax/modresolve library provides additional +operations for resolving and manipulating module names.

The name of a declared module is represented by a resolved +module path, which encapsulates either a symbol or a complete +filesystem path (see Paths). A symbol normally refers +to a predefined module or module declared through reflective +evaluation (e.g., eval). A filesystem path normally refers to +a module declaration that was loaded on demand via require or +other forms.

A module path is a datum that matches the grammar for +module-path for require. A module path is relative +to another module.

procedure

(resolved-module-path? v)  boolean?

  v : any/c
Returns #t if v is a resolved module path, +#f otherwise.

procedure

(make-resolved-module-path path)  resolved-module-path?

  path : 
(or/c symbol?
      (and/c path? complete-path?)
      (cons/c (or/c symbol?
                    (and/c path? complete-path?))
              (non-empty-listof symbol?)))
Returns a resolved module path that encapsulates path, +where a list path corresponds to a submodule path. +If path is a path or starts with a path, the path normally should be +cleansed (see cleanse-path) and simplified (see +simplify-path, including consulting the file system).

A resolved module path is interned. That is, if two +resolved module path values encapsulate paths that are +equal?, then the resolved module path values are +eq?.

procedure

(resolved-module-path-name module-path)

  
(or/c symbol?
      (and/c path? complete-path?)
      (cons/c (or/c symbol?
                    (and/c path? complete-path?))
              (non-empty-listof symbol?)))
  module-path : resolved-module-path?
Returns the path or symbol encapsulated by a resolved module path. +A list result corresponds to a submodule path.

procedure

(module-path? v)  boolean?

  v : any/c
Returns #t if v corresponds to a datum that matches +the grammar for module-path for require, +#f otherwise. Note that a path (in the sense of +path?) is a module path.

A parameter that determines the current module name +resolver, which manages the conversion from other kinds of module +references to a resolved module path. For example, +when the expander encounters (require module-path) where +module-path is not an identifier, then the expander passes +'module-path to the module name resolver to obtain a symbol +or resolved module path. When such a require appears within a +module, the module path resolver is also given the name of +the enclosing module, so that a relative reference can be converted to +an absolute symbol or resolved module path.

The default module name resolver uses +collection-file-path to convert lib and +symbolic-shorthand module paths to filesystem paths. The +collection-file-path function, in turn, uses the +current-library-collection-links +and current-library-collection-paths parameters.

A module name resolver takes two and four arguments: +
  • When given two arguments, the first is a name for a module that +is now declared in the current namespace, and the second is optionally +a namespace from which the declaration was copied. +The module name resolver’s result in this case is ignored.

    The current module name resolver is called with two arguments by +namespace-attach-module or +namespace-attach-module-declaration to notify the resolver +that a module declaration was attached to the current namespace (and +should not be loaded in the future for the namespace’s module registry). +Evaluation of a module declaration also calls the current module +name resolver with two arguments, where the first is the declared +module and the second is #f. No other Racket operation +invokes the module name resolver with two arguments, but other tools +(such as DrRacket) might call this resolver in this mode to avoid +redundant module loads.

  • When given four arguments, the first is a module path, +equivalent to a quoted module-path for require. +The second is name for the source module, if +any, to which the path is relative; if the second argument is +#f, the module path is relative to (or (current-load-relative-directory) (current-directory)). The third +argument is a syntax object that can be used for error +reporting, if it is not #f. If the last argument is +#t, then the module declaration should be loaded (if it is +not already), otherwise the module path should be simply resolved to +a name. The result is the resolved name.

For the second case, the standard module name resolver keeps a +table per module registry containing loaded module name. If a resolved module path is +not in the table, and #f is not provided as the fourth +argument to the module name resolver, then the name is put into +the table and the corresponding file is loaded with a variant of +load/use-compiled that passes the expected module name to the +compiled-load handler.

While loading a file, the default module name resolver sets the +current-module-declare-name parameter to the resolved module +name (while the compiled-load handler sets +current-module-declare-source). Also, the default +module name resolver records in a private continuation +mark the module being loaded, and it checks whether such a mark +already exists; if such a continuation mark does exist in the current +continuation, then the exn:fail exception is raised with a message about a +dependency cycle.

The default module name resolver cooperates with the default +compiled-load handler: on a module-attach notification, +bytecode-file information recorded by the compiled-load handler +for the source namespace’s module registry is transferred to +the target namespace’s module registry.

The default module name resolver also maintains a small, +module registry-specific cache that maps lib and symbolic +module paths to their resolutions. This cache is consulted before +checking parameters such as current-library-collection-links +and current-library-collection-paths, so results may +“stick” even if those parameter values change. An entry is added to +the cache only when the fourth argument to the module name resolver is +true (indicating that a module should be loaded) and only when loading +succeeds.

Finally, the default module name resolver potentially treats a +submod path specially. If the module path as the first +element of the submod form refers to non-existent collection, +then instead of raising an exception, the default module name resolver +synthesizes an uninterned symbol module name for the resulting +resolved module path. This special treatment of submodule paths +is consistent with the special treatment of nonexistent submodules by +the compiled-load handler, so that module-declared? +can be used more readily to check for the existence of a submodule.

Module loading is suppressed (i.e., #f is supplied as a fourth +argument to the module name resolver) when resolving module paths in +syntax objects (see Syntax Objects). When a +syntax object is manipulated, the current namespace might not +match the original namespace for the syntax object, and the module +should not necessarily be loaded in the current namespace.

For historical reasons, the default module name resolver currently +accepts three arguments, in addition to two and four. Three arguments +are treated the same as four arguments with the fourth argument as +#t, except that an error is also logged. Support for three +arguments will be removed in a future version.

The current-module-name-resolver binding is provided as +protected in the sense of protect-out.

Changed in version 6.0.1.12 of package base: Added error logging to the default module name resolver +when called with three arguments.
Changed in version 7.0.0.17: Added special treatment of submod forms with a +nonexistent collection by the default module name +resolver.
Changed in version 8.2.0.4: Changed binding to protected.

A parameter that determines a module name that is used when evaluating +a module declaration (when the parameter value is not +#f). In that case, the id from the module +declaration is ignored, and the parameter’s value is used as the name +of the declared module.

When declaring submodules, current-module-declare-name +determines the name used for the submodule’s root module, while its +submodule path relative to the root module is unaffected.

A parameter that determines source information to be associated with a +module when evaluating a module declaration. Source +information is used in error messages and reflected by +variable-reference->module-source. When the parameter value +is #f, the module’s name (as determined by +current-module-declare-name) is used as the source name +instead of the parameter value.

parameter

(current-module-path-for-load)

  
(or/c #f module-path?
      (and/c syntax?
             (lambda (stx)
               (module-path? (syntax->datum s)))))
(current-module-path-for-load path)  void?
  path : 
(or/c #f module-path?
      (and/c syntax?
             (lambda (stx)
               (module-path? (syntax->datum s)))))
A parameter that determines a module path used for +exn:fail:syntax:missing-module and +exn:fail:filesystem:missing-module exceptions as raised by the +default load handler. The parameter is normally set by a +module name resolver.

14.4.2 Compiled Modules and References

While expanding a module declaration, the expander resolves +module paths for imports to load module declarations as necessary and +to determine imported bindings, but the compiled form of a +module declaration preserves the original module path. +Consequently, a compiled module can be moved to another filesystem, +where the module name resolver can resolve inter-module references +among compiled code.

When a module reference is extracted from compiled form (see +module-compiled-imports) or from syntax objects in macro +expansion (see Syntax Object Content), the module reference is reported in +the form of a module path index. A module path index +is a semi-interned (multiple references to the same relative module +tend to use the same module path index value, but not always) +opaque value that encodes a module path (see module-path?) +and either a resolved module path or another module path +index to which it is relative.

A module path index that uses both #f for its path and +base module path index represents “self”—i.e., the module +declaration that was the source of the module path indexand +such a module path index can be used as the root for a chain of +module path indexes at compile time. For example, when +extracting information about an identifier’s binding within a module, +if the identifier is bound by a definition within the same module, the +identifier’s source module is reported using the “self” module +path index. If the identifier is instead defined in a module that is +imported via a module path (as opposed to a literal module name), then +the identifier’s source module will be reported using a module +path index that contains the required module path and the +“self” module path index. A “self” module path index +has a submodule path when the module that it refers to is a +submodule.

A module path index has state. When it is resolved to +a resolved module path, then the resolved module path is +stored with the module path index. In particular, when a module +is loaded, its root module path index is resolved to match the +module’s declaration-time name. This resolved path is forgotten, +however, in identifiers that the module contributes to the compiled +and marshaled form of other modules. The transient nature of resolved +names allows the module code to be loaded with a different resolved +name than the name when it was compiled.

Two module path index values are equal? when they have +equal? path and base values (even if they have different +resolved values).

procedure

(module-path-index? v)  boolean?

  v : any/c
Returns #t if v is a module path index, +#f otherwise.

procedure

(module-path-index-resolve mpi    
  [load?    
  src-stx])  resolved-module-path?
  mpi : module-path-index?
  load? : any/c = #f
  src-stx : (or/c syntax? #f) = #f
Returns a resolved module path for the resolved module name, +computing the resolved name (and storing it in mpi) if it has +not been computed before.

Resolving a module path index uses the current module +name resolver (see current-module-name-resolver). Depending +on the kind of module paths encapsulated by mpi, the computed +resolved name can depend on the value of +current-load-relative-directory or +current-directory. The load? argument is propagated as +the last argument to the module name resolver, while the +src-stx argument is propagated as the next-to-last argument.

Beware that concurrent resolution in namespaces that share a module +registry can create race conditions when loading modules. See also +namespace-call-with-registry-lock.

See also resolve-module-path-index.

Changed in version 6.90.0.16 of package base: Added the load? optional argument.
Changed in version 8.2: Added the src-stx optional argument.

Returns two values: a module path, and a base path—either a +module path index, resolved module path, or +#fto which the first path is relative.

A #f second result means that the path is relative to an +unspecified directory (i.e., its resolution depends on the value of +current-load-relative-directory and/or +current-directory).

A #f for the first result implies a #f for the +second result, and means that mpi represents “self” (see +above). Such a module path index may have a non-#f +submodule path as reported by module-path-index-submodule.

Returns a non-empty list of symbols if mpi is a “self” (see +above) module path index that refers to a submodule. The +result is always #f if either result of +(module-path-index-split mpi) is non-#f.

procedure

(module-path-index-join path base [submod])  module-path-index?

  path : (or/c module-path? #f)
  base : (or/c module-path-index? resolved-module-path? #f)
  submod : (or/c #f (non-empty-listof symbol?)) = #f
Combines path, base, and submod to create a +new module path index. The path argument can be +#f only if base is also #f. The +submod argument can be a list only when path and +base are both #f.

procedure

(compiled-module-expression? v)  boolean?

  v : any/c
Returns #t if v is a compiled module +declaration, #f otherwise. See also +current-compile.

procedure

(module-compiled-name compiled-module-code)

  (or/c symbol? (cons/c symbol? (non-empty-listof symbol?)))
  compiled-module-code : compiled-module-expression?
(module-compiled-name compiled-module-code 
  name) 
  compiled-module-expression?
  compiled-module-code : compiled-module-expression?
  name : (or/c symbol? (cons/c symbol? (non-empty-listof symbol?)))
Takes a module declaration in compiled form and either gets the +module’s declared name (when name is not provided) or returns +a revised module declaration with the given name.

The name is a symbol for a top-level module, or a symbol paired with a list of symbols +where the list reflects the submodule path to +the module starting with the top-level module’s declared name.

procedure

(module-compiled-submodules compiled-module-code 
  non-star?) 
  (listof compiled-module-expression?)
  compiled-module-code : compiled-module-expression?
  non-star? : any/c
(module-compiled-submodules compiled-module-code 
  non-star? 
  submodules) 
  compiled-module-expression?
  compiled-module-code : compiled-module-expression?
  non-star? : any/c
  submodules : (listof compiled-module-expression?)
Takes a module declaration in compiled form and either gets the +module’s submodules (when submodules is not provided) or +returns a revised module declaration with the given +submodules. The non-star? argument determines +whether the result or new submodule list corresponds to +module declarations (when non-star? is true) +or module* declarations (when non-star? is #f).

procedure

(module-compiled-imports compiled-module-code)

  
(listof (cons/c (or/c exact-integer? #f)
                (listof module-path-index?)))
  compiled-module-code : compiled-module-expression?
Takes a module declaration in compiled form and returns an association +list mapping phase level shifts (where #f corresponds +to a shift into the label phase level) to module references for +the module’s explicit imports.

procedure

(module-compiled-exports compiled-module-code 
  [verbosity]) 
  
(listof (cons/c phase+space? list?))
(listof (cons/c phase+space? list?))
  compiled-module-code : compiled-module-expression?
  verbosity : (or/c #f 'defined-names) = #f
Returns two association lists mapping from a combination of phase level +and binding space to exports at +the corresponding phase and space. The first association list is for exported +variables, and the second is for exported syntax. Beware however, that +value bindings re-exported though a rename transformer are in +the syntax list instead of the value list. See phase+space? +for information on the phase-and-space representation.

Each associated list, which is represented by list? in the +result contracts above, more precisely matches the contract

(listof (list/c symbol?
                (listof
                 (or/c module-path-index?
                       (list/c module-path-index?
                               phase+space?
                               symbol?
                               phase+space?)))
                ; only if verbosity is 'defined-names:
                symbol?))

For each element of the list, the leading symbol is the name of the +export.

The second part—the list of module path index values, +etc.—describes the origin of the exported identifier. If the origin +list is null, then the exported identifier is defined in the +module. If the exported identifier is re-exported, instead, then the +origin list provides information on the import that was re-exported. +The origin list has more than one element if the binding was imported +multiple times from (possibly) different sources.

The last part, a symbol, is included only if verbosity is +'defined-names. In that case, the included symbol is the name +of the definition within its defining module (which may be different +than the name that is exported).

For each origin, a module path index by itself means that the +binding was imported with a phase level shift of 0 +(i.e., a plain require without for-meta, +for-syntax, etc.) into the default binding space (i.e., +without for-space), and the imported identifier has the same name +as the re-exported name. An origin represented with a list indicates +explicitly the import, the phase level plus binding space +where the imported identifier is bound (see phase+space? for more +information on the representation), the symbolic name of the import +as bound in the importing module, and the phase level plus +binding space of the identifier from the exporting module.

Example:
> (module-compiled-exports
   (compile
    '(module banana racket/base
       (require (only-in racket/math pi)
                (for-syntax racket/base))
       (provide pi
                (rename-out [peel wrapper])
                bush
                cond
                (for-syntax compile-time))
       (define peel pi)
       (define bush (* 2 pi))
       (begin-for-syntax
         (define compile-time (current-seconds)))))
   'defined-names)

'((0

   (bush () bush)

   (pi (#<module-path-index:racket/math>) pi)

   (wrapper () peel))

  (1 (compile-time () compile-time)))

'((0 (cond (#<module-path-index:racket/base>) cond)))

Changed in version 7.5.0.6 of package base: Added the verbosity argument.
Changed in version 8.2.0.3: Generalized results to phase–space combinations.

procedure

(module-compiled-indirect-exports compiled-module-code)

  (listof (cons/c exact-integer? (listof symbol?)))
  compiled-module-code : compiled-module-expression?
Returns an association list mapping phase level values to +symbols that represent variables within the module. These definitions +are not directly accessible from source, but they are accessible from +bytecode, and the order of the symbols in each list corresponds to an +order for bytecode access.

Added in version 6.5.0.5 of package base.

procedure

(module-compiled-language-info compiled-module-code)

  (or/c #f (vector/c module-path? symbol? any/c))
  compiled-module-code : compiled-module-expression?

Returns information intended to reflect the “language” of the +module’s implementation as originally attached to the syntax of the +module’s declaration though the 'module-language +syntax property. See also module.

If no information is available for the module, the result is +#f. Otherwise, the result is (vector mp name val) +such that ((dynamic-require mp name) val) should return +function that takes two arguments. The function’s arguments are a key +for reflected information and a default value. Acceptable keys and +the interpretation of results is up to external tools, such as +DrRacket. If no information is available for a given key, the result +should be the given default value.

See also module->language-info and +racket/language-info.

procedure

(module-compiled-cross-phase-persistent? compiled-module-code)

  boolean?
  compiled-module-code : compiled-module-expression?
Returns #t if compiled-module-code represents a +cross-phase persistent module, #f otherwise.

procedure

(module-compiled-realm compiled-module-code)  symbol?

  compiled-module-code : compiled-module-expression?
Returns the realm of the module represented by +compiled-module-code.

Added in version 8.4.0.2 of package base.

14.4.3 Dynamic Module Access

procedure

(dynamic-require mod provided [fail-thunk])  (or/c void? any/c)

  mod : 
(or/c module-path?
      resolved-module-path?
      module-path-index?)
  provided : (or/c symbol? #f 0 void?)
  fail-thunk : (-> any) = (lambda () ....)

Because dynamic-require is a procedure, giving a plain S-expression for +mod the same way as you would for a require expression likely won’t give you +expected results. What you need instead is something that evaluates to an S-expression; using +quote is one way to do it.

Dynamically instantiates the module specified by mod +in the current namespace’s registry at the namespace’s base +phase, if it is not yet instantiated. The current module +name resolver may load a module declaration to resolve mod +(see current-module-name-resolver); the path is resolved +relative to current-load-relative-directory and/or +current-directory. Beware that concurrent dynamic-requires +in namespaces that share a module registry can create race +conditions; see also namespace-call-with-registry-lock.

If provided is #f, then the result is #<void>, +and the module is not visited (see Module Expansion, Phases, and Visits) or +even made available (for on-demand visits) in phases +above the base phase.

Examples:
> (module a racket/base (displayln "hello"))
> (dynamic-require ''a #f)

hello

The double quoted ''a evaluates to the root-module-path 'a +(see the grammar for require). Using 'a for mod won’t work, +because that evaluates to root-module-path a, and the example is +not a module installed in a collection. Using a won’t work, because a +is an undefined variable.

Declaring (module a ....) within another module, instead of in +the read-eval-print loop, would create a submodule. In that case, +(dynamic-require ''a #f) would not access the module, because ''a +does not refer to a submodule.

When provided is a symbol, the value of the module’s export +with the given name is returned, and still the module is not +visited or made available in higher phases.

Examples:
> (module b racket/base
    (provide dessert)
    (define dessert "gulab jamun"))
> (dynamic-require ''b 'dessert)

"gulab jamun"

If the module exports provided as syntax, then a use of the binding +is expanded and evaluated in a fresh namespace to which the module is +attached, which means that the module is visited in the fresh +namespace. The expanded syntax must return a single value.

Examples:
> (module c racket/base
    (require (for-syntax racket/base))
    (provide dessert2)
    (define dessert "nanaimo bar")
    (define-syntax dessert2
      (make-rename-transformer #'dessert)))
> (dynamic-require ''c 'dessert2)

"nanaimo bar"

If the module has no such exported variable or syntax, then +fail-thunk is called; the default fail-thunk raises +exn:fail:contract. If the variable named by provided +is exported protected (see Code Inspectors), then the +exn:fail:contract exception is raised.

If provided is 0, then the module is +instantiated but not visited, the same as when +provided is #f. With 0, however, the module +is made available in higher phases.

If provided is #<void>, then the module is +visited but not instantiated (see Module Expansion, Phases, and Visits), +and the result is #<void>.

More examples using different module-path grammar expressions are given below:

Example:
> (dynamic-require 'racket/base #f)

Example:
> (dynamic-require (list 'lib "racket/base") #f)

Examples:
> (module a racket/base
    (module b racket/base
      (provide inner-dessert)
      (define inner-dessert "tiramisu")))
> (dynamic-require '(submod 'a b) 'inner-dessert)

"tiramisu"

The last line in the above example could instead have been written as

Example:
> (dynamic-require ((lambda () (list 'submod ''a 'b))) 'inner-dessert)

"tiramisu"

which is equivalent.

procedure

(dynamic-require-for-syntax mod    
  provided    
  [fail-thunk])  any
  mod : module-path?
  provided : (or/c symbol? #f)
  fail-thunk : (-> any) = (lambda () ....)
Like dynamic-require, but in a phase that is 1 +more than the namespace’s base phase.

procedure

(module-declared? mod [load?])  boolean?

  mod : 
(or/c module-path? module-path-index?
      resolved-module-path?)
  load? : any/c = #f
Returns #t if the module indicated by mod is +declared (but not necessarily instantiated or visited) +in the current namespace, #f otherwise.

If load? is #t and mod is not a +resolved module path, the module is loaded in the process of +resolving mod (as for dynamic-require and other +functions). Checking for the declaration of a submodule does +not trigger an exception if the submodule cannot be loaded because +it does not exist, either within a root module that does exist or +because the root module does not exist.

procedure

(module->language-info mod [load?])

  (or/c #f (vector/c module-path? symbol? any/c))
  mod : 
(or/c module-path? module-path-index?
      resolved-module-path?)
  load? : any/c = #f
Returns information intended to reflect the “language” of the +implementation of mod. If mod is a +resolved module path or load? is #f, the +module named by mod must be declared (but not necessarily +instantiated or visited) in the current namespace; +otherwise, mod may be loaded (as for dynamic-require +and other functions). The information returned by +module->language-info is the same as would have been returned +by module-compiled-language-info applied to the module’s +implementation as compiled code.

A module can be declared by using dynamic-require.

Examples:
> (dynamic-require 'racket/dict (void))
> (module->language-info 'racket/dict)

#f

procedure

(module->imports mod)

  
(listof (cons/c (or/c exact-integer? #f)
                (listof module-path-index?)))
  mod : 
(or/c module-path? module-path-index?
      resolved-module-path?)
Like module-compiled-imports, but produces the + imports of mod, which must be declared (but + not necessarily instantiated or visited) in + the current namespace. See module->language-info for + an example of declaring an existing module.

Examples:
> (module banana racket/base
    (require (only-in racket/math pi))
    (provide peel)
    (define peel pi)
    (define bush (* 2 pi)))
> (module->imports ''banana)

'((0 #<module-path-index:racket/base> #<module-path-index:racket/math>))

procedure

(module->exports mod [verbosity])

  
(listof (cons/c phase+space? list?))
(listof (cons/c phase+space? list?))
  mod : 
(or/c module-path? module-path-index?
      resolved-module-path?)
  verbosity : (or/c #f 'defined-names) = #f
Like module-compiled-exports, but produces the + exports of mod, which must be declared (but + not necessarily instantiated or visited) in + the current namespace. See module->language-info for + an example of declaring an existing module.

Examples:
> (module banana racket/base
    (require (only-in racket/math pi))
    (provide (rename-out [peel wrapper]))
    (define peel pi)
    (define bush (* 2 pi)))
> (module->exports ''banana)

'((0 (wrapper ())))

'()

Changed in version 7.5.0.6 of package base: Added the verbosity argument.
Changed in version 8.2.0.3: Generalized results to phase–space combinations.

Like module-compiled-indirect-exports, but produces the + exports of mod, which must be declared (but + not necessarily instantiated or visited) in + the current namespace. See module->language-info for + an example of declaring an existing module.

Examples:
> (module banana racket/base
    (require (only-in racket/math pi))
    (provide peel)
    (define peel pi)
    (define bush (* 2 pi)))
> (module->indirect-exports ''banana)

'((0 bush))

Added in version 6.5.0.5 of package base.

procedure

(module->realm mod)  symbol?

  mod : 
(or/c module-path? module-path-index?
      resolved-module-path?)
Like module-compiled-realm, but produces the + exports of mod, which must be declared (but + not necessarily instantiated or visited) in + the current namespace.

Added in version 8.4.0.2 of package base.

Reports whether mod refers to a module that is predefined for +the running Racket instance. Predefined modules always have a symbolic +resolved module path, and they may be predefined always or +specifically within a particular executable (such as one created by +raco exe or create-embedding-executable).

14.4.4 Module Cache

The expander keeps a place-local module cache in order to save time +while loading modules that have been previously declared.

procedure

(module-cache-clear!)  void?

Clears the place-local module cache.

Added in version 8.4.0.5 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/More_Path_Utilities.html b/clones/docs.racket-lang.org/reference/More_Path_Utilities.html new file mode 100644 index 00000000..615f07f9 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/More_Path_Utilities.html @@ -0,0 +1,65 @@ + +15.1.2 More Path Utilities
15.1.2 More Path Utilities

 (require racket/path) package: base
The bindings documented in this section are provided by the racket/path and racket libraries, but not racket/base.

Returns the last element of path. If path is +syntactically a directory path (see split-path), then the +result is #f.

procedure

(path-get-extension path)  (or/c bytes? #f)

  path : (or/c path-string? path-for-some-system?)
Returns a byte string that is the extension part of the filename in +path, including the . separator. If the path has no +extension, #f is returned.

See path-replace-extension for the definition of a filename +extension.

Examples:
> (path-get-extension "x/y.rkt")

#".rkt"

> (path-get-extension "x/y")

#f

> (path-get-extension "x/y.tar.gz")

#".gz"

> (path-get-extension "x/.racketrc")

#f

Added in version 6.5.0.3 of package base.

procedure

(path-has-extension? path ext)  (or/c bytes? #f)

  path : (or/c path-string? path-for-some-system?)
  ext : (or/c bytes? string?)
Determines whether the last element of path ends with +ext but is not exactly the same as ext.

If ext is a byte string with the shape of an extension +(i.e., starting with . and not including another .), this check is equivalent to +checking whether (path-get-extension path) produces ext.

Examples:
> (path-has-extension? "x/y.rkt" #".rkt")

#t

> (path-has-extension? "x/y.ss" #".rkt")

#f

> (path-has-extension? "x/y" #".rkt")

#f

> (path-has-extension? "x/.racketrc" #".racketrc")

#f

> (path-has-extension? "x/compiled/y_rkt.zo" #"_rkt.zo")

#t

Added in version 6.5.0.3 of package base.

procedure

(filename-extension path)  (or/c bytes? #f)

  path : (or/c path-string? path-for-some-system?)

NOTE: This function is deprecated; use path-get-extension, instead.

Returns a byte string that is the extension part of the filename in +path without the . separator. If path is +syntactically a directory (see split-path) or if the path has +no extension, #f is returned.

procedure

(find-relative-path base 
  path 
  [#:more-than-root? more-than-root? 
  #:more-than-same? more-than-same? 
  #:normalize-case? normalize-case?]) 
  (or/c path-for-some-system? path-string?)
  base : (or/c path-string? path-for-some-system?)
  path : (or/c path-string?  path-for-some-system?)
  more-than-root? : any/c = #f
  more-than-same? : any/c = #t
  normalize-case? : any/c = #t
Finds a relative pathname with respect to base that names the +same file or directory as path. Both base and +path must be simplified in the sense of +simple-form-path. If path shares no subpath in +common with base, path is returned.

If more-than-root? is true, if base and +path share only a Unix root in common, and if neither +base nor path is just a root path, then +path is returned.

If path is the same as base, then +(build-path 'same) is returned only if +more-than-same? is true. Otherwise, path is +returned when path is the same as base.

If normalize-case? is true (the default), then pairs of path +elements to be compared are first converted via +normal-case-path, which means that path elements are +compared case-insentively on Windows. If normalize-case? is +#f, then path elements and the path roots match only if they +have the same case.

The result is normally a path in the sense of path?. +The result is a string only if path is provided a string and +also returned as the result.

Changed in version 6.8.0.3 of package base: Made path elements case-normalized +for comparison by default, and +added the #:normalize-case? +argument.
Changed in version 6.90.0.21: Added the #:more-than-same? +argument.

procedure

(normalize-path path [wrt])  path?

  path : path-string?
  wrt : (and/c path-string? complete-path?)
   = (current-directory)

For most purposes, simple-form-path is the +preferred mechanism to normalize a path, because it works for paths +that include non-existent directory components, and it avoids +unnecessarily expanding soft links.

Returns a complete version of path by making the path +complete, expanding the complete path, and resolving all soft links +(which requires consulting the filesystem). If path is +relative, then wrt is used as the base path.

Letter case is not normalized by normalize-path. For +this and other reasons, such as whether the path is syntactically a +directory, the result of normalize-path is not suitable for +comparisons that determine whether two paths refer to the same file or +directory (i.e., the comparison may produce false negatives).

An error is signaled by normalize-path if the input +path contains an embedded path for a non-existent directory, +or if an infinite cycle of soft links is detected.

Example:

procedure

(path-element? path)  boolean?

  path : any/c
Returns #t if path is a path element: +a path value for some platform (see path-for-some-system?) such that +split-path applied to path would return +'relative as its first result and a path as its second +result. Otherwise, the result is #f.

procedure

(path-only path)  (or/c #f path-for-some-system?)

  path : (or/c path-string? path-for-some-system?)
Returns path without its final path element in the case that +path is not syntactically a directory; if path has only +a single, non-directory path element, #f is returned. If +path is syntactically a directory, then path is +returned unchanged (but as a path, if it was a string).

Examples:
> (path-only (build-path "a" "b"))

#<path:a/>

> (path-only (build-path "a"))

#f

> (path-only (path->directory-path (build-path "a")))

#<path:a/>

> (path-only (build-path 'up 'up))

#<path:../..>

procedure

(simple-form-path path)  path?

  path : path-string?
Returns (simplify-path (path->complete-path path)), which +ensures that the result is a complete path containing no up- or +same-directory indicators.

procedure

(some-system-path->string path)  string?

  path : path-for-some-system?
Converts path to a string using a UTF-8 encoding of the +path’s bytes.

Use this function when working with paths for a different system +(whose encoding of pathnames might be unrelated to the current +locale’s encoding) and when starting and ending with strings.

procedure

(string->some-system-path str kind)  path-for-some-system?

  str : string?
  kind : (or/c 'unix 'windows)
Converts str to a kind path using a UTF-8 encoding +of the path’s bytes.

Use this function when working with paths for a different system +(whose encoding of pathnames might be unrelated to the current +locale’s encoding) and when starting and ending with strings.

procedure

(shrink-path-wrt pth other-pths)  (or/c #f path?)

  pth : path?
  other-pths : (listof path?)
Returns a suffix of pth that shares nothing +in common with the suffixes of other-pths, or +pth, if not possible (e.g. when other-pths +is empty or contains only paths with the same elements as pth).

Examples:
> (shrink-path-wrt (build-path "racket" "list.rkt")
                   (list (build-path "racket" "list.rkt")
                         (build-path "racket" "base.rkt")))

#<path:list.rkt>

> (shrink-path-wrt (build-path "racket" "list.rkt")
                   (list (build-path "racket" "list.rkt")
                         (build-path "racket" "private" "list.rkt")
                         (build-path "racket" "base.rkt")))

#<path:racket/list.rkt>

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Namespaces.html b/clones/docs.racket-lang.org/reference/Namespaces.html new file mode 100644 index 00000000..73779558 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Namespaces.html @@ -0,0 +1,207 @@ + +14.1 Namespaces

14.1 Namespaces

See Namespaces for basic information on the +namespace model.

A new namespace is created with procedures like +make-empty-namespace, and make-base-namespace, which +return a first-class namespace value. A namespace is used by setting +the current-namespace parameter value, or by providing the +namespace to procedures such as eval and +eval-syntax.

procedure

(namespace? v)  boolean?

  v : any/c
Returns #t if v is a namespace value, #f +otherwise.

Creates a new namespace that is empty, and whose module +registry contains only mappings for some internal, predefined modules, +such as '#%kernel. The namespace’s base phase is +the same as the base phase of the current +namespace. Attach modules from an existing namespace to the new one +with namespace-attach-module.

The new namespace is associated with a new root namespace, +which has the same module registry as the returned namespace +and has a base phase of 0. The new root namespace is +the same as the returned namespace if both have base phase 0.

Creates a new empty namespace like make-empty-namespace, +but with racket/base +attached. The namespace’s base phase is the same as the +phase in which the make-base-empty-namespace +function was created.

Creates a new namespace like make-empty-namespace, but +with racket/base attached and +required into the top-level environment. The namespace’s +base phase is the same as the phase in which the +make-base-namespace function was created.

Binds id to a namespace anchor that can be used with +namespace-anchor->empty-namespace and +namespace-anchor->namespace.

This form can be used only in a top-level context or in a +module-context.

procedure

(namespace-anchor? v)  boolean?

  v : any/c
Returns #t if v is a namespace-anchor value, +#f otherwise.

Returns an empty namespace that shares a module registry +and root namespace with +the source of the anchor, and whose base phase is the +phase in which the anchor was created.

If the anchor is from a define-namespace-anchor form in a +module context, then the source is the namespace in which the +containing module is instantiated. If the anchor is from a +define-namespace-anchor form in a top-level content, then the +source is the namespace in which the anchor definition was evaluated.

Returns a namespace corresponding to the source of the anchor.

If the anchor is from a define-namespace-anchor form in a +module context, then the result is a namespace for the module’s body +in the anchor’s phase. The result is the same as a namespace obtained +via module->namespace, and the module is similarly made +available if it is not available already.

If the anchor is from a define-namespace-anchor form in a +top-level content, then the result is the namespace in which the +anchor definition was evaluated.

parameter

(current-namespace)  namespace?

(current-namespace n)  void?
  n : namespace?
A parameter that determines the current namespace.

procedure

(namespace-symbol->identifier sym)  identifier?

  sym : symbol?
Similar to datum->syntax restricted to symbols. The +lexical information of the resulting identifier corresponds to +the top-level environment of the current namespace; the identifier has +no source location or properties.

procedure

(namespace-base-phase [namespace])  exact-integer?

  namespace : namespace? = (current-namespace)
Returns the base phase of namespace.

procedure

(namespace-module-identifier [where])  identifier?

  where : (or/c namespace? exact-integer? #f)
   = (current-namespace)
Returns an identifier whose binding is module in the +base phase of where if it is a namespace, or in the +where phase level otherwise.

The lexical information of the identifier includes bindings (in +the same phase level) for all syntactic forms that appear in +fully expanded code (see Fully Expanded Programs), but using the +name reported by the second element of identifier-binding for +the binding; the lexical information may also include other +bindings.

procedure

(namespace-variable-value sym    
  [use-mapping?    
  failure-thunk    
  namespace])  any
  sym : symbol?
  use-mapping? : any/c = #t
  failure-thunk : (or/c (-> any) #f) = #f
  namespace : namespace? = (current-namespace)
Returns a value for sym in namespace, using +namespace’s base phase. The returned value depends on +use-mapping?:

  • If use-mapping? is true (the default), and if +sym maps to a top-level variable or an imported variable +(see Namespaces), then the result is the same as +evaluating sym as an expression. If sym maps to +syntax or imported syntax, then failure-thunk is called or +the exn:fail:syntax exception is raised. If sym is mapped to an +undefined variable or an uninitialized module variable, then +failure-thunk is called or the +exn:fail:contract:variable exception is raised.

  • If use-mapping? is #f, the namespace’s +syntax and import mappings are ignored. Instead, the value of the +top-level variable named sym in namespace is returned. If +the variable is undefined, then failure-thunk is called or +the exn:fail:contract:variable exception is raised.

If failure-thunk is not #f, +namespace-variable-value calls failure-thunk to +produce the return value in place of raising an +exn:fail:contract:variable or exn:fail:syntax +exception.

procedure

(namespace-set-variable-value! sym    
  v    
  [map?    
  namespace    
  as-constant?])  void?
  sym : symbol?
  v : any/c
  map? : any/c = #f
  namespace : namespace? = (current-namespace)
  as-constant? : any/c = #f
Sets the value of sym in the top-level environment of +namespace in the base phase, defining sym if +it is not already defined.

If map? is supplied as true, then the namespace’s +identifier mapping is also adjusted (see +Namespaces) in the phase level corresponding to +the base phase, so that sym maps to the variable.

If as-constant? is true, then the variable is made a constant +(so future assignments are rejected) after v is installed as +the value.

Changed in version 6.90.0.14 of package base: Added the as-constant? argument.

procedure

(namespace-undefine-variable! sym    
  [namespace])  void?
  sym : symbol?
  namespace : namespace? = (current-namespace)
Removes the sym variable, if any, in the top-level +environment of namespace in its base phase. The +namespace’s identifier mapping (see Namespaces) +is unaffected.

procedure

(namespace-mapped-symbols [namespace])  (listof symbol?)

  namespace : namespace? = (current-namespace)
Returns a list of all symbols that are mapped to variables, syntax, +and imports in namespace for the phase level +corresponding to the namespace’s base phase.

procedure

(namespace-require quoted-raw-require-spec    
  [namespace])  void?
  quoted-raw-require-spec : any/c
  namespace : namespace? = (current-namespace)
Performs the import corresponding to quoted-raw-require-spec +in the top-level environment of namespace, like a +top-level #%require. The quoted-raw-require-spec +argument must be either a datum that corresponds to a quoted +raw-require-spec for #%require, which includes +module paths, or it can be a resolved module path.

Module paths in quoted-raw-require-spec are resolved with respect +to current-load-relative-directory or +current-directory (if the former is #f), even if the +current namespace corresponds to a module body.

Changed in version 6.90.0.16 of package base: Added the namespace optional argument.

procedure

(namespace-require/copy quoted-raw-require-spec    
  [namespace])  void?
  quoted-raw-require-spec : any/c
  namespace : namespace? = (current-namespace)
Like namespace-require for syntax exported from the module, +but exported variables at the namespace’s base phase are +treated differently: the export’s current value is copied to a +top-level variable in namespace.

Changed in version 6.90.0.16 of package base: Added the namespace optional argument.

procedure

(namespace-require/constant quoted-raw-require-spec    
  [namespace])  void?
  quoted-raw-require-spec : any/c
  namespace : namespace? = (current-namespace)
Like namespace-require, but for each exported variable at the +namespace’s base phase, the export’s value is copied to +a corresponding top-level variable that is made immutable. Despite +setting the top-level variable, the corresponding identifier is bound +as imported.

Changed in version 6.90.0.16 of package base: Added the namespace optional argument.

procedure

(namespace-require/expansion-time quoted-raw-require-spec 
  [namespace]) 
  void?
  quoted-raw-require-spec : any/c
  namespace : namespace? = (current-namespace)
Like namespace-require, but only the transformer part of the +module is executed relative to namespace’s base +phase; that is, the module is merely visited, and not +instantiated (see Module Expansion, Phases, and Visits). If the required module +has not been instantiated before, the module’s variables remain +undefined.

Changed in version 6.90.0.16 of package base: Added the namespace optional argument.

procedure

(namespace-attach-module src-namespace    
  modname    
  [dest-namespace])  void?
  src-namespace : namespace?
  modname : (or module-path? resolved-module-path?)
  dest-namespace : namespace? = (current-namespace)
Attaches the instantiated module named by modname + in src-namespace (at its base phase) to the + module registry of dest-namespace.

In addition to modname, every module that it + imports (directly or indirectly) is also recorded in the + current namespace’s module registry, and instances + at the same phase are also attached to + dest-namespace (while visits at the + module’s phase and instances at higher or lower phases are + not attached, nor even made available for on-demand + visits). The inspector of the module invocation in + dest-namespace is the same as inspector of the + invocation in src-namespace.

If modname is not a symbol, the current module + name resolver is called to resolve the path, but no module + is loaded; the resolved form of modname is used as + the module name in dest-namespace.

If modname refers to a submodule or a module with + submodules, unless the module was loaded from bytecode + (i.e., a ".zo" file) independently from submodules + within the same top-level module, then declarations for all + submodules within the module’s top-level module are also + attached to dest-namespace.

If modname does not refer to an + instantiated module in src-namespace, or if + the name of any module to be attached already has a + different declaration or same-phase instance in + dest-namespace, then the + exn:fail:contract exception is raised.

If src-namespace and dest-namespace do + not have the same base phase, then the + exn:fail:contract exception is raised.

Unlike namespace-require, + namespace-attach-module does not + instantiate the module, but copies the module + instance from the source namespace to the target namespace.

Examples:
> (module food racket/base
    (provide apple)
    (define apple (list "pie")))
> (namespace-require ''food)
> (define ns (current-namespace))
> (parameterize ([current-namespace (make-base-namespace)])
    (namespace-require ''food))

require: unknown module

  module name: 'food

> (parameterize ([current-namespace (make-base-namespace)])
    (namespace-attach-module ns ''food)
    (namespace-require ''food)
    (eq? (eval 'apple) apple))

#t

> (parameterize ([current-namespace (make-base-namespace)])
    (namespace-attach-module-declaration ns ''food)
    (namespace-require ''food)
    (eq? (eval 'apple) apple))

#f

procedure

(namespace-attach-module-declaration src-namespace    
  modname    
  [dest-namespace])  void?
  src-namespace : namespace?
  modname : module-path?
  dest-namespace : namespace? = (current-namespace)
Like namespace-attach-module, but the module +specified by modname need only be declared (and not +necessarily instantiated) in src-namespace, and the +module is merely declared in dest-namespace.

procedure

(namespace-unprotect-module inspector    
  modname    
  [namespace])  void?
  inspector : inspector?
  modname : module-path?
  namespace : namespace? = (current-namespace)
Changes the inspector for the instance of the module referenced by +modname in namespace’s module registry so +that it is controlled by the current code inspector. The given +inspector must currently control the invocation of the module +in namespace’s module registry, otherwise the +inspector is not changed. See also Code Inspectors.

procedure

(namespace-module-registry namespace)  any

  namespace : namespace?
Returns the module registry of the given namespace. This value +is useful only for identification via eq?.

procedure

(namespace-call-with-registry-lock namespace    
  thunk)  any
  namespace : namespace?
  thunk : (-> any)
Calls thunk while holding a reentrant lock for the namespace’s +module registry.

Namespace functions do not automatically use the registry lock, but it +can be used via namespace-call-with-registry-lock among +threads that load and instantiate modules to avoid internal race +conditions. On-demand instantiation of available modules +also takes the lock; see Module Expansion, Phases, and Visits.

Added in version 8.1.0.5 of package base.

procedure

(module->namespace mod [src-namespace])  namespace?

  mod : 
(or/c module-path?
      resolved-module-path?
      module-path-index?)
  src-namespace : namespace? = (current-namespace)
Returns a namespace that corresponds to the body of an instantiated +module in src-namespace’s module registry and in the +src-namespace’s base phase, making the module +available for on-demand visits at src-namespace’s +base phase. The returned namespace has the same module +registry as src-namespace. Modifying a binding in the +resulting namespace changes the binding seen in modules that require the +namespace’s module.

Module paths in a top-level require expression are resolved +with respect to the namespace’s module. New provide +declarations are not allowed.

If the current code inspector does not control the invocation of the +module in src-namespace’s module registry, the +exn:fail:contract exception is raised; see also Code Inspectors.

Bindings in the result namespace cannot be modified if the +compile-enforce-module-constants parameter was true when the +module was declared, unless the module declaration itself included +assignments to the binding via set!.

Changed in version 6.90.0.16 of package base: Added the src-namespace optional argument.

procedure

(namespace-syntax-introduce stx [namespace])  syntax?

  stx : syntax?
  namespace : namespace? = (current-namespace)
Returns a syntax object like stx, except that +namespace’s bindings are included in the syntax object’s +lexical information (see Syntax Objects). The +additional context is overridden by any existing top-level +bindings in the syntax object’s lexical information, or +by any existing or future module bindings in the lexical +information.

Changed in version 6.90.0.16 of package base: Added the namespace optional argument.

procedure

(module-provide-protected? module-path-index    
  sym)  boolean?
  module-path-index : (or/c symbol? module-path-index?)
  sym : symbol?
Returns #f if the module declaration for +module-path-index defines sym and exports it +unprotected, #t otherwise (which may mean that the symbol +corresponds to an unexported definition, a protected export, or an +identifier that is not defined at all within the module).

The module-path-index argument can be a symbol; see +Compiled Modules and References for more information on module path +indices.

Typically, the arguments to module-provide-protected? +correspond to the first two elements of a list produced by +identifier-binding.

procedure

(variable-reference? v)  boolean?

  v : any/c
Return #t if v is a variable reference +produced by #%variable-reference, #f otherwise.

procedure

(variable-reference-constant? varref)  boolean?

  varref : variable-reference?
Returns #t if the variable represented by varref +will retain its current value (i.e., varref refers to a +variable that cannot be further modified by set! or +define), #f otherwise.

Returns an empty namespace that shares module declarations and +instances with the namespace in which varref is instantiated, +and with the same phase as varref.

procedure

(variable-reference->namespace varref)  namespace?

  varref : variable-reference?
If varref refers to a module-level variable, then the +result is a namespace for the module’s body in the referenced +variable’s phase; the result is the same as a namespace +obtained via module->namespace, and the module is similarly made +available if it is not available already.

If varref refers to a top-level variable, then the +result is the namespace in which the referenced variable is defined.

If varref refers to a module-level variable, the +result is a resolved module path naming the module.

If varref refers to a top-level variable, then the +result is #f.

If varref refers to a module-level variable, the +result is a module path index naming the module.

If varref refers to a top-level variable, then the +result is #f.

If varref refers to a module-level variable, the +result is a path or symbol naming the module’s source (which is +typically, but not always, the same as in the resolved module +path). If the relevant module is a submodule, the result +corresponds to the enclosing top-level module’s source.

If varref refers to a top-level variable, then the +result is #f.

Returns the phase of the variable referenced by varref.

Returns the phase in which the module is instantiated for the +variable referenced by varref, or 0 if the variable +for varref is not within a module.

For a variable with a module, the result is less than the result of +(variable-reference->phase varref) by n when the +variable is bound at phase level n within the module.

Returns the declaration inspector (see Code Inspectors) +for the module of varref, where varref must refer to +an anonymous module variable as produced by +(#%variable-reference).

procedure

(variable-reference-from-unsafe? varref)  boolean?

  varref : variable-reference?
Returns #t if the module of the variable reference itself +(not necessarily a referenced variable) is compiled in unsafe mode, +#f otherwise. Unsafe mode can be enabled through the +linklet interface or enable for a module with +(#%declare #:unsafe).

The variable-reference-from-unsafe? procedure is intended for +use as

(variable-reference-from-unsafe? (#%variable-reference))

which the compiler can optimize to a literal #t or +#f (since the enclosing module is being compiled in +unsafe mode or not).

Added in version 6.12.0.4 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Object_and_Class_Contracts.html b/clones/docs.racket-lang.org/reference/Object_and_Class_Contracts.html new file mode 100644 index 00000000..46c68afc --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Object_and_Class_Contracts.html @@ -0,0 +1,127 @@ + +6.7 Object and Class Contracts

6.7 Object and Class Contracts

syntax

(class/c maybe-opaque member-spec ...)

 
maybe-opaque = 
  | #:opaque
  | #:opaque #:ignore-local-member-names
     
member-spec = method-spec
  | (field field-spec ...)
  | (init field-spec ...)
  | (init-field field-spec ...)
  | (inherit method-spec ...)
  | (inherit-field field-spec ...)
  | (super method-spec ...)
  | (inner method-spec ...)
  | (override method-spec ...)
  | (augment method-spec ...)
  | (augride method-spec ...)
  | (absent absent-spec ...)
     
method-spec = method-id
  | (method-id method-contract-expr)
     
field-spec = field-id
  | (field-id contract-expr)
     
absent-spec = method-id
  | (field field-id ...)
Produces a contract for a class.

There are two major categories of contracts listed in a class/c +form: external and internal contracts. External contracts govern behavior +when an object is instantiated from a class or when methods or fields are +accessed via an object of that class. Internal contracts govern behavior +when method or fields are accessed within the class hierarchy. This +separation allows for stronger contracts for class clients and weaker +contracts for subclasses.

Method contracts must contain an additional initial argument which corresponds +to the implicit this parameter of the method. This allows for +contracts which discuss the state of the object when the method is called +(or, for dependent contracts, in other parts of the contract). Alternative +contract forms, such as ->m, are provided as a shorthand +for writing method contracts.

Methods and fields listed in an absent clause must not be present in the class.

A class contract can be specified to be opaque with the #:opaque +keyword. An opaque class contract will only accept a class that defines +exactly the external methods and fields specified by the contract. A contract error +is raised if the contracted class contains any methods or fields that are +not specified. Methods or fields with local member names (i.e., defined with +define-local-member-name) are ignored for this check if +#:ignore-local-member-names is provided.

The external contracts are as follows:

  • An external method contract without a tag describes the behavior +of the implementation of method-id on method sends to an +object of the contracted class. This contract will continue to be +checked in subclasses until the contracted class’s implementation is +no longer the entry point for dynamic dispatch.

    If only the field name is present, this is equivalent to insisting only +that the method is present in the class.

    Examples:
    (define woody%
      (class object%
        (define/public (draw who)
          (format "reach for the sky, ~a" who))
        (super-new)))
     
    (define/contract woody+c%
      (class/c [draw (->m symbol? string?)])
      woody%)

     

    > (send (new woody%) draw #f)

    "reach for the sky, #f"

    > (send (new woody+c%) draw 'zurg)

    "reach for the sky, zurg"

    > (send (new woody+c%) draw #f)

    draw: contract violation

      expected: symbol?

      given: #f

      in: the 1st argument of

          the draw method in

          (class/c (draw (->m symbol? string?)))

      contract from: (definition woody+c%)

      contract on: woody+c%

      blaming: top-level

       (assuming the contract is correct)

      at: eval:68:0

  • An external field contract, tagged with field, describes the +behavior of the value contained in that field when accessed from outside +the class. Since fields may be mutated, these contracts +are checked on any external access (via get-field) +and external mutations (via set-field!) of the field.

    If only the field name is present, this is equivalent to using the +contract any/c (but it is checked more efficiently).

    Examples:
    (define woody/hat%
      (class woody%
        (field [hat-location 'uninitialized])
        (define/public (lose-hat) (set! hat-location 'lost))
        (define/public (find-hat) (set! hat-location 'on-head))
        (super-new)))
    (define/contract woody/hat+c%
      (class/c [draw (->m symbol? string?)]
               [lose-hat (->m void?)]
               [find-hat (->m void?)]
               (field [hat-location (or/c 'on-head 'lost)]))
      woody/hat%)

     

    > (get-field hat-location (new woody/hat%))

    'uninitialized

    > (let ([woody (new woody/hat+c%)])
        (send woody lose-hat)
        (get-field hat-location woody))

    'lost

    > (get-field hat-location (new woody/hat+c%))

    woody/hat+c%: broke its own contract

      promised: (or/c (quote on-head) (quote lost))

      produced: 'uninitialized

      in: the hat-location field in

          (class/c

           (draw (->m symbol? string?))

           (lose-hat (->m void?))

           (find-hat (->m void?))

           (field (hat-location

                   (or/c 'on-head 'lost))))

      contract from: (definition woody/hat+c%)

      blaming: (definition woody/hat+c%)

       (assuming the contract is correct)

      at: eval:73:0

    > (let ([woody (new woody/hat+c%)])
        (set-field! hat-location woody 'under-the-dresser))

    woody/hat+c%: contract violation

      expected: (or/c (quote on-head) (quote lost))

      given: 'under-the-dresser

      in: the hat-location field in

          (class/c

           (draw (->m symbol? string?))

           (lose-hat (->m void?))

           (find-hat (->m void?))

           (field (hat-location

                   (or/c 'on-head 'lost))))

      contract from: (definition woody/hat+c%)

      blaming: top-level

       (assuming the contract is correct)

      at: eval:73:0

  • An initialization argument contract, tagged with init, +describes the expected behavior of the value paired with that name +during class instantiation. The same name can be provided more than +once, in which case the first such contract in the class/c +form is applied to the first value tagged with that name in the list +of initialization arguments, and so on.

    If only the initialization argument name is present, this is equivalent to using the +contract any/c (but it is checked more efficiently).

    Examples:
    (define woody/init-hat%
      (class woody%
        (init init-hat-location)
        (field [hat-location init-hat-location])
        (define/public (lose-hat) (set! hat-location 'lost))
        (define/public (find-hat) (set! hat-location 'on-head))
        (super-new)))
    (define/contract woody/init-hat+c%
      (class/c [draw (->m symbol? string?)]
               [lose-hat (->m void?)]
               [find-hat (->m void?)]
               (init [init-hat-location (or/c 'on-head 'lost)])
               (field [hat-location (or/c 'on-head 'lost)]))
      woody/init-hat%)

     

    > (get-field hat-location
                 (new woody/init-hat+c%
                      [init-hat-location 'lost]))

    'lost

    > (get-field hat-location
                 (new woody/init-hat+c%
                      [init-hat-location 'slinkys-mouth]))

    woody/init-hat+c%: contract violation

      expected: (or/c (quote on-head) (quote lost))

      given: 'slinkys-mouth

      in: the init-hat-location init argument in

          (class/c

           (draw (->m symbol? string?))

           (lose-hat (->m void?))

           (find-hat (->m void?))

           (init (init-hat-location

                  (or/c 'on-head 'lost)))

           (field (hat-location

                   (or/c 'on-head 'lost))))

      contract from:

          (definition woody/init-hat+c%)

      blaming: top-level

       (assuming the contract is correct)

      at: eval:79:0

  • The contracts listed in an init-field section are +treated as if each contract appeared in an init section and +a field section.

The internal contracts restrict the behavior of method calls +made between classes and their subclasses; such calls are not +controlled by the class contracts described above.

As with the external contracts, when a method or field name is specified + but no contract appears, the contract is satisfied merely with the + presence of the corresponding field or method.

  • A method contract tagged with inherit describes the +behavior of the method when invoked directly (i.e., via +inherit) in any subclass of the contracted class. This +contract, like external method contracts, applies until the +contracted class’s method implementation is no longer the entry point +for dynamic dispatch.

    Examples:
    > (new (class woody+c%
             (inherit draw)
             (super-new)
             (printf "woody sez: “~a”\n" (draw "evil dr porkchop"))))

    woody sez: “reach for the sky, evil dr porkchop”

    (object:eval:82:0 ...)

     

    (define/contract woody+c-inherit%
      (class/c (inherit [draw (->m symbol? string?)]))
      woody+c%)

     

    > (new (class woody+c-inherit%
             (inherit draw)
             (printf "woody sez: ~a\n" (draw "evil dr porkchop"))))

    draw: contract violation

      expected: symbol?

      given: "evil dr porkchop"

      in: the 1st argument of

          the draw method in

          (class/c

           (inherit (draw (->m symbol? string?))))

      contract from: (definition woody+c-inherit%)

      contract on: woody+c-inherit%

      blaming: top-level

       (assuming the contract is correct)

      at: eval:83:0

  • A method contract tagged with super describes the behavior of +method-id when called by the super form in a +subclass. This contract only affects super calls in +subclasses which call the contract class’s implementation of +method-id.

    This example shows how to extend the draw method +so that if it is passed two arguments, it combines two +calls to the original draw method, but with a +contract the controls how the super methods must +be invoked.

    Examples:
    (define/contract woody%+s
      (class/c (super [draw (->m symbol? string?)]))
      (class object%
        (define/public (draw who)
          (format "reach for the sky, ~a" who))
        (super-new)))
     
    (define woody2+c%
      (class woody%+s
        (define/override draw
          (case-lambda
            [(a) (super draw a)]
            [(a b) (string-append (super draw a)
                                  " and "
                                  (super draw b))]))
        (super-new)))

     

    > (send (new woody2+c%) draw 'evil-dr-porkchop  'zurg)

    "reach for the sky, evil-dr-porkchop and reach for the sky, zurg"

    > (send (new woody2+c%) draw "evil dr porkchop" "zurg")

    draw: contract violation

      expected: symbol?

      given: "evil dr porkchop"

      in: the 1st argument of

          the draw method in

          (class/c

           (super (draw (->m symbol? string?))))

      contract from: (definition woody%+s)

      contract on: woody%+s

      blaming: top-level

       (assuming the contract is correct)

      at: eval:85:0

    The last call signals an error blaming woody2%+c because +there is no contract checking the initial draw call and +the super-call violates its contract.

  • A method contract tagged with inner describes the +behavior the class expects of an augmenting method in a subclass. +This contract affects any implementations of method-id in +subclasses which can be called via inner from the contracted +class. This means a subclass which implements method-id via +augment or overment stop future subclasses from +being affected by the contract, since further extension cannot be +reached via the contracted class.

  • A method contract tagged with override describes the +behavior expected by the contracted class for method-id when +called directly (i.e. by the application (method-id ...)). +This form can only be used if overriding the method in subclasses +will change the entry point to the dynamic dispatch chain (i.e., the +method has never been augmentable).

    This time, instead of overriding draw to support +two arguments, we can make a new method, draw2 that +takes the two arguments and calls draw. We also +add a contract to make sure that overriding draw +doesn’t break draw2.

    Examples:
    (define/contract woody2+override/c%
      (class/c (override [draw (->m symbol? string?)]))
      (class woody+c%
        (inherit draw)
        (define/public (draw2 a b)
          (string-append (draw a)
                         " and "
                         (draw b)))
        (super-new)))
     
    (define woody2+broken-draw
      (class woody2+override/c%
        (define/override (draw x)
          'not-a-string)
        (super-new)))

     

    > (send (new woody2+broken-draw) draw2
            'evil-dr-porkchop
            'zurg)

    draw: contract violation

      expected: string?

      given: 'not-a-string

      in: the range of

          the draw method in

          (class/c

           (override (draw (->m symbol? string?))))

      contract from:

          (definition woody2+override/c%)

      contract on: woody2+override/c%

      blaming: top-level

       (assuming the contract is correct)

      at: eval:89:0

  • A method contract tagged with either augment or +augride describes the behavior provided by the contracted +class for method-id when called directly from subclasses. +These forms can only be used if the method has previously been +augmentable, which means that no augmenting or overriding +implementation will change the entry point to the dynamic dispatch +chain. augment is used when subclasses can augment the +method, and augride is used when subclasses can override the +current augmentation.

  • A field contract tagged with inherit-field describes +the behavior of the value contained in that field when accessed +directly (i.e., via inherit-field) in any subclass of the +contracted class. Since fields may be mutated, these contracts are +checked on any access and/or mutation of the field that occurs in +such subclasses.

  • Changed in version 6.1.1.8 of package base: Opaque class/c now optionally ignores local +member names if an additional keyword is supplied.

syntax

(absent absent-spec ...)

See class/c; use outside of a class/c form is a syntax error.

syntax

(->m dom ... range)

Similar to ->, except that the domain of the resulting contract +contains one more element than the stated domain, where the first +(implicit) argument is contracted with any/c. This contract is +useful for writing simpler method contracts when no properties of +this need to be checked.

syntax

(->*m (mandatory-dom ...) (optional-dom ...) rest range)

Similar to ->*, except that the mandatory domain of the +resulting contract contains one more element than the stated domain, +where the first (implicit) argument is contracted with +any/c. This contract is useful for writing simpler method +contracts when no properties of this need to be checked.

syntax

(case->m (-> dom ... rest range) ...)

Similar to case->, except that the mandatory domain of each +case of the resulting contract contains one more element than the stated +domain, where the first (implicit) argument is contracted with +any/c. This contract is useful for writing simpler method +contracts when no properties of this need to be checked.

syntax

(->dm (mandatory-dependent-dom ...)
      (optional-dependent-dom ...)
      dependent-rest
      pre-cond
      dep-range)
Similar to ->d, except that the mandatory domain of the resulting contract +contains one more element than the stated domain, where the first (implicit) argument is contracted +with any/c. In addition, this is appropriately bound in the body of the contract. +This contract is useful for writing simpler method contracts when no properties +of this need to be checked.

syntax

(object/c member-spec ...)

 
member-spec = method-spec
  | (field field-spec ...)
     
method-spec = method-id
  | (method-id method-contract)
     
field-spec = field-id
  | (field-id contract-expr)
Produces a contract for an object.

Unlike the older form object-contract, but like +class/c, arbitrary contract expressions are allowed. +Also, method contracts for object/c follow those for +class/c. An object wrapped with object/c +behaves as if its class had been wrapped with the equivalent +class/c contract.

procedure

(instanceof/c class-contract)  contract?

  class-contract : contract?
Produces a contract for an object, where the object is an +instance of a class that conforms to class-contract.

procedure

(dynamic-object/c method-names    
  method-contracts    
  field-names    
  field-contracts)  contract?
  method-names : (listof symbol?)
  method-contracts : (listof contract?)
  field-names : (listof symbol?)
  field-contracts : (listof contract?)
Produces a contract for an object, similar to object/c but +where the names and contracts for both methods and fields can be +computed dynamically. The list of names and contracts for both +methods and field respectively must have the same lengths.

syntax

(object-contract member-spec ...)

 
member-spec = (method-id method-contract)
  | (field field-id contract-expr)
     
method-contract = (-> dom ... range)
  | 
(->* (mandatory-dom ...)
     (optional-dom ...)
     rest
     range)
  | 
(->d (mandatory-dependent-dom ...)
     (optional-dependent-dom ...)
     dependent-rest
     pre-cond
     dep-range)
     
dom = dom-expr
  | keyword dom-expr
     
range = range-expr
  | (values range-expr ...)
  | any
     
mandatory-dom = dom-expr
  | keyword dom-expr
     
optional-dom = dom-expr
  | keyword dom-expr
     
rest = 
  | #:rest rest-expr
     
mandatory-dependent-dom = [id dom-expr]
  | keyword [id dom-expr]
     
optional-dependent-dom = [id dom-expr]
  | keyword [id dom-expr]
     
dependent-rest = 
  | #:rest id rest-expr
     
pre-cond = 
  | #:pre-cond boolean-expr
     
dep-range = any
  | [id range-expr] post-cond
  | (values [id range-expr] ...) post-cond
     
post-cond = 
  | #:post-cond boolean-expr
Produces a contract for an object.

Each of the contracts for a method has the same semantics as +the corresponding function contract, but the syntax of the +method contract must be written directly in the body of the +object-contract—much like the way that methods in class +definitions use the same syntax as regular function +definitions, but cannot be arbitrary procedures. Unlike the +method contracts for class/c, the implicit this +argument is not part of the contract. To allow for the use of +this in dependent contracts, ->d contracts +implicitly bind this to the object itself.

A function contract that recognizes mixins. It guarantees that +the input to the function is a class and the result of the function is +a subclass of the input.

procedure

(make-mixin-contract type ...)  contract?

  type : (or/c class? interface?)
Produces a function contract that guarantees the input to the +function is a class that implements/subclasses each type, and +that the result of the function is a subclass of the input.

procedure

(is-a?/c type)  flat-contract?

  type : (or/c class? interface?)
Accepts a class or interface and returns a flat contract that +recognizes objects that instantiate the class/interface.

See is-a?.

procedure

(implementation?/c interface)  flat-contract?

  interface : interface?
Returns a flat contract that recognizes classes that implement +interface.

See implementation?.

procedure

(subclass?/c class)  flat-contract?

  class : class?
Returns a flat contract that recognizes classes that +are subclasses of class.

See subclass?.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Printer_Extension.html b/clones/docs.racket-lang.org/reference/Printer_Extension.html new file mode 100644 index 00000000..c75806f9 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Printer_Extension.html @@ -0,0 +1,51 @@ + +13.8 Printer Extension

13.8 Printer Extension

A generic interface (see Generic Interfaces) that +supplies a method, write-proc used by the default printer to +display, write, or print instances of the +structure type.

A write-proc method takes three +arguments: the structure to be printed, the target port, and an +argument that is #t for write mode, #f for +display mode, or 0 or 1 indicating +the current quoting depth for print mode. The +procedure should print the value to the given port using +write, display, print, fprintf, +write-special, etc.

The port write handler, port display handler, +and print handler are specially +configured for a port given to a custom-write procedure. Printing to +the port through display, write, or print +prints a value recursively with sharing annotations. To avoid a +recursive print (i.e., to print without regard to sharing with a value +currently being printed), print instead to a string or pipe and +transfer the result to the target port using write-string or +write-special. To print recursively to a port other than +the one given to the custom-write procedure, copy the given port’s +write handler, display handler, and print handler to the other port.

The port given to write-proc is not necessarily the actual +target port. In particular, to detect cycles, sharing, and quoting +modes (in the case of print), the printer invokes a +custom-write procedure with a port that records information about +recursive prints, and does not retain any other output. This +information-gathering phase needs the same objects (in the +eq? sense) to be printed as later, so that the recorded +information can be correlated with printed values.

Recursive print operations may trigger an escape from a call to +write-proc. For example, printing may escape during +pretty-printing where a tentative print attempt overflows the line, or +it may escape while printing error output that is constrained to a +limited width.

The following example definition of a tuple type includes +a write-proc procedure that prints the tuple’s list content using +angle brackets in write and print mode and no brackets in +display mode. Elements of the tuple are printed recursively, +so that graph and cycle structure can be represented.

Examples:
(define (tuple-print tuple port mode)
  (when mode (write-string "<" port))
  (let ([l (tuple-ref tuple)]
        [recur (case mode
                 [(#t) write]
                 [(#f) display]
                 [else (lambda (p port) (print p port mode))])])
    (unless (zero? (vector-length l))
      (recur (vector-ref l 0) port)
      (for-each (lambda (e)
                  (write-string ", " port)
                  (recur e port))
                (cdr (vector->list l)))))
  (when mode (write-string ">" port)))

 

(struct tuple (ref)
        #:methods gen:custom-write
        [(define write-proc tuple-print)])

 

> (display (tuple #(1 2 "a")))

1, 2, a

> (print (tuple #(1 2 "a")))

<1, 2, "a">

> (let ([t (tuple (vector 1 2 "a"))])
    (vector-set! (tuple-ref t) 0 t)
    (write t))

#0=<#0#, 2, "a">

The make-constructor-style-printer function can help in the +implementation of a write-proc, as in this example:

Examples:
(require racket/struct)

 

(struct point (x y)
  #:methods gen:custom-write
  [(define write-proc
     (make-constructor-style-printer
      (lambda (obj) 'point)
      (lambda (obj) (list (point-x obj) (point-y obj)))))])

 

> (print (point 1 2))

(point 1 2)

> (write (point 1 2))

#<point: 1 2>

A structure type property (see Structure Type Properties) +that supplies a procedure that corresponds to gen:custom-write’s +write-proc. Using the prop:custom-write property is +discouraged; use the gen:custom-write generic interface +instead.

procedure

(custom-write? v)  boolean?

  v : any/c
Returns #t if v has the prop:custom-write +property, #f otherwise.

procedure

(custom-write-accessor v)

  (custom-write? output-port? (or/c #t #f 0 1) . -> . any)
  v : custom-write?
Returns the custom-write procedure associated with v.

A property and associated predicate and accessor. The property value +is one of 'self, 'never, 'maybe, or +'always. When a structure has this property in addition to a +prop:custom-write property value, then the property value +affects printing in print mode; see The Printer. When +a value does not have the prop:custom-print-quotable, it is +equivalent to having the 'self property value, which is +suitable both for self-quoting forms and printed forms that are +unreadable.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Random_generation.html b/clones/docs.racket-lang.org/reference/Random_generation.html new file mode 100644 index 00000000..a36424dd --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Random_generation.html @@ -0,0 +1,44 @@ + +8.12 Random generation

8.12 Random generation

procedure

(contract-random-generate ctc [fuel fail])  any/c

  ctc : contract?
  fuel : 5 = exact-nonnegative-integer?
  fail : (or/c #f (-> any) (-> boolean? any)) = #f
Attempts to randomly generate a value which will match the contract. The fuel +argument limits how hard the generator tries to generate a value matching the +contract and is a rough limit of the size of the resulting value.

The generator may fail to generate a value, either because some contracts +do not have corresponding generators (for example, not all predicates have +generators) or because there is not enough fuel. In either case, the +function fail is invoked. If fail accepts an argument, +it is called with #t when there is no generator for ctc +and called with #f when there is a generator, but the generator +ended up returning contract-random-generate-fail.

Example:
> (for/list ([i (in-range 10)])
    (contract-random-generate (or/c integer? #f)))

'(#f -476814620 -2147483647.0 110.0 540119564.0 -1 #f #f -1886291931.0 168.0)

Changed in version 6.1.1.5 of package base: Allow fail to accept a boolean.

procedure

(contract-exercise [#:fuel fuel    
  #:shuffle? shuffle?]    
  val ...+)  void?
  fuel : exact-nonnegative-integer? = 10
  shuffle? : any/c = #f
  val : any/c
Attempts to get the vals to break their contracts (if any).

Uses value-contract to determine if any of the vals have a + contract and, for those that do, uses information about the contract’s shape + to poke and prod at the value. For example, if the value is function, it will + use the contract to tell it what arguments to supply to the value.

The argument fuel determines how hard contract-exercise + tries to break the values. It controls both the number of exercise iterations + and the size of the intermediate values generated during the exercises.

The argument shuffle? controls whether contract-exercise + randomizes the exercise order or not. If shuffle? is not #f, + contract-exercise would shuffle the order of the contracts in each + exercise iteration.

Examples:
> (define/contract (returns-false x)
    (-> integer? integer?)
    ; does not obey its contract
    #f)
> (contract-exercise returns-false)

returns-false: broke its own contract

  promised: integer?

  produced: #f

  in: the range of

      (-> integer? integer?)

  contract from: (function returns-false)

  blaming: (function returns-false)

   (assuming the contract is correct)

  at: eval:2:0

> (define/contract (calls-its-argument-with-eleven f)
    (-> (-> integer? integer?) boolean?)
    ; f returns an integer, but
    ; we're supposed to return a boolean
    (f 11))
> (contract-exercise calls-its-argument-with-eleven)

calls-its-argument-with-eleven: broke its own contract

  promised: boolean?

  produced: 1980102363.0

  in: the range of

      (-> (-> integer? integer?) boolean?)

  contract from:

      (function calls-its-argument-with-eleven)

  blaming: (function calls-its-argument-with-eleven)

   (assuming the contract is correct)

  at: eval:4:0

Changed in version 7.0.0.18 of package base: Added the shuffle? optional argument.

procedure

(contract-random-generate/choose c fuel)  (or/c #f (-> c))

  c : contract?
  fuel : exact-nonnegative-integer?
This function is like contract-random-generate, but it is intended to + be used with combinators that generate values based on sub-contracts + they have. It must be called when contract-random-generate + (and contract-exercise) creates the generators. + To be more precise, contract-random-generate/choose is available + only for the generate and exercise arguments in + build-contract-property, build-chaperone-contract-property + or build-flat-contract-property and only during the dynamic + extent of the call to generate (and exercise). + That is, after it receives the c and fuel arguments + and before it returns the thunk (or the exerciser).

contract-random-generate/choose will never fail, + but it might escape back to an enclosing + call or to the original call to contract-random-generate.

It chooses one of several possible generation strategies, and thus it may not + actually use the generator associated with c, but might instead + use a stashed value that matches c that it knows about via + contract-random-generate-stash.

Added in version 6.1.1.5 of package base.

An atomic value that is used to indicate that a generator + failed to generate a value.

Added in version 6.1.1.5 of package base.

procedure

(contract-random-generate-fail? v)  boolean?

  v : any/c
A predicate to recognize contract-random-generate-fail.

Added in version 6.1.1.5 of package base.

procedure

(contract-random-generate-env? v)  boolean?

  v : any/c
Recognizes contract generation environments.

Added in version 6.1.1.5 of package base.

procedure

(contract-random-generate-stash env c v)  void?

  env : contract-random-generate-env?
  c : contract?
  v : c
This should be called with values that the program under + test supplies during contract generation. For example, when + (-> (-> integer? integer?) integer?) is generated, + it may call its argument function. That argument function may + return an integer and, if so, that integer should be saved by + calling contract-random-generate-stash, so it can + be used by other integer generators.

Added in version 6.1.1.5 of package base.

Returns the environment currently being for generation. This function + can be called only during the dynamic extent of contract generation. + It is intended to be grabbed during the construction of a contract + generator and then used with contract-random-generate-stash + while generation is happening.

Added in version 6.1.1.5 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Reader_Extension.html b/clones/docs.racket-lang.org/reference/Reader_Extension.html new file mode 100644 index 00000000..23c667a7 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Reader_Extension.html @@ -0,0 +1,10 @@ + +13.7 Reader Extension

13.7 Reader Extension

Racket’s reader can be extended in three ways: through a reader-macro +procedure in a readtable (see Readtables), through a +#reader form (see Reading via an Extension), or through a +custom-port byte reader that returns a “special” result procedure +(see Custom Ports). All three kinds of reader +extension procedures accept similar arguments, and their results are +treated in the same way by read and read-syntax (or, +more precisely, by the default read handler; see +port-read-handler).

    13.7.1 Readtables

    13.7.2 Reader-Extension Procedures

    13.7.3 Special Comments

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Reading.html b/clones/docs.racket-lang.org/reference/Reading.html new file mode 100644 index 00000000..06220ea3 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Reading.html @@ -0,0 +1,185 @@ + +13.4 Reading

13.4 Reading

procedure

(read [in])  any

  in : input-port? = (current-input-port)
Reads and returns a single datum from in. If +in has a handler associated to it via +port-read-handler, then the handler is called. Otherwise, the +default reader is used, as parameterized by the +current-readtable parameter, as well as many other +parameters.

See The Reader for information on the default reader and +Reading via an Extension for the protocol of read.

procedure

(read-syntax [source-name in])  (or/c syntax? eof-object?)

  source-name : any/c = (object-name (current-input-port))
  in : input-port? = (current-input-port)
Like read, but produces a syntax object with +source-location information. The source-name is used as the +source field of the syntax object; it can be an arbitrary value, but +it should generally be a path for the source file.

See The Reader for information on the default reader in +read-syntax mode and Reading via an Extension for +the protocol of read-syntax.

+See also Syntax Objects in The Racket Guide.

procedure

(read/recursive [in start readtable graph?])  any

  in : input-port? = (current-input-port)
  start : (or/c char? #f) = #f
  readtable : (or/c readtable? #f) = (current-readtable)
  graph? : any/c = #t
Similar to calling read, but normally used during the dynamic +extent of read within a reader-extension procedure (see +Reader-Extension Procedures). The main effect of using +read/recursive instead of read is that +graph-structure annotations (see Reading Graph Structure) in the +nested read are considered part of the overall read, at least when the +graph? argument is true; since the result is wrapped in a +placeholder, however, it is not directly inspectable.

If start is provided and not #f, it is effectively +prefixed to the beginning of in’s stream for the read. (To +prefix multiple characters, use input-port-append.)

The readtable argument is used for top-level parsing to +satisfy the read request, including various delimiters of a built-in +top-level form (such as parentheses and . for reading a hash +table); recursive parsing within the read (e.g., to +read the elements of a list) instead uses the current readtable as +determined by the current-readtable parameter. A reader +macro might call read/recursive with a character and +readtable to effectively invoke the readtable’s behavior for the +character. If readtable is #f, the default +readtable is used for top-level parsing.

When graph? is #f, graph structure annotations in +the read datum are local to the datum.

When called within the dynamic extent of read, the +read/recursive procedure can produce a special-comment value +(see Special Comments) when the input stream’s first +non-whitespace content parses as a comment.

See Readtables for an extended example that uses +read/recursive.

Changed in version 6.2 of package base: Adjusted use of readtable to +more consistently apply to the delimiters of +a built-in form.

procedure

(read-syntax/recursive [source-name    
  in    
  start    
  readtable    
  graph?])  any
  source-name : any/c = (object-name in)
  in : input-port? = (current-input-port)
  start : (or/c char? #f) = #f
  readtable : (or/c readtable? #f) = (current-readtable)
  graph? : any/c = #t
Analogous to calling read/recursive, but the resulting value +encapsulates S-expression structure with source-location +information. As with read/recursive, when +read-syntax/recursive is used within the dynamic extent of +read-syntax, the result from +read-syntax/recursive is either a special-comment value, +end-of-file, or opaque graph-structure placeholder (not a syntax +object). The placeholder can be embedded in an S-expression or syntax +object returned by a reader macro, etc., and it will be replaced with +the actual syntax object before the outermost read-syntax +returns.

Using read/recursive within the dynamic extent of +read-syntax does not allow graph structure for reading to be +included in the outer read-syntax parsing, and neither does +using read-syntax/recursive within the dynamic extent of +read. In those cases, read/recursive and +read-syntax/recursive produce results like read and +read-syntax, except that a special-comment value is returned +when the input stream starts with a comment (after whitespace).

See Readtables for an extended example that uses +read-syntax/recursive.

Changed in version 6.2 of package base: Adjusted use of readtable +in the same way as for +read/recursive.

procedure

(read-language [in fail-thunk])

  (or/c (any/c any/c . -> . any) #f)
  in : input-port? = (current-input-port)
  fail-thunk : (-> any) = (lambda () (error ...))
Reads from in in the same way as read, but stopping as +soon as a reader language (or its absence) is determined, and +using the current namespace to load a reader module instead +of its root namespace (if those are different).

A reader language is specified by #lang or +#! (see Reading via an Extension) at the beginning of the +input, though possibly after comment forms. The default +readtable is used by read-language (instead of the +value of current-readtable), and #reader forms +(which might produce comments) are not allowed before #lang +or #!.

+See also Source-Handling Configuration in The Racket Guide.

When it finds a #lang or #! specification, instead +of dispatching to a read or read-syntax +function as read and read-syntax do, +read-language dispatches to the get-info +function (if any) exported by the same module. The arguments to +get-info are the same as for read +as described in Reading via an Extension. The result of the +get-info function is the result of +read-language if it is a function of two arguments; if +get-info produces any other kind of result, the +exn:fail:contract exception is raised. If no get-info function is +exported, read-language returns #f.

The function produced by get-info reflects information +about the expected syntax of the input stream. The first argument to the +function serves as a key on such information; acceptable keys and the +interpretation of results is up to external tools, such as DrRacket (see +the DrRacket documentation). +If no information is available for a given key, the result should be +the second argument. +

Examples:
> (define scribble-manual-info
    (read-language (open-input-string "#lang scribble/manual")))
> (scribble-manual-info 'color-lexer #f)

#<procedure:scribble-inside-lexer>

> (scribble-manual-info 'something-else #f)

#f

The get-info function itself is applied to five +arguments: the input port being read, the module path from which the +get-info function was extracted, and the source line +(positive exact integer or #f), column (non-negative exact +integer or #f), and position (positive exact integer or +#f) of the start of the #lang or #! +form. The get-info function may further read from the +given input port to determine its result, but it should read no +further than necessary. The get-info function should +not read from the port after returning a function.

If in starts with a reader language specification but +the relevant module does not export get-info (but +perhaps does export read and +read-syntax), then the result of read-language +is #f.

If in has a #lang or #! specification, +but parsing and resolving the specification raises an exception, the +exception is propagated by read-language. Having at least +#l or #! (after comments and whitespace) counts as +starting a #lang or #! specification.

If in does not specify a reader language with +#lang or #!, then fail-thunk is +called. The default fail-thunk raises +exn:fail:read or exn:fail:read:eof.

parameter

(read-case-sensitive)  boolean?

(read-case-sensitive on?)  void?
  on? : any/c
A parameter that controls parsing and printing of symbols. When this +parameter’s value is #f, the reader case-folds symbols (e.g., +producing 'hi when the input is any one of hi, +Hi, HI, or hI). The parameter also +affects the way that write prints symbols containing +uppercase characters; if the parameter’s value is #f, then +symbols are printed with uppercase characters quoted by a +\ or |. The parameter’s value is overridden by +quoting \ or | vertical-bar quotes and the +#cs and #ci prefixes; see +Reading Symbols for more information. While a module is +loaded, the parameter is set to #t (see +current-load).

A parameter that controls whether [ and ] +are treated as parentheses. See Reading Pairs and Lists for more +information.

A parameter that controls whether { and } +are treated as parentheses. See Reading Pairs and Lists for more +information.

A parameter that controls whether [ and ] +are treated as parentheses, but the resulting list tagged with +#%brackets. See Reading Pairs and Lists for more information.

Added in version 6.3.0.5 of package base.

A parameter that controls whether { and +} are treated as parentheses, but the resulting list +tagged with #%braces. See Reading Pairs and Lists for more +information.

Added in version 6.3.0.5 of package base.

parameter

(read-accept-box)  boolean?

(read-accept-box on?)  void?
  on? : any/c
A parameter that controls parsing #& input. See +Reading Boxes for more information.

parameter

(read-accept-compiled)  boolean?

(read-accept-compiled on?)  void?
  on? : any/c
A parameter that controls parsing #~ compiled input. See +The Reader and current-compile for more +information.

parameter

(read-accept-bar-quote)  boolean?

(read-accept-bar-quote on?)  void?
  on? : any/c
A parameter that controls parsing and printing of | in +symbols. See Reading Symbols and The Printer for +more information.

parameter

(read-accept-graph)  boolean?

(read-accept-graph on?)  void?
  on? : any/c
A parameter value that controls parsing input with sharing in +read mode. See Reading Graph Structure for more information.

parameter

(read-syntax-accept-graph)  boolean?

(read-syntax-accept-graph on?)  void?
  on? : any/c
A parameter value that controls parsing input with sharing in +read-syntax mode. See Reading Graph Structure for more information.

Added in version 8.4.0.8 of package base.

parameter

(read-decimal-as-inexact)  boolean?

(read-decimal-as-inexact on?)  void?
  on? : any/c
A parameter that controls parsing input numbers with a decimal point +or exponent (but no explicit exactness tag). See +Reading Numbers for more information.

parameter

(read-single-flonum)  boolean?

(read-single-flonum on?)  void?
  on? : any/c
A parameter that controls parsing input numbers that have a +f, F, s, or S precision +character. See Reading Numbers for more information.

Added in version 7.3.0.5 of package base.

parameter

(read-accept-dot)  boolean?

(read-accept-dot on?)  void?
  on? : any/c
A parameter that controls parsing input with a dot, which is normally +used for literal cons cells. See Reading Pairs and Lists for more +information.

parameter

(read-accept-infix-dot)  boolean?

(read-accept-infix-dot on?)  void?
  on? : any/c
A parameter that controls parsing input with two dots to trigger infix + conversion. See Reading Pairs and Lists for more information.

parameter

(read-cdot)  boolean?

(read-cdot on?)  void?
  on? : any/c
A parameter that controls parsing input with a dot, in a C +structure accessor style. See Reading with C-style Infix-Dot Notation for more +information.

Added in version 6.3.0.5 of package base.

parameter

(read-accept-quasiquote)  boolean?

(read-accept-quasiquote on?)  void?
  on? : any/c
A parameter that controls parsing input with ` or +, which is normally used for quasiquote, +unquote, and unquote-splicing abbreviations. See +Reading Quotes for more information.

parameter

(read-accept-reader)  boolean?

(read-accept-reader on?)  void?
  on? : any/c
A parameter that controls whether #reader, #lang, +or #! are allowed for selecting a parser. See +Reading via an Extension for more information.

parameter

(read-accept-lang)  boolean?

(read-accept-lang on?)  void?
  on? : any/c
A parameter that (along with read-accept-reader) controls +whether #lang and #! are allowed for selecting a +parser. See Reading via an Extension for more information.

parameter

(current-readtable)  (or/c readtable? #f)

(current-readtable readtable)  void?
  readtable : (or/c readtable? #f)
A parameter whose value determines a readtable that +adjusts the parsing of S-expression input, where #f implies the +default behavior. See Readtables for more information.

procedure

(call-with-default-reading-parameterization thunk)  any

  thunk : (-> any)
Calls thunk in tail position of a parameterize +to set all reader parameters above to their default values.

Using the default parameter values ensures consistency, and it also +provides safety when reading from untrusted sources, since the default +values disable evaluation of arbitrary code via #lang or +#reader.

parameter

(current-reader-guard)  (any/c . -> . any)

(current-reader-guard proc)  void?
  proc : (any/c . -> . any)
A parameter whose value converts or rejects (by raising an exception) +a module-path datum following #reader. See +Reading via an Extension for more information.

parameter

(read-on-demand-source)

  (or/c #f #t (and/c path? complete-path?))
(read-on-demand-source mode)  void?
  mode : (or/c #f #t (and/c path? complete-path?))
A parameter that enables lazy parsing of compiled code, so that +closure bodies and syntax objects are extracted (and validated) from +marshaled compiled code on demand. Normally, this parameter is set by +the default load handler when load-on-demand-enabled +is #t.

A #f value for read-on-demand-source disables lazy +parsing of compiled code. A #t value enables lazy parsing. A +path value furthers enable lazy retrieval from disk—instead +of keeping unparsed compiled code in memory—when the +PLT_DELAY_FROM_ZO environment variable is set (to +any value) on start-up.

If the file at mode as a path changes before the +delayed code is parsed when lazy retrieval from disk is enabled, then +the on-demand parse most likely will encounter garbage, leading to an +exception.

procedure

(port-read-handler in)  
(case->
 (input-port? . -> . any)
 (input-port?  any/c . -> . any))
  in : input-port?
(port-read-handler in proc)  void?
  in : input-port?
  proc : 
(case->
 (input-port? . -> . any)
 (input-port? any/c . -> . any))
Gets or sets the port read handler for in. The +handler called to read from the port when the built-in read +or read-syntax procedure is applied to the port. (The +port read handler is not used for read/recursive or +read-syntax/recursive.)

A port read handler is applied to either one argument or two +arguments:

  • A single argument is supplied when the port is used +with read; the argument is the port being read. The return +value is the value that was read from the port (or end-of-file).

  • Two arguments are supplied when the port is used with +read-syntax; the first argument is the port being read, and +the second argument is a value indicating the source. The return +value is a syntax object that was read from the port (or end-of-file).

The default port read handler reads standard Racket expressions with +Racket’s built-in parser (see The Reader). It handles a +special result from a custom input port (see +make-input-port) by treating it as a single expression, +except that special-comment values (see +Special Comments) are treated as whitespace.

The default port read handler itself can be customized through a +readtable; see Readtables for more information.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Sandboxed_Evaluation.html b/clones/docs.racket-lang.org/reference/Sandboxed_Evaluation.html new file mode 100644 index 00000000..403b9bed --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Sandboxed_Evaluation.html @@ -0,0 +1,511 @@ + +14.12 Sandboxed Evaluation

14.12 Sandboxed Evaluation

The bindings documented in this section are provided by the racket/sandbox library, not racket/base or racket.

The racket/sandbox module provides utilities for +creating “sandboxed” evaluators, which are configured in a +particular way and can have restricted resources (memory and time), +filesystem and network access, and much more. Sandboxed evaluators can be +configured through numerous parameters — and the defaults are set +for the common use case where sandboxes are very limited.

procedure

(make-evaluator 
  language 
  input-program ... 
  [#:requires requires 
  #:allow-for-require allow-for-require 
  #:allow-for-load allow-for-load 
  #:allow-read allow-read 
  #:allow-syntactic-requires allow-syntactic-requires]) 
  (any/c . -> . any)
  language : 
(or/c module-path?
      (list/c 'special symbol?)
      (cons/c 'begin list?))
  input-program : any/c
  requires : 
(listof (or/c module-path? path-string?
              (cons/c 'for-syntax (listof module-path?))))
   = null
  allow-for-require : (listof (or/c module-path? path?)) = null
  allow-for-load : (listof path-string?) = null
  allow-read : (listof (or/c module-path? path-string?)) = null
  allow-syntactic-requires : (or/c #f (listof module-path?))
   = #f
(make-module-evaluator 
  module-decl 
  [#:language lang 
  #:readers readers 
  #:allow-for-require allow-for-require 
  #:allow-for-load allow-for-load 
  #:allow-read allow-read 
  #:allow-syntactic-requires allow-syntactic-requires]) 
  (any/c . -> . any)
  module-decl : (or/c syntax? pair? path? input-port? string? bytes?)
  lang : (or/c #f module-path?) = #f
  readers : (or/c #f (listof module-path?))
   = (and lang (default-language-readers lang))
  allow-for-require : (listof (or/c module-path? path?)) = null
  allow-for-load : (listof path-string?) = null
  allow-read : (listof (or/c module-path? path-string?)) = null
  allow-syntactic-requires : (or/c #f (listof module-path?))
   = #f
The make-evaluator function creates an evaluator with a +language and requires specification, and starts +evaluating the given input-programs. The +make-module-evaluator function creates an evaluator that +works in the context of a given module. The result in either case is a +function for further evaluation.

The returned evaluator operates in an isolated and limited +environment. In particular, filesystem access is restricted, which may +interfere with using modules from the filesystem that are not +in a collection. See below for +information on the allow-for-require, +allow-for-load, and allow-read arguments; collection-based +module files typically do not need to be included in those lists. When +language is a module path or when requires is +provided, the indicated modules are implicitly included in the +allow-for-require list. When allow-syntactic-requires +is not #f, it constraints the set of modules that can be directly +referenced in a module; see below for more information. +(For backward compatibility, +non-module-path? path strings are allowed in arguments like +requires; they are implicitly converted to paths before +addition to allow-for-require.)

Each input-program or module-decl argument provides +a program in one of the following forms:

  • an input port used to read the program;

  • a string or a byte string holding the complete input;

  • a path that names a file holding the input; or

  • an S-expression or a syntax object, which is evaluated +as with eval (see also +get-uncovered-expressions).

In the first three cases above, the program is read using +sandbox-reader, with line-counting enabled for sensible error +messages, and with 'program as the source (used for testing +coverage). In the last case, the input is expected to be the complete +program, and is converted to a syntax object (using +'program as the source), unless it already is a syntax +object.

The returned evaluator function accepts additional expressions +(each time it is called) in essentially the same form: a string or +byte string holding a sequence of expressions, a path for a file +holding expressions, an S-expression, or a syntax object. If +the evaluator receives an eof value, it is terminated and +raises errors thereafter. See also kill-evaluator, which +terminates the evaluator without raising an exception.

For make-evaluator, multiple input-programs are +effectively concatenated to form a single program. The way that the +input-programs are evaluated depends on the language +argument:

  • The language argument can be a module path (i.e., a +datum that matches the grammar for module-path of +require).

    In this case, the input-programs are automatically +wrapped in a module, and the resulting evaluator works +within the resulting module’s namespace.

  • The language argument can be a list starting with +'special, which indicates a built-in language with +special input configuration. The possible values are +'(special r5rs) or a value indicating a teaching +language: '(special beginner), '(special beginner-abbr), '(special intermediate), +'(special intermediate-lambda), or '(special advanced).

    In this case, the input-programs are automatically +wrapped in a module, and the resulting evaluator works +within the resulting module’s namespace. In addition, certain +parameters (such as such as read-accept-infix-dot) are +set to customize reading programs from strings and ports.

    This option is provided mainly for older test systems. Using +make-module-evaluator with input starting with +#lang is generally better.

  • Finally, language can be a list whose first element is +'begin.

    In this case, a new namespace is created using +sandbox-namespace-specs, which by default creates a +new namespace using sandbox-make-namespace (which, in +turn, uses make-base-namespace or +make-gui-namespace depending on +sandbox-gui-available and gui-available?).

    In the new namespace, language is evaluated as an +expression to further initialize the namespace.

The requires list adds additional imports to the module or +namespace for the input-programs, even in the case that +require is not made available through the language. +The allow-syntactic-requires argument, if non-#f, +constrains require references expanded in the module when the +language argument implies a module wrapper; more +precisely, it constrains the module paths that can be resolved when a +syntax object is provided to the module name resolver, which +will include require forms that are created by macro +expansion. A relative-submodule path using submod followed by +either "." or ".." is always allowed.

The following examples illustrate the difference between an evaluator +that puts the program in a module and one that merely initializes a +top-level namespace:

> (define base-module-eval
    ; a module cannot have free variables...
    (make-evaluator 'racket/base '(define (f) later)))

program:1:0: later: unbound identifier

  in: later

> (define base-module-eval
    (make-evaluator 'racket/base '(define (f) later)
                                 '(define later 5)))
> (base-module-eval '(f))

5

> (define base-top-eval
    ; non-module code can have free variables:
    (make-evaluator '(begin) '(define (f) later)))
> (base-top-eval '(+ 1 2))

3

> (base-top-eval '(define later 5))
> (base-top-eval '(f))

5

The make-module-evaluator function is essentially a +restriction of make-evaluator, where the program must be a +module, and all imports are part of the program. In some cases it is +useful to restrict the program to be a module using a specific module +in its language position; use the optional lang argument +to specify such a restriction, where #f means that no +restriction is enforced. The readers argument similarly +constrains the paths that can follow #lang or #reader +if it is not #f, and the default is based on lang. +The allow-syntactic-requires argument is treated the same as +for make-evaluator in the module-wrapper case.

When the program is specified as a path, then +the path is implicitly added to the allow-for-load list.

(define base-module-eval2
  ; equivalent to base-module-eval:
  (make-module-evaluator '(module m racket/base
                            (define (f) later)
                            (define later 5))))

The make-module-evaluator function can be convenient for testing +module files: pass in a path value for the file +name, and you get back an evaluator in the module’s context which you +can use with your favorite test facility.

In all cases, the evaluator operates in an isolated and limited +environment: +
Note that these limits apply to the creation of the sandbox +environment too — so, for example, if the memory that is required to +create the sandbox is higher than the limit, then +make-evaluator will fail with a memory limit exception.

The allow-for-require and allow-for-load arguments +adjust filesystem permissions to extend the set of files that +are usable by the evaluator. Modules that are in a collection +are automatically accessible, but the allow-for-require argument lists +additional modules that can be required along with their imports +(transitively) through a filesystem path. The allow-for-load argument +similarly lists files that can +be loaded. (The precise permissions needed for +require versus load can differ.) The +allow-read argument is for backward compatibility, only; each +module-path? element of allow-read is effectively +moved to allow-for-require, while other elements are moved to +allow-for-load.

The sandboxed environment is well isolated, and the evaluator function +essentially sends it an expression and waits for a result. This form +of communication makes it impossible to have nested (or concurrent) +calls to a single evaluator. Usually this is not a problem, but in +some cases you can get the evaluator function available inside the +sandboxed code, for example: +
> (let ([e (make-evaluator 'racket/base)])
    (e `(,e 1)))

evaluator: nested evaluator call with: 1

An error will be signaled in such cases.

If the value of sandbox-propagate-exceptions is true (the +default) when the sandbox is created, then exceptions (both syntax and +run-time) are propagated as usual to the caller of the evaluation +function (i.e., catch them with with-handlers). See below +for a caveat about using raised exceptions directly. If the value +of sandbox-propagate-exceptions is #f when the +sandbox is created, then uncaught exceptions in a sandbox evaluation +cause the error to be printed to the sandbox’s error port, and the +caller of the evaluation receives #<void>.

Take care when using a value returned from a sandbox or raised as an +exception by a sandbox. The value might by an impersonator, or it +might be a structure whose structure type redirects equality +comparisons or printing operations. To safely handle an unknown value +produced by a sandbox, manipulate it within the sandbox, possibly +using call-in-sandbox-context.

An evaluator can be used only by one thread at a time, and detected +concurrent use triggers an exception. Beware of using an evaluator in +a non-main thread, because the default value of +sandbox-make-plumber registers a callback in the current +plumber to flush the evaluator’s plumber, and that means a flush of +the current plumber (such as when the Racket process is about to exit) +implies a use of the evaluator.

Changed in version 1.2 of package sandbox-lib: Added the #:readers and +#:allow-syntactic-require arguments.

A predicate and accessor for exceptions that are raised when a sandbox +is terminated. Once a sandbox raises such an exception, it will +continue to raise it on further evaluation attempts.

14.12.1 Security Considerations

Although the sandbox is designed to provide a safe environment for executing +Racket programs with restricted access to system resources, executing untrusted +programs in a sandbox still carries some risk. Because a malicious program can +exercise arbitrary functionality from the Racket runtime and installed collections, +an attacker who identifies a vulnerability in Racket or an installed collection +may be able to escape the sandbox.

To mitigate this risk, programs that use the sandbox should employ additional +precautions when possible. Suggested measures include: +
  • Supplying a custom module language to make-evaluator or +make-module-evaluator that gives untrusted code access to only +the language constructs it absolutely requires.

  • If untrusted code needs access to installed collections, installing only +the collections required by your program.

  • Using operating-system-level security features to provide defense-in-depth +in case the process running the sandbox is compromised.

  • Making sure your Racket installation and installed packages are up-to-date +with the latest release.

14.12.2 Customizing Evaluators

The sandboxed evaluators that make-evaluator creates can be +customized via many parameters. Most of the configuration parameters +affect newly created evaluators; changing them has no effect on +already-running evaluators.

The default configuration options are set for a very restricted +sandboxed environment — one that is safe to make publicly available. +Further customizations might be needed in case more privileges are +needed, or if you want tighter restrictions. Another useful approach +for customizing an evaluator is to begin with a relatively +unrestricted configuration and add the desired restrictions. This approach is made +possible by the call-with-trusted-sandbox-configuration +function.

The sandbox environment uses two notions of restricting the time that +evaluations takes: shallow time and deep +time. Shallow time refers to the immediate execution of an +expression. For example, a shallow time limit of five seconds +would restrict (sleep 6) and other computations that take +longer than five seconds. Deep time refers to the total +execution of the expression and all threads and sub-processes that the +expression creates. For example, a deep time limit of five +seconds would restrict (thread (λ () (sleep 6))), which +shallow time would not, as well as all expressions that +shallow time would restrict. By default, most sandboxes only +restrict shallow time to facilitate expressions that use +threads.

procedure

(call-with-trusted-sandbox-configuration thunk)  any

  thunk : (-> any)
Invokes the thunk in a context where sandbox configuration +parameters are set for minimal restrictions. More specifically, there +are no memory or time limits, and the existing existing inspectors, +security guard, exit handler, logger, plumber, and +environment variable set are used. (Note that the I/O +ports settings are not included.)

parameter

(sandbox-init-hook)  (-> any)

(sandbox-init-hook thunk)  void?
  thunk : (-> any)
A parameter that determines a thunk to be called for initializing a +new evaluator. The hook is called just before the program is +evaluated in a newly-created evaluator context. It can be used to +setup environment parameters related to reading, writing, evaluation, +and so on. Certain languages ('(special r5rs) and the +teaching languages) have initializations specific to the language; the +hook is used after that initialization, so it can override settings.

parameter

(sandbox-reader)  (any/c . -> . any)

(sandbox-reader proc)  void?
  proc : (any/c . -> . any)
A parameter that specifies a function that reads all expressions from +(current-input-port). The function is used to read program +source for an evaluator when a string, byte string, or port is +supplied. The reader function receives a value to be used as input +source (i.e., the first argument to read-syntax), and it +should return a list of syntax objects. The default reader +calls read-syntax, accumulating results in a list until it +receives eof.

Note that the reader function is usually called as is, but when it is +used to read the program input for make-module-evaluator, +read-accept-lang and read-accept-reader are set to +#t.

parameter

(sandbox-input)  
(or/c #f
      string? bytes?
      input-port?
      'pipe
      (-> input-port?))
(sandbox-input in)  void?
  in : 
(or/c #f
      string? bytes?
      input-port?
      'pipe
      (-> input-port?))
A parameter that determines the initial current-input-port +setting for a newly created evaluator. It defaults to #f, +which creates an empty port. The following other values are allowed:

  • a string or byte string, which is converted to a port using +open-input-string or open-input-bytes;

  • an input port;

  • the symbol 'pipe, which triggers the creation of a +pipe, where put-input can return the output end of the +pipe or write directly to it;

  • a thunk, which is called to obtain a port (e.g., using +current-input-port means that the evaluator input is +the same as the calling context’s input).

parameter

(sandbox-output)  
(or/c #f
      output-port?
      'pipe
      'bytes
      'string
      (-> output-port?))
(sandbox-output in)  void?
  in : 
(or/c #f
      output-port?
      'pipe
      'bytes
      'string
      (-> output-port?))
A parameter that determines the initial current-output-port +setting for a newly created evaluator. It defaults to #f, +which creates a port that discards all data. The following other +values are allowed:

  • an output port, which is used as-is;

  • the symbol 'bytes, which causes get-output to +return the complete output as a byte string as long as the +evaluator has not yet terminated (so that the size of the bytes +can be charged to the evaluator);

  • the symbol 'string, which is similar to +'bytes, but makes get-output produce a +string;

  • the symbol 'pipe, which triggers the creation of a +pipe, where get-output returns the input end of the +pipe;

  • a thunk, which is called to obtain a port (e.g., using +current-output-port means that the evaluator output is +not diverted).

parameter

(sandbox-error-output)  
(or/c #f
      output-port?
      'pipe
      'bytes
      'string
      (-> output-port?))
(sandbox-error-output in)  void?
  in : 
(or/c #f
      output-port?
      'pipe
      'bytes
      'string
      (-> output-port?))
Like sandbox-output, but for the initial +current-error-port value. An evaluator’s error output is set +after its output, so using current-output-port (the parameter +itself, not its value) for this parameter value means that the error +port is the same as the evaluator’s initial output port.

The default is (lambda () (dup-output-port (current-error-port))), which means that the error output of the +generated evaluator goes to the calling context’s error port.

parameter

(sandbox-coverage-enabled)  boolean?

(sandbox-coverage-enabled enabled?)  void?
  enabled? : any/c
A parameter that controls whether syntactic coverage information is +collected by sandbox evaluators. Use +get-uncovered-expressions to retrieve coverage information.

The default value is #f.

parameter

(sandbox-propagate-breaks)  boolean?

(sandbox-propagate-breaks propagate?)  void?
  propagate? : any/c
When both this boolean parameter and (break-enabled) are true, +breaking while an evaluator is +running propagates the break signal to the sandboxed +context. This makes the sandboxed evaluator break, typically, but +beware that sandboxed evaluation can capture and avoid the breaks (so +if safe execution of code is your goal, make sure you use it with a +time limit). Also, beware that a break may be received after the +evaluator’s result, in which case the evaluation result is lost. Finally, +beware that a break may be propagated after an evaluator has produced +a result, so that the break is visible on the next interaction with +the evaluator (or the break is lost if the evaluator is not used +further). The default is #t.

parameter

(sandbox-propagate-exceptions)  boolean?

(sandbox-propagate-exceptions propagate?)  void?
  propagate? : any/c
A parameter that controls how uncaught exceptions during a sandbox +evaluation are treated. When the parameter value is #t, +then the exception is propagated to the caller of sandbox. +When the parameter value is #f, the exception message +is printed to the sandbox’s error port, and the caller of the +sandbox receives #<void> for the evaluation. The default +is #t.

parameter

(sandbox-namespace-specs)  
(cons/c (-> namespace?)
        (listof module-path?))
(sandbox-namespace-specs spec)  void?
  spec : 
(cons/c (-> namespace?)
        (listof module-path?))
A parameter that holds a list of values that specify how to create a +namespace for evaluation in make-evaluator or +make-module-evaluator. The first item in the list is a thunk +that creates the namespace, and the rest are module paths for modules +to be attached to the created namespace using +namespace-attach-module.

The default is (list sandbox-make-namespace).

The module paths are needed for sharing module instantiations between +the sandbox and the caller. For example, sandbox code that returns +posn values (from the lang/posn module) will +not be recognized as such by your own code by default, since the +sandbox will have its own instance of lang/posn and +thus its own struct type for posns. To be able to use such +values, include 'lang/posn in the list of module paths.

When testing code that uses a teaching language, the following piece +of code can be helpful:

(sandbox-namespace-specs
 (let ([specs (sandbox-namespace-specs)])
   `(,(car specs)
     ,@(cdr specs)
     lang/posn
     ,@(if (gui-available?) '(mrlib/cache-image-snip) '()))))

Calls make-gui-namespace when (sandbox-gui-available) +produces true, make-base-namespace otherwise.

parameter

(sandbox-gui-available)  boolean?

(sandbox-gui-available avail?)  void?
  avail? : any/c
Determines whether the racket/gui module can be used +when a sandbox evaluator is created. If gui-available? +produces #f during the creation of a sandbox evaluator, this +parameter is forced to #f during initialization of the +sandbox. The default value of the parameter is #t.

Various aspects of the library change when the GUI library is +available, such as using a new eventspace for each evaluator.

A parameter that determines a list of collection directories to prefix +current-library-collection-paths in an evaluator. This +parameter is useful for cases when you want to test code using an +alternate, test-friendly version of a collection, for example, testing +code that uses a GUI (like the htdp/world teachpack) can be +done using a fake library that provides the same interface but no +actual interaction. The default is null.

A parameter that determines the initial +(current-security-guard) for sandboxed evaluations. It can +be either a security guard, or a function to construct one. The +default is a function that restricts the access of the current +security guard by forbidding all filesystem I/O except for +specifications in sandbox-path-permissions, and it uses +sandbox-network-guard for network connections.

parameter

(sandbox-path-permissions)

  
(listof (list/c (or/c 'execute 'write 'delete
                      'read-bytecode 'read 'exists)
                (or/c byte-regexp? bytes? string? path?)))
(sandbox-path-permissions perms)  void?
  perms : 
(listof (list/c (or/c 'execute 'write 'delete
                      'read-bytecode 'read 'exists)
                (or/c byte-regexp? bytes? string? path?)))
A parameter that configures the behavior of the default sandbox +security guard by listing paths and access modes that are allowed for +them. The contents of this parameter is a list of specifications, +each is an access mode and a byte-regexp for paths that are granted this +access.

The access mode symbol is one of: 'execute, 'write, +'delete, 'read, or 'exists. These symbols +are in decreasing order: each implies access for the following modes +too (e.g., 'read allows reading or checking for existence).

The path regexp is used to identify paths that are granted access. It +can also be given as a path (or a string or a byte string), which is +(made into a complete path, cleansed, simplified, and then) converted +to a regexp that allows the path and sub-directories; e.g., +"/foo/bar" applies to "/foo/bar/baz".

An additional mode symbol, 'read-bytecode, is not part of the +linear order of these modes. Specifying this mode is similar to +specifying 'read, but it is not implied by any other mode. +(For example, even if you specify 'write for a certain path, +you need to also specify 'read-bytecode to grant this +permission.) The sandbox usually works in the context of a lower code +inspector (see sandbox-make-code-inspector) which prevents +loading of untrusted bytecode files — the sandbox is set-up to allow +loading bytecode from files that are specified with +'read-bytecode. This specification is given by default to +the Racket collection hierarchy (including user-specific libraries) and +to libraries that are explicitly specified in an #:allow-read +argument. (Note that this applies for loading bytecode files only, +under a lower code inspector it is still impossible to use protected +module bindings (see Code Inspectors).)

The default value is null, but when an evaluator is created, it is +augmented by 'read-bytecode permissions that make it possible +to use collection libraries (including +sandbox-override-collection-paths). See +make-evaluator for more information.

parameter

(sandbox-network-guard)

  
(symbol?
 (or/c (and/c string? immutable?) #f)
 (or/c (integer-in 1 65535) #f)
 (or/c 'server 'client)
 . -> . any)
(sandbox-network-guard proc)  void?
  proc : 
(symbol?
 (or/c (and/c string? immutable?) #f)
 (or/c (integer-in 1 65535) #f)
 (or/c 'server 'client)
 . -> . any)
A parameter that specifies a procedure to be used (as is) by the +default sandbox-security-guard. The default forbids all +network connection.

parameter

(sandbox-exit-handler)  (any/c . -> . any)

(sandbox-exit-handler handler)  void?
  handler : (any/c . -> . any)
A parameter that determines the initial (exit-handler) for +sandboxed evaluations. The default kills the evaluator with an +appropriate error message (see +exn:fail:sandbox-terminated-reason).

parameter

(sandbox-memory-limit)  (or/c (>=/c 0) #f)

(sandbox-memory-limit limit)  void?
  limit : (or/c (>=/c 0) #f)
A parameter that determines the total memory limit on the sandbox in +megabytes (it can hold a rational or a floating point number). When +this limit is exceeded, the sandbox is terminated. This value is used +when the sandbox is created and the limit cannot be changed +afterwards. It defaults to 30mb. See sandbox-eval-limits +for per-evaluation limits and a description of how the two limits work +together.

Note that (when memory accounting is enabled) memory is attributed to +the highest custodian that refers to it. This means that if you +inspect a value that sandboxed evaluation returns outside of the +sandbox, your own custodian will be charged for it. To ensure that it +is charged back to the sandbox, you should remove references to such +values when the code is done inspecting it.

This policy has an impact on how the sandbox memory limit interacts +with the per-expression limit specified by +sandbox-eval-limits: values that are reachable from the +sandbox, as well as from the interaction will count against the +sandbox limit. For example, in the last interaction of this code, +
(define e (make-evaluator 'racket/base))
(e '(define a 1))
(e '(for ([i (in-range 20)]) (set! a (cons (make-bytes 500000) a))))
the memory blocks are allocated within the interaction limit, but +since they’re chained to the defined variable, they’re also reachable +from the sandbox — so they will count against the sandbox memory +limit but not against the interaction limit (more precisely, no more +than one block counts against the interaction limit).

parameter

(sandbox-eval-limits)  
(or/c (list/c (or/c (>=/c 0) #f)
              (or/c (>=/c 0) #f))
      #f)
(sandbox-eval-limits limits)  void?
  limits : 
(or/c (list/c (or/c (>=/c 0) #f)
              (or/c (>=/c 0) #f))
      #f)
A parameter that determines the default limits on each +use of a make-evaluator function, including the initial +evaluation of the input program. Its value should be a list of two +numbers; where the first is a shallow time value in seconds, +and the second is a memory limit in megabytes (note that they don’t +have to be integers). Either one can be #f for disabling the +corresponding limit; alternately, the parameter can be set to +#f to disable all per-evaluation limits (useful in case more +limit kinds are available in future versions). The default is +(list 30 20).

Note that these limits apply to the creation of the sandbox +environment too — even (make-evaluator 'racket/base) can +fail if the limits are strict enough. For example, +
(parameterize ([sandbox-eval-limits '(0.25 5)])
  (make-evaluator 'racket/base '(sleep 2)))
will throw an error instead of creating an evaluator. Therefore, to +avoid surprises you need to catch errors that happen when the sandbox +is created.

When limits are set, call-with-limits (see below) is wrapped +around each use of the evaluator, so consuming too much time or memory +results in an exception. Change the limits of a running evaluator +using set-eval-limits.

A custodian’s limit is checked only after a garbage +collection, except that it may also be checked during +certain large allocations that are individually larger +than the custodian’s limit.

The memory limit that is specified by this parameter applies to each +individual evaluation, but not to the whole sandbox — that limit is +specified via sandbox-memory-limit. When the global limit is +exceeded, the sandbox is terminated, but when the per-evaluation limit +is exceeded, an exception recognizable by exn:fail:resource? is raised. For example, say that +you evaluate an expression like +
(for ([i (in-range 1000)])
  (set! a (cons (make-bytes 1000000) a))
  (collect-garbage))
then, assuming sufficiently small limits, +
  • if a global limit is set but no per-evaluation limit, the +sandbox will eventually be terminated and no further +evaluations possible;

  • if there is a per-evaluation limit, but no global limit, the +evaluation will abort with an error and it can be used again +— specifically, a will still hold a number of +blocks, and you can evaluate the same expression again which +will add more blocks to it;

  • if both limits are set, with the global one larger than the +per-evaluation limit, then the evaluation will abort and you +will be able to repeat it, but doing so several times will +eventually terminate the sandbox (this will be indicated by +the error message, and by the evaluator-alive? +predicate).

parameter

(sandbox-eval-handlers)

  
(list/c (or/c #f ((-> any) . -> . any))
        (or/c #f ((-> any) . -> . any)))
(sandbox-eval-handlers handlers)  void?
  handlers : 
(list/c (or/c #f ((-> any) . -> . any))
        (or/c #f ((-> any) . -> . any)))
A parameter that determines two (optional) handlers that wrap +sandboxed evaluations. The first one is used when evaluating the +initial program when the sandbox is being set-up, and the second is +used for each interaction. Each of these handlers should expect a +thunk as an argument, and they should execute these thunks — +possibly imposing further restrictions. The default values are +#f and call-with-custodian-shutdown, meaning no +additional restrictions on initial sandbox code (e.g., it can start +background threads), and a custodian-shutdown around each interaction +that follows. Another useful function for this is +call-with-killing-threads which kills all threads, but leaves +other resources intact.

parameter

(sandbox-run-submodules)  (list/c symbol?)

(sandbox-run-submodules submod-syms)  void?
  submod-syms : (list/c symbol?)
A parameter that determines submodules to run when a sandbox is +created by make-module-evaluator. The parameter’s default +value is the empty list.

parameter

(sandbox-make-inspector)  (-> inspector?)

(sandbox-make-inspector make)  void?
  make : (-> inspector?)
A parameter that determines the (nullary) procedure that is used to +create the inspector for sandboxed evaluation. The procedure is called +when initializing an evaluator. The default parameter value is +(lambda () (make-inspector (current-inspector))).

A parameter that determines the (nullary) procedure that is used to +create the code inspector for sandboxed evaluation. The procedure is +called when initializing an evaluator. The default parameter value is +(lambda () (make-inspector (current-code-inspector))).

The current-load/use-compiled handler is setup to allow loading +of bytecode files under the original code inspector when +sandbox-path-permissions allows it through a +'read-bytecode mode symbol, which makes loading libraries +possible.

parameter

(sandbox-make-logger)  (-> logger?)

(sandbox-make-logger make)  void?
  make : (-> logger?)
A parameter that determines the procedure used to create the logger +for sandboxed evaluation. The procedure is called when initializing +an evaluator, and the default parameter value is +current-logger. This means that it is not creating a new +logger (this might change in the future).

parameter

(sandbox-make-plumber)  (or/c (-> plumber?) 'propagate)

(sandbox-make-plumber make)  void?
  make : (or/c (-> plumber?) 'propagate)
A parameter that determines the procedure used to create the +plumber for sandboxed evaluation. The procedure is called when +initializing an evaluator.

If the value is 'propagate (the default), then a new plumber +is created, and a flush callback is added to the current +plumber to propagate the request to the new plumber within the created +sandbox (if the sandbox has not already terminated).

Added in version 6.0.1.8 of package sandbox-lib.

A parameter that determines the procedure used to create the +environment variable set for sandboxed evaluation. The +procedure is called when initializing an evaluator, and the default +parameter value constructs a new environment variable set using +(environment-variables-copy (current-environment-variables)).

procedure

(default-language-readers lang)  (listof module-path?)

  lang : module-path?
Creates a default list of readers that should be allowed to produce a +module that uses lang as the language.

This default list includes the following (and more paths may be added +in the future):

  • `(submod ,lang reader)

  • lang/lang/reader if lang is a symbol

  • the module path producing by adding the relative path "lang/reader.rkt" +to lang if lang is not a symbol

  • '(submod at-exp reader)

  • 'at-exp/lang/reader

Added in version 1.2 of package sandbox-lib.

14.12.3 Interacting with Evaluators

The following functions are used to interact with a sandboxed +evaluator in addition to using it to evaluate code.

procedure

(evaluator-alive? evaluator)  boolean?

  evaluator : (any/c . -> . any)
Determines whether the evaluator is still alive.

procedure

(kill-evaluator evaluator)  void?

  evaluator : (any/c . -> . any)
Releases the resources that are held by evaluator by shutting +down the evaluator’s custodian. Attempting to use an evaluator after +killing raises an exception, and attempts to kill a dead evaluator are +ignored.

Killing an evaluator is similar to sending an eof value to +the evaluator, except that an eof value will raise an error +immediately.

procedure

(break-evaluator evaluator)  void?

  evaluator : (any/c . -> . any)
Sends a break to the running evaluator. The effect of this is as if +Ctrl-C was typed when the evaluator is currently executing, which +propagates the break to the evaluator’s context.

procedure

(get-user-custodian evaluator)  void?

  evaluator : (any/c . -> . any)
Retrieves the evaluator’s toplevel custodian. This returns a +value that is different from (evaluator '(current-custodian)) +or (call-in-sandbox-context evaluator current-custodian) each +sandbox interaction is wrapped in its own custodian, which is what these +would return.

(One use for this custodian is with current-memory-use, where +the per-interaction sub-custodians will not be charged with the memory +for the whole sandbox.)

procedure

(set-eval-limits evaluator secs mb)  void?

  evaluator : (any/c . -> . any)
  secs : (or/c exact-nonnegative-integer? #f)
  mb : (or/c exact-nonnegative-integer? #f)
Changes the per-expression limits that evaluator uses to +secs seconds of shallow time and mb +megabytes (either one can be #f, indicating no limit).

This procedure should be used to modify an existing evaluator limits, +because changing the sandbox-eval-limits parameter does not +affect existing evaluators. See also call-with-limits.

procedure

(set-eval-handler evaluator handler)  void?

  evaluator : (any/c . -> . any)
  handler : (or/c #f ((-> any) . -> . any))
Changes the per-expression handler that the evaluator uses +around each interaction. A #f value means no handler is +used.

This procedure should be used to modify an existing evaluator handler, +because changing the sandbox-eval-handlers parameter does not +affect existing evaluators. See also +call-with-custodian-shutdown and +call-with-killing-threads for two useful handlers that are +provided.

procedure

(call-with-custodian-shutdown thunk)  any

  thunk : (-> any)
(call-with-killing-threads thunk)  any
  thunk : (-> any)
These functions are useful for use as an evaluation handler. +call-with-custodian-shutdown will execute the thunk +in a fresh custodian, then shutdown that custodian, making sure that +thunk could not have left behind any resources. +call-with-killing-threads is similar, except that it kills +threads that were left, but leaves other resources as is.

procedure

(put-input evaluator)  output-port?

  evaluator : (any/c . -> . any)
(put-input evaluator i/o)  void?
  evaluator : (any/c . -> . any)
  i/o : (or/c bytes? string? eof-object?)
If (sandbox-input) is 'pipe when an evaluator is +created, then this procedure can be used to retrieve the output port +end of the pipe (when used with no arguments), or to add a string or a +byte string into the pipe. It can also be used with eof, +which closes the pipe.

procedure

(get-output evaluator)  (or/c #f input-port? bytes? string?)

  evaluator : (any/c . -> . any)
(get-error-output evaluator)
  (or/c #f input-port? bytes? string?)
  evaluator : (any/c . -> . any)
Returns the output or error-output of the evaluator, +in a way that depends on the setting of (sandbox-output) or +(sandbox-error-output) when the evaluator was created:

  • if it was 'pipe, then get-output returns the +input port end of the created pipe;

  • if it was 'bytes or 'string, then the result +is the accumulated output, and the output port is reset so each +call returns a different piece of the evaluator’s output (note +that results are available only until the evaluator has +terminated, and any allocations of the output are subject to +the sandbox memory limit);

  • otherwise, it returns #f.

procedure

(get-uncovered-expressions evaluator    
  [prog?    
  src])  (listof syntax?)
  evaluator : (any/c . -> . any)
  prog? : any/c = #t
  src : any/c = default-src
Retrieves uncovered expression from an evaluator, as longs as the +sandbox-coverage-enabled parameter had a true value when the +evaluator was created. Otherwise, an exception is raised to indicate +that no coverage information is available.

The prog? argument specifies whether to obtain expressions that +were uncovered after only the original input program was evaluated +(#t) or after all later uses of the evaluator (#f). +Using #t retrieves a list that is saved after the input +program is evaluated, and before the evaluator is used, so the result is +always the same.

A #t value of prog? is useful for testing student +programs to find out whether a submission has sufficient test coverage +built in. A #f value is useful for writing test suites for a +program to ensure that your tests cover the whole code.

The second optional argument, src, specifies that the result +should be filtered to hold only syntax objects whose source +matches src. The default is the source that was used in the +program code, if there was one. Note that 'program is used as +the source value if the input program was given as S-expressions or as a +string (and in these cases it will be the default for filtering). If given +#f, the result is the unfiltered list of expressions.

The resulting list of syntax objects has at most one expression +for each position and span. Thus, the contents may be unreliable, but +the position information is reliable (i.e., it always indicates source +code that would be painted red in DrRacket when coverage information +is used).

Note that if the input program is a sequence of syntax values, either +make sure that they have 'program as the source field, or use +the src argument. Using a sequence of S-expressions (not +syntax objects) for an input program leads to unreliable +coverage results, since each expression may be assigned a single +source location.

procedure

(call-in-sandbox-context evaluator    
  thunk    
  [unrestricted?])  any
  evaluator : (any/c . -> . any)
  thunk : (-> any)
  unrestricted? : boolean? = #f
Calls the given thunk in the context of a sandboxed +evaluator. The call is performed under the resource limits and +evaluation handler that are used for evaluating expressions, unless +unrestricted? is specified as true.

This process is usually similar to (evaluator (list thunk)), +except that it does not rely on the common meaning of a sexpr-based +syntax with list expressions as function application (which is not true +in all languages). Note that this is more useful for meta-level +operations such as namespace manipulation, it is not intended to be used +as a safe-evaluation replacement (i.e., using the sandbox evaluator as +usual).

In addition, you can avoid some of the sandboxed restrictions by using +your own permissions, for example, +
(let ([guard (current-security-guard)])
  (call-in-sandbox-context
    ev
    (lambda ()
      (parameterize ([current-security-guard guard])
        ; can access anything you want here
        (delete-file "/some/file")))))

14.12.4 Miscellaneous

value

gui? : boolean?

For backward compatibility, only: the result of gui-available? +at the time that racket/sandbox was instantiated.

The value of gui? is no longer used by +racket/sandbox itself. Instead, +gui-available? and sandbox-gui-available are +checked at the time that a sandbox evaluator is created.

procedure

(call-with-limits secs mb thunk)  any

  secs : (or/c exact-nonnegative-integer? #f)
  mb : (or/c exact-nonnegative-integer? #f)
  thunk : (-> any)
Executes the given thunk with memory and time restrictions: +if execution consumes more than mb megabytes or more than +secs shallow time seconds, then the computation is +aborted and an exception recognizable by exn:fail:resource? is raised. Otherwise, the result of +the thunk is returned as usual (a value, multiple values, or an +exception). Each of the two limits can be #f to indicate the +absence of a limit. See also custodian-limit-memory for +information on memory limits.

To enforce limits, thunk is run in a new thread. As usual, +the new thread starts with the same parameter values as the one that +calls call-with-limits. Not as usual, parameter values +from the thread used to run thunk are copied back to the +thread that called call-with-limits when thunk +completes.

Sandboxed evaluators use call-with-limits, according to the +sandbox-eval-limits setting and uses of +set-eval-limits: each expression evaluation is protected from +timeouts and memory problems. Use call-with-limits directly +only to limit a whole testing session, instead of each expression.

syntax

(with-limits sec-expr mb-expr body ...)

A macro version of call-with-limits.

procedure

(call-with-deep-time-limit secs thunk)  any

  secs : exact-nonnegative-integer?
  thunk : (-> any)
Executes the given thunk with deep time restrictions, +and returns the values produced by thunk.

The given thunk is run in a new thread. If it errors or if +the thread terminates returning a value, then (values) is +returned.

Changed in version 1.1 of package sandbox-lib: Changed to return thunk’s result +if it completes normally.

syntax

(with-deep-time-limit secs-expr body ...)

A macro version of call-with-deep-time-limit.

procedure

(exn:fail:resource? v)  boolean?

  v : any/c
(exn:fail:resource-resource exn)
  (or/c 'time 'memory 'deep-time)
  exn : exn:fail:resource?
A predicate and accessor for exceptions that are raised by +call-with-limits. The resource field holds a +symbol, representing the resource that was expended. 'time is +used for shallow time and 'deep-time is used for +deep time.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Serializing_Syntax.html b/clones/docs.racket-lang.org/reference/Serializing_Syntax.html new file mode 100644 index 00000000..5847692b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Serializing_Syntax.html @@ -0,0 +1,41 @@ + +12.10 Serializing Syntax

12.10 Serializing Syntax

procedure

(syntax-serialize 
  stx 
  #:preserve-property-keys preserve-property-keys 
  [#:provides-namespace provides-namespace 
  #:base-module-path-index base-module-path-index]) 
  any/c
  stx : syntax?
  preserve-property-keys : (listof symbol?)
  provides-namespace : (or/c namespace? #f)
   = (current-namespace)
  base-module-path-index : (or/c module-path-index? #f) = #f
Converts stx to a serialized form that is suitable for use +with s-exp->fasl or serialize. Although stx +could be serialized with (compile `(quote-syntax ,stx)) and +then writing the compiled form, syntax-serialize provides +more control over serialization:

  • The preserve-property-keys lists syntax-property keys +to whose values should be preserved in serialization, even if +the property value was not added as preserved with +syntax-property (so it would be discarded in compiled +form). The values associated with the properties to preserve +must be serializable in the sense required by +syntax-property for a preserved property.

  • The provides-namespace argument constrains how much +the serialized syntax object can rely on bulk +bindings, which are shared binding tables provided by +exporting modules. If provides-namespace is +#f, then complete binding information is recorded in +the syntax object’s serialized form, and no bulk bindings will +be needed from the namespace at deserialization. Otherwise, +bulk bindings will be used only for modules declared in +provides-namespace (i.e., the deserialize-time +namespace will have the same module declarations as +provides-namespace); note that supplying a namespace +with no module bindings is equivalent to supplying +#f.

  • The base-module-path-index argument specifies a +module path index to which binding information in +stx is relative. For example, if a syntax object +originates from quote-syntax in the body of a module, +then base-module-path-index could usefully be the +enclosing module’s module path index as produced by +(variable-reference->module-path-index (#%variable-reference)) within the module. On deserialization, +a different module path index can be supplied to substitute in +place of base-module-path-index, which shifts any +binding that is relative to the serialize-time module’s +identity to be relative to the module identity supplied at +deserialize time. If base-module-path-index is +#f, then no shifting is supported at deserialize time, +and any base-module-path-index supplied at that time +is ignored.

A serialized syntax object is otherwise similar to compiled code: it +is version-specific, and deserialization will require a sufficiently +powerful code inspector.

Added in version 8.0.0.13 of package base.

procedure

(syntax-deserialize 
  v 
  [#:base-module-path-index base-module-path-index]) 
  syntax?
  v : any/c
  base-module-path-index : (or/c module-path-index? #f) = #f
Converts the result of syntax-serialize back to a syntax +object. See syntax-serialize for more information.

Added in version 8.0.0.13 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Single-Signature_Modules.html b/clones/docs.racket-lang.org/reference/Single-Signature_Modules.html new file mode 100644 index 00000000..1ded975b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Single-Signature_Modules.html @@ -0,0 +1,15 @@ + +7.11 Single-Signature Modules

7.11 Single-Signature Modules

The racket/signature +language treats a module body as a unit signature.

The body must match the following module-body grammar:

  module-body = (require require-spec ...) ... sig-spec ...

See Creating Units for the grammar of sig-spec. +Unlike the body of a racket/unit module, a +require in a racket/signature module must be +a literal use of require.

The resulting signature is exported as +base^, where base is derived from +the enclosing module’s name (i.e., its symbolic name, or its path +without the directory and file suffix). If the module name ends in +-sig, then base corresponds to the module +name before -sig. Otherwise, the module name serves as +base.

A struct form as a sig-spec is consistent with the +definitions introduced by define-struct, as opposed to +definitions introduced struct. (That behavior was originally +a bug, but it is preserved for compatibility.)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Structural_Matching.html b/clones/docs.racket-lang.org/reference/Structural_Matching.html new file mode 100644 index 00000000..0fbad5b6 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Structural_Matching.html @@ -0,0 +1,25 @@ + +7.6 Structural Matching

7.6 Structural Matching

syntax

(unit/new-import-export
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...)
  init-depends-decl
  ((tagged-sig-spec ...) unit-expr tagged-sig-spec))
Similar to unit, except the body of the unit is determined by +an existing unit produced by unit-expr. The result is a unit +whose implementation is unit-expr, but whose imports, +exports, and initialization dependencies are as in the +unit/new-import-export form (instead of as in the unit +produced by unit-expr).

The final clause of the unit/new-import-export form +determines the connection between the old and new imports and exports. +The connection is similar to the way that compound-unit +propagates imports and exports; the difference is that the connection +between import and the right-hand side of the link clause is +based on the names of elements in signatures, rather than the names of +the signatures. That is, a tagged-sig-spec on the right-hand +side of the link clause need not appear as a tagged-sig-spec +in the import clause, but each of the bindings implied by the +linking tagged-sig-spec must be implied by some +tagged-sig-spec in the import clause. Similarly, +each of the bindings implied by an export +tagged-sig-spec must be implied by some left-hand-side +tagged-sig-spec in the linking clause.

syntax

(define-unit/new-import-export unit-id
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...)
  init-depends-decl
  ((tagged-sig-spec ...) unit-expr tagged-sig-spec))
Like unit/new-import-export, but binds static information to +unit-id like define-unit.

syntax

(unit/s
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...)
  init-depends-decl
  unit-id)
Like unit/new-import-export, but the linking clause is +inferred, so unit-id must have the appropriate static +information. +

syntax

(define-unit/s name-id
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...)
  init-depends-decl
  unit-id)
Like unit/s, but binds static information to name-id +like define-unit.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Structure_Type_Property_Contracts.html b/clones/docs.racket-lang.org/reference/Structure_Type_Property_Contracts.html new file mode 100644 index 00000000..f881d5e7 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Structure_Type_Property_Contracts.html @@ -0,0 +1,32 @@ + +8.5 Structure Type Property Contracts
8.6

8.5 Structure Type Property Contracts

procedure

(struct-type-property/c value-contract)  contract?

  value-contract : contract?
Produces a contract for a structure type property. When the +contract is applied to a struct type property, it produces a wrapped +struct type property that applies value-contract to the value +associated with the property when it used to create a new struct type +(via struct, make-struct-type, etc).

The struct type property’s accessor function is not affected; if it is +exported, it must be protected separately.

As an example, consider the following module. It creates a structure +type property, prop, whose value should be a function mapping +a structure instance to a numeric predicate. The module also exports +app-prop, which extracts the predicate from a structure +instance and applies it to a given value.

> (module propmod racket
    (require racket/contract)
    (define-values (prop prop? prop-ref)
      (make-struct-type-property 'prop))
    (define (app-prop x v)
      (((prop-ref x) x) v))
    (provide/contract
     [prop? (-> any/c boolean?)]
     [prop (struct-type-property/c
            (-> prop? (-> integer? boolean?)))]
     [app-prop (-> prop? integer? boolean?)])
    (provide prop-ref))

The structmod module creates a structure type named +s with a single field; the value of prop is a +function that extracts the field value from an instance. Thus the +field ought to be an integer predicate, but notice that +structmod places no contract on s enforcing that +constraint.

> (module structmod racket
    (require 'propmod)
    (struct s (f) #:property prop (lambda (s) (s-f s)))
    (provide (struct-out s)))
> (require 'propmod 'structmod)

First we create an s instance with an integer predicate, so +the constraint on prop is in fact satisfied. The first call +to app-prop is correct; the second simply violates the +contract of app-prop.

> (define s1 (s even?))
> (app-prop s1 5)

#f

> (app-prop s1 'apple)

app-prop: contract violation

  expected: integer?

  given: 'apple

  in: the 2nd argument of

      (-> prop? integer? boolean?)

  contract from: propmod

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

We are able to create s instances with values other than +integer predicates, but applying app-prop on them blames +structmod, because the function associated with +propthat is, (lambda (s) (s-f s))does not +always produce a value satisfying (-> integer? boolean?).

> (define s2 (s "not a fun"))
> (app-prop s2 5)

prop: contract violation

  expected: a procedure

  given: "not a fun"

  in: the range of

      the struct property value of

      (struct-type-property/c

       (-> prop? (-> integer? boolean?)))

  contract from: propmod

  blaming: structmod

   (assuming the contract is correct)

  at: eval:2:0

> (define s3 (s list))
> (app-prop s3 5)

prop: contract violation

  expected: boolean?

  given: '(5)

  in: the range of

      the range of

      the struct property value of

      (struct-type-property/c

       (-> prop? (-> integer? boolean?)))

  contract from: propmod

  blaming: structmod

   (assuming the contract is correct)

  at: eval:2:0

The fix would be to propagate the obligation inherited from +prop to s:

(provide (contract-out
           [struct s ([f (-> integer? boolean?)])]))

Finally, if we directly apply the property accessor, +prop-ref, and then misuse the resulting function, the +propmod module is blamed:

> ((prop-ref s3) 'apple)

prop: broke its own contract

  promised: prop?

  produced: 'apple

  in: the 1st argument of

      the struct property value of

      (struct-type-property/c

       (-> prop? (-> integer? boolean?)))

  contract from: propmod

  blaming: propmod

   (assuming the contract is correct)

  at: eval:2:0

The propmod module has an obligation to ensure a function +associated with prop is applied only to values satisfying +prop?. By directly providing prop-ref, it enables +that constraint to be violated (and thus it is blamed), even though +the bad application actually occurs elsewhere.

Generally there is no need to provide a structure type property +accessor at all; it is typically only used by other functions within +the module. But if it must be provided, it should be protected thus:

(provide (contract-out
           [prop-ref (-> prop? (-> prop? (-> integer? boolean?)))]))
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Surrogates.html b/clones/docs.racket-lang.org/reference/Surrogates.html new file mode 100644 index 00000000..dacac225 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Surrogates.html @@ -0,0 +1,63 @@ + +6.12 Surrogates

6.12 Surrogates

The bindings documented in this section are provided by the racket/surrogate library, not racket/base or racket.

The racket/surrogate library provides an abstraction +for building an instance of the proxy design pattern. The +pattern consists of two objects, a host and a +surrogate object. The host object delegates method calls to +its surrogate object. Each host has a dynamically assigned surrogate, +so an object can completely change its behavior merely by changing the +surrogate.

syntax

(surrogate use-wrapper-proc method-spec ...)

 
use-wrapper-proc = #:use-wrapper-proc
  | 
     
method-spec = (augment default-expr method-id arg-spec ...)
  | (override method-id arg-spec ...)
     
arg-spec = (id ...)
  | id
The surrogate form produces four values: a host mixin (a +procedure that accepts and returns a class), a host interface, a +surrogate class, and a surrogate interface.

If #:use-wrapper-proc does not appear, +the host mixin adds a single private field to its argument. It also adds getter and setter methods +get-surrogate and set-surrogate to get and set the value of the field. The +set-surrogate method accepts instances of the class returned by +the surrogate form or #f, and it updates the field with its +argument; then, set-surrogate calls the on-disable-surrogate on the +previous value of the field and on-enable-surrogate for the +new value of the field. The get-surrogate method returns the +current value of the field.

If #:use-wrapper-proc does appear, the the host mixin adds +and a second private field and its getter and setter +methods get-surrogate-wrapper-proc and set-surrogate-wrapper-proc. +The additional field holds a wrapper procedure whose contract +is (-> (-> any) (-> any) any), so the procedure is invoked with two thunks. +The first thunk is a fallback that invokes the original object’s method, +skipping the surrogate. The second thunk invokes the surrogate. The default +wrapper procedure is +
(λ (fallback-thunk surrogate-thunk)
  (surrogate-thunk))
That is, it simply defers to the method being invoked on the surrogate. +Note that wrapper procedure can adjust the +dynamic extent of calls to the surrogate +by, for example, changing the values of parameters. The +wrapper procedure is also invoked when calling the +on-disable-surrogate and on-enable-surrogate methods +of the surrogate.

The host mixin has a single overriding method for each +method-id in the surrogate form (even the ones +specified with augment). Each of these +methods is defined with a case-lambda with one arm for each +arg-spec. Each arm has the variables as arguments in the +arg-spec. The body of each method tests the +private surrogate field. If the field value is #f, the method just +returns the result of invoking the super or inner method. If the +field value is not #f, the corresponding method +of the object in the field is invoked. This method receives the same +arguments as the original method, plus two extras. The extra arguments +come at the beginning of the argument list. The first is the original +object. The second is a procedure that calls the super or inner method +(i.e., the method of the class that is passed to the mixin or an +extension, or the method in an overriding class), with the arguments +that the procedure receives.

For example, the host-mixin for this surrogate: +

(surrogate (override m (x y z)))

will override the m method and call the surrogate like this: +
(define/override (m x y z)
  (if surrogate
      (send surrogate m
            this
            (λ (x y z) (super m x y z))
            x y z)
      (super m x y z)))
where surrogate is bound to the value most recently passed +to the host mixin’s set-surrogate method.

The host interface has the names set-surrogate, +get-surrogate, and each of the method-ids in the +original form.

The surrogate class has a single public method for each +method-id in the surrogate form. These methods are +invoked by classes constructed by the mixin. Each has a corresponding +method signature, as described in the above paragraph. Each method +just passes its argument along to the super procedure it receives.

In the example above, this is the m method in the surrogate class: +
(define/public (m original-object original-super x y z)
  (original-super x y z))

If you derive a class from the surrogate class, do not both call +the super argument and the super method of the surrogate +class itself. Only call one or the other, since the default methods +call the super argument.

Finally, the interface contains all of the names specified in +surrogate’s argument, plus on-enable-surrogate and +on-disable-surrogate. The class returned by +surrogate implements this interface.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Syntax_Quoting__quote-syntax.html b/clones/docs.racket-lang.org/reference/Syntax_Quoting__quote-syntax.html new file mode 100644 index 00000000..7e20d406 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Syntax_Quoting__quote-syntax.html @@ -0,0 +1,13 @@ + +3.21 Syntax Quoting: quote-syntax
On this page:
quote-syntax

3.21 Syntax Quoting: quote-syntax

syntax

(quote-syntax datum)

(quote-syntax datum #:local)
Similar to quote, but produces a syntax object +that preserves the lexical information and source-location +information attached to datum at expansion time.

When #:local is specified, then all scopes in the +syntax object’s lexical information are preserved. When +#:local is omitted, then the scope sets within +datum are pruned to omit the scope for any binding +form that appears between the quote-syntax form and the +enclosing top-level context, module body, or phase level +crossing, whichever is closer.

Unlike syntax (#'), quote-syntax does +not substitute pattern variables bound by with-syntax, +syntax-parse, or syntax-case.

Examples:
> (syntax? (quote-syntax x))

#t

> (quote-syntax (1 2 3))

#<syntax:eval:78:0 (1 2 3)>

> (with-syntax ([a #'5])
    (quote-syntax (a b c)))

#<syntax:eval:79:0 (a b c)>

> (free-identifier=? (let ([x 1]) (quote-syntax x))
                     (quote-syntax x))

#t

> (free-identifier=? (let ([x 1]) (quote-syntax x #:local))
                     (quote-syntax x))

#f

Changed in version 6.3 of package base: Added scope pruning and support +for #:local.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Transformer_Helpers.html b/clones/docs.racket-lang.org/reference/Transformer_Helpers.html new file mode 100644 index 00000000..b8cd06e6 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Transformer_Helpers.html @@ -0,0 +1,36 @@ + +7.12 Transformer Helpers

7.12 Transformer Helpers

 (require racket/unit-exptime) package: base

The racket/unit-exptime library provides procedures +that are intended for use by macro transformers. In particular, the +library is typically imported using for-syntax into a module +that defines macro with define-syntax.

procedure

(unit-static-signatures unit-identifier 
  err-syntax) 
  
(list/c (cons/c (or/c symbol? #f)
                identifier?))
(list/c (cons/c (or/c symbol? #f)
                identifier?))
  unit-identifier : identifier?
  err-syntax : syntax?
If unit-identifier is bound to static unit information via +define-unit (or other such forms), the result is two +values. The first value is for the unit’s imports, and the second is +for the unit’s exports. Each result value is a list, where each list +element pairs a symbol or #f with an identifier. The symbol +or #f indicates the import’s or export’s tag (where +#f indicates no tag), and the identifier indicates the +binding of the corresponding signature.

If unit-identifier is not bound to static unit information, +then the exn:fail:syntax exception is raised. In that case, the given +err-syntax argument is used as the source of the error, where +unit-identifier is used as the detail source location.

procedure

(signature-members sig-identifier    
  err-syntax)  
(or/c identifier? #f)
(listof identifier?)
(listof identifier?)
(listof identifier?)
  sig-identifier : identifier?
  err-syntax : syntax?
If sig-identifier is bound to static unit information via +define-signature (or other such forms), the result is four +values:

  • an identifier or #f indicating the signature (of any) +that is extended by the sig-identifier binding;

  • a list of identifiers representing the variables +supplied/required by the signature;

  • a list of identifiers for variable definitions in the +signature (i.e., variable bindings that are provided on +import, but not defined by units that implement the +signature); and

  • a list of identifiers with syntax definitions in the signature.

Each of the result identifiers is given lexical information that is +based on sig-identifier, so the names are suitable for +reference or binding in the context of sig-identifier. +See define-signature for more information.

If sig-identifier is not bound to a signature, then the +exn:fail:syntax exception is raised. In that case, the given +err-syntax argument is used as the source of the error, where +sig-identifier is used as the detail source location.

procedure

(unit-static-init-dependencies unit-identifier 
  err-syntax) 
  
(list/c (cons/c (or/c symbol? #f)
                identifier?))
  unit-identifier : identifier?
  err-syntax : syntax?
If unit-identifier is bound to static unit information via +define-unit (or other such forms), the result is a list of +pairs. Each pair combines a tag (or #f for no tag) and a +signature name, indicating an initialization dependency of the unit on +the specified import (i.e., the same tag and signature are included in +the first result from unit-static-signatures).

If unit-identifier is not bound to static unit information, +then the exn:fail:syntax exception is raised. In that case, the given +err-syntax argument is used as the source of the error, where +unit-identifier is used as the detail source location.

Added in version 6.1.1.8 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Unit_Utilities.html b/clones/docs.racket-lang.org/reference/Unit_Utilities.html new file mode 100644 index 00000000..5e9e836f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Unit_Utilities.html @@ -0,0 +1,4 @@ + +7.8 Unit Utilities

7.8 Unit Utilities

procedure

(unit? v)  boolean?

  v : any/c
Returns #t if v is a unit, #f otherwise.

syntax

(provide-signature-elements sig-spec ...)

Expands to a provide of all identifiers implied by the +sig-specs. See unit for the grammar of +sig-spec.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/Writing.html b/clones/docs.racket-lang.org/reference/Writing.html new file mode 100644 index 00000000..04e43ffb --- /dev/null +++ b/clones/docs.racket-lang.org/reference/Writing.html @@ -0,0 +1,140 @@ + +13.5 Writing

13.5 Writing

procedure

(write datum [out])  void?

  datum : any/c
  out : output-port? = (current-output-port)
Writes datum to out, normally in such a way that +instances of core datatypes can be read back in. If out has a +handler associated to it via port-write-handler, then the +handler is called. Otherwise, the default printer is used (in +write mode), as configured by various parameters.

See The Printer for more information about the default +printer. In particular, note that write may require memory +proportional to the depth of the value being printed, due to the +initial cycle check.

Examples:
> (write 'hi)

hi

> (write (lambda (n) n))

#<procedure>

> (define o (open-output-string))
> (write "hello" o)
> (get-output-string o)

"\"hello\""

procedure

(display datum [out])  void?

  datum : any/c
  out : output-port? = (current-output-port)
Displays datum to out, similar to write, +but usually in such a way that byte- and character-based datatypes are +written as raw bytes or characters. If out has a handler +associated to it via port-display-handler, then the handler +is called. Otherwise, the default printer is used (in display +mode), as configured by various parameters.

See The Printer for more information about the default +printer. In particular, note that display may require memory +proportional to the depth of the value being printed, due to the +initial cycle check.

procedure

(print datum [out quote-depth])  void?

  datum : any/c
  out : output-port? = (current-output-port)
  quote-depth : (or/c 0 1) = 0
Prints datum to out. If out has a handler +associated to it via port-print-handler, then the handler is +called. Otherwise, the handler specified by +global-port-print-handler is called; the default handler uses +the default printer in print mode.

The optional quote-depth argument adjusts printing when the +print-as-expression parameter is set to #t. In that +case, quote-depth specifies the starting quote depth for +printing datum.

The rationale for providing print is that display +and write both have specific output conventions, and those +conventions restrict the ways that an environment can change the +behavior of display and write procedures. No output +conventions should be assumed for print, so that environments +are free to modify the actual output generated by print in +any way.

procedure

(writeln datum [out])  void?

  datum : any/c
  out : output-port? = (current-output-port)
The same as (write datum out) followed by (newline out).

Added in version 6.1.1.8 of package base.

procedure

(displayln datum [out])  void?

  datum : any/c
  out : output-port? = (current-output-port)
The same as (display datum out) followed by (newline out), +which is similar to println in Pascal or Java.

procedure

(println datum [out quote-depth])  void?

  datum : any/c
  out : output-port? = (current-output-port)
  quote-depth : (or/c 0 1) = 0
The same as (print datum out quote-depth) followed by +(newline out).

The println function is not equivalent to println in +other languages, because println uses printing conventions +that are closer to write than to display. For a closer +analog to println in other languages, use displayln.

Added in version 6.1.1.8 of package base.

procedure

(fprintf out form v ...)  void?

  out : output-port?
  form : string?
  v : any/c
Prints formatted output to out, where form is a string +that is printed directly, except for special formatting +escapes:

  • ~n or ~% prints a newline character (which +is equivalent to \n in a literal format string)

  • ~a or ~A displays the next argument +among the vs

  • ~s or ~S writes the next argument +among the vs

  • ~v or ~V prints the next argument +among the vs

  • ~.c where c is a, +A, s, S, v, or V: +truncates default-handler display, write, or print output +to (error-print-width) characters, using ... as +the last three characters if the untruncated output would be longer

  • ~e or ~E outputs the next argument among the +vs using the current error value conversion handler (see +error-value->string-handler) and current error printing +width

  • ~c or ~C write-chars the +next argument in vs; if the next argument is not a +character, the exn:fail:contract exception is raised

  • ~b or ~B prints the next argument among the +vs in binary; if the next argument is not an exact number, the +exn:fail:contract exception is raised

  • ~o or ~O prints the next argument among the +vs in octal; if the next argument is not an exact number, the +exn:fail:contract exception is raised

  • ~x or ~X prints the next argument among the +vs in hexadecimal; if the next argument is not an exact +number, the exn:fail:contract exception is raised

  • ~~ prints a tilde.

  • ~w, where w is a whitespace +character (see char-whitespace?), skips characters in +form until a non-whitespace character is encountered or +until a second end-of-line is encountered (whichever happens +first). On all platforms, an end-of-line can be #\return, +#\newline, or #\return followed immediately by +#\newline.

The form string must not contain any ~ that is +not one of the above escapes, otherwise the +exn:fail:contract exception is raised. When the format string requires more +vs than are supplied, the +exn:fail:contract exception is raised. Similarly, when more vs are +supplied than are used by the format string, the +exn:fail:contract exception is raised.

Example:
> (fprintf (current-output-port)
           "~a as a string is ~s.\n"
           '(3 4)
           "(3 4)")

(3 4) as a string is "(3 4)".

procedure

(printf form v ...)  void?

  form : string?
  v : any/c
The same as (fprintf (current-output-port) form v ...).

procedure

(eprintf form v ...)  void?

  form : string?
  v : any/c
The same as (fprintf (current-error-port) form v ...).

procedure

(format form v ...)  string?

  form : string?
  v : any/c
Formats to a string. The result is the same as

(let ([o (open-output-string)])
  (fprintf o form v ...)
  (get-output-string o))

Example:
> (format "~a as a string is ~s.\n" '(3 4) "(3 4)")

"(3 4) as a string is \"(3 4)\".\n"

parameter

(print-pair-curly-braces)  boolean?

(print-pair-curly-braces on?)  void?
  on? : any/c
A parameter that controls pair printing. If the value is true, then +pairs print using { and } instead of +( and ). The default is #f.

parameter

(print-mpair-curly-braces)  boolean?

(print-mpair-curly-braces on?)  void?
  on? : any/c
A parameter that controls pair printing. If the value is true, then +mutable pairs print using { and } instead of +( and ). The default is #t.

parameter

(print-unreadable)  boolean?

(print-unreadable on?)  void?
  on? : any/c
A parameter that enables or disables printing of values that have no +readable form (using the default reader), including +structures that have a custom-write procedure (see +prop:custom-write), but not including uninterned +symbols and unreadable symbols (which print the same as +interned symbols). If the parameter value is #f, an +attempt to print an unreadable value raises exn:fail. The +parameter value defaults to #t. See The Printer for +more information.

parameter

(print-graph)  boolean?

(print-graph on?)  void?
  on? : any/c
A parameter that controls printing data with sharing; defaults to +#f. See The Printer for more information.

parameter

(print-struct)  boolean?

(print-struct on?)  void?
  on? : any/c
A parameter that controls printing structure values in vector or +prefab form; defaults to #t. See The Printer +for more information. This parameter has no effect on the printing of +structures that have a custom-write procedure (see +prop:custom-write).

parameter

(print-box)  boolean?

(print-box on?)  void?
  on? : any/c
A parameter that controls printing box values; defaults to +#t. See Printing Boxes for more information.

parameter

(print-vector-length)  boolean?

(print-vector-length on?)  void?
  on? : any/c
A parameter that controls printing vectors; defaults to +#f. See Printing Vectors for more information.

parameter

(print-hash-table)  boolean?

(print-hash-table on?)  void?
  on? : any/c
A parameter that controls printing hash tables; defaults to +#t. See Printing Hash Tables for more information.

parameter

(print-boolean-long-form)  boolean?

(print-boolean-long-form on?)  void?
  on? : any/c
A parameter that controls printing of booleans. When the parameter’s +value is true, #t and #f print as #true +and #false, otherwise they print as #t +and #f. The default is #f.

A parameter that controls printing of two-element lists that start +with quote, 'quasiquote, 'unquote, +'unquote-splicing, 'syntax, 'quasisyntax, +'unsyntax, or 'unsyntax-splicing; defaults to +#f. See Printing Pairs and Lists for more information.

parameter

(print-as-expression)  boolean?

(print-as-expression on?)  void?
  on? : any/c
A parameter that controls printing in print mode (as opposed +to write or display); defaults to #t. See +The Printer for more information.

parameter

(print-syntax-width)

  (or/c +inf.0 0 (and/c exact-integer? (>/c 3)))
(print-syntax-width width)  void?
  width : (or/c +inf.0 0 (and/c exact-integer? (>/c 3)))
A parameter that controls printing of syntax objects. Up to +width characters are used to show the datum form of a syntax +object within #<syntax...> (after the +syntax object’s source location, if any), where ... is +used as the last three characters if the printed form would otherwise be longer +than width characters. A value of 0 for +width means that the datum is not shown at all.

parameter

(print-value-columns)

  (or/c +inf.0 (and/c exact-integer? (>/c 5)))
(print-value-columns columns)  void?
  columns : (or/c +inf.0 (and/c exact-integer? (>/c 5)))
A parameter that contains a recommendation for the number of +columns that should be used for printing values via print. +May or may not be respected by print - the current default +handler for print does not. It is expected that REPLs that use +some form of pretty-printing for values respect this parameter.

Added in version 8.0.0.13 of package base.

parameter

(current-write-relative-directory)

  
(or/c (and/c path? complete-path?)
      (cons/c (and/c path? complete-path?)
              (and/c path? complete-path?))
      #f)
(current-write-relative-directory path)  void?
  path : 
(or/c (and/c path-string? complete-path?)
      (cons/c (and/c path-string? complete-path?)
              (and/c path-string? complete-path?))
      #f)
A parameter that is used when writing compiled code (see Printing Compiled Code) that contains +pathname literals, including source-location pathnames for procedure +names. When the parameter’s value is a path, paths that syntactically extend path +are converted to relative paths; when the resulting +compiled code is read, relative paths are converted back to complete +paths using the current-load-relative-directory parameter (if +it is not #f; otherwise, the path is left relative). +When the parameter’s value is (cons rel-to-path base-path), then +paths that syntactically extend base-path are converted as relative to rel-to-path; +the rel-to-path must extend base-path, in which case 'up +path elements (in the sense of build-path) may be used to make a path relative +to rel-to-path.

procedure

(port-write-handler out)  (any/c output-port? . -> . any)

  out : output-port?
(port-write-handler out proc)  void?
  out : output-port?
  proc : (any/c output-port? . -> . any)

procedure

(port-display-handler out)  (any/c output-port? . -> . any)

  out : output-port?
(port-display-handler out proc)  void?
  out : output-port?
  proc : (any/c output-port? . -> . any)

procedure

(port-print-handler out)

  ((any/c output-port?) ((or/c 0 1)) . ->* . any)
  out : output-port?
(port-print-handler out proc)  void?
  out : output-port?
  proc : (any/c output-port? . -> . any)
Gets or sets the port write handler, port display +handler, or port print handler for out. This +handler is called to output to the port when write, +display, or print (respectively) is applied to the +port. Each handler must accept two arguments: the value to be printed and +the destination port. The handler’s return value is ignored.

A port print handler optionally accepts a third argument, which +corresponds to the optional third argument to print; if a +procedure given to port-print-handler does not accept a third +argument, it is wrapped with a procedure that discards the optional +third argument.

The default port display and write handlers print Racket expressions +with Racket’s built-in printer (see The Printer). The +default print handler calls the global port print handler (the value +of the global-port-print-handler parameter); the default +global port print handler is the same as the default write handler.

procedure

(global-port-print-handler)

  (->* (any/c output-port?) ((or/c 0 1)) any)
(global-port-print-handler proc)  void?
  proc : 
(or/c (->* (any/c output-port?) ((or/c 0 1)) any)
      (any/c output-port? . -> . any))
A parameter that determines global port print handler, +which is called by the default port print handler (see +port-print-handler) to print values into a port. +The default value uses the built-in printer (see +The Printer) in print mode.

A global port print handler optionally accepts a third +argument, which corresponds to the optional third argument to +print. If a procedure given to +global-port-print-handler does not accept a third argument, +it is wrapped with a procedure that discards the optional third +argument.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/__expression.html b/clones/docs.racket-lang.org/reference/__expression.html new file mode 100644 index 00000000..c1c2844d --- /dev/null +++ b/clones/docs.racket-lang.org/reference/__expression.html @@ -0,0 +1,22 @@ + +3.4 Expression Wrapper: #%expression
On this page:
#%expression

3.4 Expression Wrapper: #%expression

syntax

(#%expression expr)

Produces the same result as expr. Using +#%expression forces the parsing of a form as an +expression.

Examples:
> (#%expression (+ 1 2))

3

> (#%expression (define x 10))

eval:8:0: define: not allowed in an expression context

  in: (define x 10)

The #%expression form is helpful in recursive definition contexts +where expanding a subsequent definition can provide compile-time information +for the current expression. For example, consider a define-sym-case +macro that simply records some symbols at compile-time in a given identifier. +
(define-syntax (define-sym-case stx)
  (syntax-case stx ()
    [(_ id sym ...)
     (andmap identifier? (syntax->list #'(sym ...)))
     #'(define-syntax id
         '(sym ...))]))
and then a variant of case that checks to make sure the symbols +used in the expression match those given in the earlier definition: +
(define-syntax (sym-case stx)
  (syntax-case stx ()
    [(_ id val-expr [(sym) expr] ...)
     (let ()
       (define expected-ids
         (syntax-local-value
          #'id
          (λ ()
            (raise-syntax-error
             'sym-case
             "expected an identifier bound via define-sym-case"
             stx
             #'id))))
       (define actual-ids (syntax->datum #'(sym ...)))
       (unless (equal? expected-ids actual-ids)
         (raise-syntax-error
          'sym-case
          (format "expected the symbols ~s"
                  expected-ids)
          stx))
       #'(case val-expr [(sym) expr] ...))]))

If the definition follows the use like this, then +the define-sym-case macro does not have +a chance to bind id and the sym-case +macro signals an error: +
> (let ()
    (sym-case land-creatures 'bear
              [(bear) 1]
              [(fox) 2])
    (define-sym-case land-creatures bear fox))

eval:11:0: sym-case: expected an identifier bound via

define-sym-case

  at: land-creatures

  in: (sym-case land-creatures (quote bear) ((bear) 1)

((fox) 2))

But if the sym-case is wrapped in an #%expression, +then the expander does not need to expand it to know it is +an expression and it moves on to the define-sym-case +expression. +
> (let ()
    (#%expression (sym-case sea-creatures 'whale
                            [(whale) 1]
                            [(squid) 2]))
    (define-sym-case sea-creatures whale squid)
    'more...)

'more...

Of course, a macro like sym-case should not require its +clients to add #%expression; instead it should check +the basic shape of its arguments and then expand to #%expression +wrapped around a helper macro that calls syntax-local-value +and finishes the expansion.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/__top-interaction.html b/clones/docs.racket-lang.org/reference/__top-interaction.html new file mode 100644 index 00000000..6ad4bd33 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/__top-interaction.html @@ -0,0 +1,6 @@ + +3.22 Interaction Wrapper: #%top-interaction
On this page:
#%top-interaction

3.22 Interaction Wrapper: #%top-interaction

syntax

(#%top-interaction . form)

Expands to simply form. The #%top-interaction form +is similar to #%app and #%module-begin, in that it +provides a hook to control interactive evaluation through +load (more precisely, the default load handler) or +read-eval-print-loop.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/__top.html b/clones/docs.racket-lang.org/reference/__top.html new file mode 100644 index 00000000..35529954 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/__top.html @@ -0,0 +1,24 @@ + +3.5 Variable References and #%top
On this page:
#%top

3.5 Variable References and #%top

syntax

id

Refers to a top-level, module-level, or local binding, when id is +not bound as a transformer (see Expansion). At run-time, +the reference evaluates to the value in the location associated with +the binding.

When the expander encounters an id that is not bound by a +module-level or local binding, it converts the expression to +(#%top . id) giving #%top +the lexical context of the id; typically, that context refers +to #%top. See also Expansion Steps.

Examples:
> (define x 10)
> x

10

> (let ([x 5]) x)

5

> ((lambda (x) x) 2)

2

syntax

(#%top . id)

Equivalent to id when id is bound to a module-level +or top-level variable. In a top-level context, (#%top . id) +always refers to a top-level variable, even if id is +unbound or bound to syntax, as long as id does not +have a local binding. In all contexts, (#%top . id) is +a syntax error if id has a local binding.

Within a module form, (#%top . id) expands to just +id as long as id is defined within +the module and has no local binding in its context. At phase +level 0, (#%top . id) is an immediate syntax error if +id is not bound. At phase level 1 and higher, a syntax +error is reported if id is not defined at the corresponding +phase by the end of module-body partial expansion.

See also Expansion Steps for information on how the expander +introduces #%top identifiers.

Examples:
> (define x 12)
> (#%top . x)

12

Changed in version 6.3 of package base: Changed the introduction of +#%top in a top-level context +to unbound identifiers only.
Changed in version 8.2.0.7: Changed treatment of locally bound id to +always report a syntax error, even outside of a module.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/all-sync.html b/clones/docs.racket-lang.org/reference/all-sync.html new file mode 100644 index 00000000..920ea234 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/all-sync.html @@ -0,0 +1,7 @@ + +11.2 Synchronization

11.2 Synchronization

Racket’s synchronization toolbox spans four layers:

  • synchronizable events a general framework for +synchronization;

  • channels a primitive that can be used, in principle, +to build most other kinds of synchronizable events (except the ones +that compose events); and

  • semaphores a simple and especially cheap primitive +for synchronization.

  • future semaphores a simple synchronization primitive +for use with futures.

    11.2.1 Events

    11.2.2 Channels

    11.2.3 Semaphores

    11.2.4 Buffered Asynchronous Channels

      11.2.4.1 Creating and Using Asynchronous Channels

      11.2.4.2 Contracts and Impersonators on Asynchronous Channels

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/application.html b/clones/docs.racket-lang.org/reference/application.html new file mode 100644 index 00000000..a5bbe219 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/application.html @@ -0,0 +1,29 @@ + +3.7 Procedure Applications and #%app
On this page:
#%app
#%plain-app

3.7 Procedure Applications and #%app

+Function Calls in The Racket Guide introduces procedure applications.

syntax

(proc-expr arg ...)

Applies a procedure, when proc-expr is not an +identifier that has a transformer binding (see +Expansion).

More precisely, the expander converts this form to +(#%app proc-expr arg ...), giving +#%app the lexical context that is associated with the +original form (i.e., the pair that combines proc-expr and its +arguments). Typically, the lexical context of the pair indicates the +procedure-application #%app that is described next. See also +Expansion Steps.

Examples:
> (+ 1 2)

3

> ((lambda (x #:arg y) (list y x)) #:arg 2 1)

'(2 1)

syntax

(#%app proc-expr arg ...)

Applies a procedure. Each arg is one of the following:

arg-expr

The resulting value is a non-keyword +argument.

keyword arg-expr

The resulting value is a +keyword argument using keyword. Each +keyword in the application must be distinct.

The proc-expr and arg-exprs are evaluated in order, +left to right. If the result of proc-expr is a procedure that +accepts as many arguments as non-keyword +arg-exprs, if it accepts arguments for all of the +keywords in the application, and if all required +keyword-based arguments are represented among the keywords +in the application, then the procedure is called with the values of +the arg-exprs. Otherwise, the exn:fail:contract exception is raised.

The continuation of the procedure call is the same as the continuation +of the application expression, so the results of the procedure are the +results of the application expression.

The relative order of keyword-based arguments matters only +for the order of arg-expr evaluations; the arguments are +associated with argument variables in the applied procedure based on +the keywords, and not their positions. The other +arg-expr values, in contrast, are associated with variables +according to their order in the application form.

See also Expansion Steps for information on how the +expander introduces #%app identifiers.

Examples:
> (#%app + 1 2)

3

> (#%app (lambda (x #:arg y) (list y x)) #:arg 2 1)

'(2 1)

> (#%app cons)

cons: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 2

  given: 0

syntax

(#%plain-app proc-expr arg-expr ...)

(#%plain-app)
Like #%app, but without support for keyword arguments. +As a special case, (#%plain-app) produces '().

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/async-channel.html b/clones/docs.racket-lang.org/reference/async-channel.html new file mode 100644 index 00000000..33c38ccf --- /dev/null +++ b/clones/docs.racket-lang.org/reference/async-channel.html @@ -0,0 +1,41 @@ + +11.2.4 Buffered Asynchronous Channels
11.2.4 Buffered Asynchronous Channels

The bindings documented in this section are provided by the racket/async-channel library, not racket/base or racket.

11.2.4.1 Creating and Using Asynchronous Channels

+See also Thread Mailboxes.

An asynchronous channel is like a channel, but it buffers +values so that a send operation does not wait on a receive operation.

In addition to its use with procedures that are specific to +asynchronous channels, an asynchronous channel can be used as a +synchronizable event (see Events). An asynchronous +channel is ready for synchronization when +async-channel-get would not block; the asynchronous channel’s +synchronization result is the same as the +async-channel-get result.

procedure

(async-channel? v)  boolean?

  v : any/c
Returns #t if v is an asynchronous channel, +#f otherwise.

procedure

(make-async-channel [limit])  async-channel?

  limit : (or/c exact-positive-integer? #f) = #f
Returns an asynchronous channel with a buffer limit of limit +items. A get operation blocks when the channel is empty, and a put +operation blocks when the channel has limit items already. +If limit is #f, the channel buffer has no limit (so +a put never blocks).

procedure

(async-channel-get ach)  any/c

  ach : async-channel?
Blocks until at least one value is available in ach, and then +returns the first of the values that were put into +async-channel.

procedure

(async-channel-try-get ach)  any/c

  ach : async-channel?
If at least one value is immediately available in ach, +returns the first of the values that were put into ach. If +async-channel is empty, the result is #f.

procedure

(async-channel-put ach v)  void?

  ach : async-channel?
  v : any/c
Puts v into ach, blocking if ach’s buffer +is full until space is available.

procedure

(async-channel-put-evt ach v)  evt?

  ach : async-channel?
  v : any/c
Returns a synchronizable event that is ready for +synchronization when (async-channel-put ach v) would return +a value (i.e., when the channel holds fewer values already than its +limit); the synchronization result of a asynchronous channel-put event is the asynchronous channel-put event itself.

Examples:
(define (server input-channel output-channel)
  (thread (lambda ()
            (define (get)
              (async-channel-get input-channel))
            (define (put x)
              (async-channel-put output-channel x))
            (define (do-large-computation)
              (sqrt 9))
            (let loop ([data (get)])
              (case data
                [(quit) (void)]
                [(add) (begin
                         (put (+ 1 (get)))
                         (loop (get)))]
                [(long) (begin
                          (put (do-large-computation))
                          (loop (get)))])))))
(define to-server (make-async-channel))
(define from-server (make-async-channel))

 

> (server to-server from-server)

#<thread>

> (async-channel? to-server)

#t

> (printf "Adding 1 to 4\n")

Adding 1 to 4

> (async-channel-put to-server 'add)
> (async-channel-put to-server 4)
> (printf "Result is ~a\n" (async-channel-get from-server))

Result is 5

> (printf "Ask server to do a long computation\n")

Ask server to do a long computation

> (async-channel-put to-server 'long)
> (printf "I can do other stuff\n")

I can do other stuff

> (printf "Ok, computation from server is ~a\n"
          (async-channel-get from-server))

Ok, computation from server is 3

> (async-channel-put to-server 'quit)

11.2.4.2 Contracts and Impersonators on Asynchronous Channels

procedure

(async-channel/c c)  contract?

  c : contract?
Returns a contract that recognizes asynchronous channels. Values put into or +retrieved from the channel must match c.

If the c argument is a flat contract or a chaperone contract, then the +result will be a chaperone contract. Otherwise, the result will be an +impersonator contract.

When an async-channel/c contract is applied to an asynchronous channel, +the result is not eq? to the input. The result will be either a +chaperone or impersonator of the input depending on the type of +contract.

procedure

(impersonate-async-channel channel 
  get-proc 
  put-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c async-channel? impersonator?)
  channel : async-channel?
  get-proc : (any/c . -> . any/c)
  put-proc : (any/c . -> . any/c)
  prop : impersonator-property?
  prop-val : any
Returns an impersonator of channel, which redirects the +async-channel-get and async-channel-put operations.

The get-proc must accept the value that async-channel-get +produces on channel; it must produce a replacement value, which is the +result of the get operation on the impersonator.

The put-proc must accept the value passed to async-channel-put +called on channel; it must produce a replacement value, which is the +value passed to the put procedure called on the original channel.

The get-proc and put-proc procedures are called for all +operations that get or put values from the channel, not just +async-channel-get and async-channel-put.

Pairs of prop and prop-val (the number of arguments to +impersonate-async-channel must be odd) add +impersonator properties or override impersonator property values +of channel.

procedure

(chaperone-async-channel channel 
  get-proc 
  put-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c async-channel? chaperone?)
  channel : async-channel?
  get-proc : (any/c . -> . any/c)
  put-proc : (any/c . -> . any/c)
  prop : impersonator-property?
  prop-val : any
Like impersonate-async-channel, but the get-proc procedure +must produce the same value or a chaperone of the original value, and +put-proc must produce the same value or a chaperone of the original +value.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/attaching-contracts-to-values.html b/clones/docs.racket-lang.org/reference/attaching-contracts-to-values.html new file mode 100644 index 00000000..30b53028 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/attaching-contracts-to-values.html @@ -0,0 +1,151 @@ + +8.6 Attaching Contracts to Values

8.6 Attaching Contracts to Values

syntax

(contract-out unprotected-submodule contract-out-item ...)

 
unprotected-submodule = 
  | #:unprotected-submodule submodule-name
     
contract-out-item = 
(struct id/ignored ((id contract-expr) ...)
  struct-option)
  | (rename orig-id id contract-expr)
  | (id contract-expr)
  | #:∃ poly-variables
  | #:exists poly-variables
  | #:∀ poly-variables
  | #:forall poly-variables
     
poly-variables = id
  | (id ...)
     
id/ignored = id
  | (id ignored-id)
     
struct-option = 
  | #:omit-constructor
A provide-spec for use in provide (currently only for +the same phase level as the provide form; for example, +contract-out cannot be nested within for-syntax). Each id +is provided from the module. In +addition, clients of the module must live up to the contract specified +by contract-expr for each export.

The contract-out form treats modules as units of +blame. The module that defines the provided variable is expected to +meet the positive (co-variant) positions of the contract. Each module +that imports the provided variable must obey the negative +(contra-variant) positions of the contract. Each contract-expr +in a contract-out form is effectively moved to the end of the +enclosing module, so a contract-expr can refer to variables +that are defined later in the same module.

Only uses of the contracted variable outside the module are +checked. Inside the module, no contract checking occurs.

The rename form of contract-out exports the +first variable (the internal name) with the name specified by the +second variable (the external name).

The struct form of contract-out +provides a structure-type definition id, and each field has a contract +that dictates the contents of the fields. Unlike a struct +definition, however, all of the fields (and their contracts) must be +listed. The contract on the fields that the sub-struct shares with its +parent are only used in the contract for the sub-struct’s constructor, and +the selector or mutators for the super-struct are not provided. The +exported structure-type name always doubles as a constructor, even if +the original structure-type name does not act as a constructor. +If the #:omit-constructor option is present, the constructor +is not provided. The second form of id/ignored, which has both +id and ignored-id, is deprecated and allowed +in the grammar only for backward compatability, where ignored-id is ignored. +The first form should be used instead.

Note that if the struct is created with serializable-struct +or define-serializable-struct, contract-out does not +protect struct instances that are created via +deserialize. Consider using struct-guard/c instead.

The #:∃, #:exists, #:∀, and #:forall +clauses define new abstract contracts. The variables are bound in the +remainder of the contract-out form to new contracts that hide +the values they accept and ensure that the exported functions are treated +parametrically. See new-∃/c and new-∀/c for details +on how the clauses hide the values.

If #:unprotected-submodule appears, the identifier +that follows it is used as the name of a submodule that +contract-out generates. The submodule exports all +of the names in the contract-out, but without +contracts.

The implementation of contract-out uses +syntax-property to attach properties to the code it generates +that records the syntax of the contracts in the fully expanded program. +Specifically, the symbol 'provide/contract-original-contract +is bound to vectors of two elements, the exported identifier and a +syntax object for the expression that produces the contract controlling +the export.

Changed in version 7.3.0.3 of package base: Added #:unprotected-submodule.
Changed in version 7.7.0.9: Started ignoring ignored-id.

syntax

(recontract-out id ...)

A provide-spec for use in provide (currently, + just like contract-out, only for + the same phase level as the provide form).

It re-exports id, but with positive blame associated +to the module containing recontract-out instead of the +location of the original site of id.

This can be useful when a public module wants to export an +identifier from a private module but where any contract violations +should be reported in terms of the public module instead of the +private one.

Examples:
> (module private-implementation racket/base
    (require racket/contract)
    (define (recip x) (/ 1 x))
    (define (non-zero? x) (not (= x 0)))
    (provide/contract [recip (-> (and/c real? non-zero?)
                                 (between/c -1 1))]))
> (module public racket/base
    (require racket/contract
             'private-implementation)
    (provide (recontract-out recip)))
> (require 'public)
> (recip +nan.0)

recip: broke its own contract

  promised: (between/c -1 1)

  produced: +nan.0

  in: the range of

      (->

       (and/c real? non-zero?)

       (between/c -1 1))

  contract from: public

  blaming: public

   (assuming the contract is correct)

  at: eval:3:0

Replacing the use of recontract-out with just +recip would result in a contract violation blaming +the private module.

syntax

(provide/contract unprotected-submodule contract-out-item ...)

A legacy shorthand for (provide (contract-out unprotected-submodule contract-out-item ...)), +except that a contract-expr within provide/contract +is evaluated at the position of the provide/contract form +instead of at the end of the enclosing module.

syntax

(struct-guard/c contract-expr ...)

Returns a procedure suitable to be passed as the #:guard +argument to struct, serializable-struct (and related forms). +The guard procedure ensures that each contract protects the +corresponding field values, as long as the struct is not mutated. +Mutations are not protected.

Examples:
> (struct snake (weight hungry?)
    #:guard (struct-guard/c real? boolean?))
> (snake 1.5 "yep")

snake, field 2: contract violation

  expected: boolean?

  given: "yep"

  in: boolean?

  contract from: top-level

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

8.6.1 Nested Contract Boundaries

 (require racket/contract/region) package: base

syntax

(with-contract blame-id (wc-export ...) free-var-list ... body ...+)

(with-contract blame-id results-spec free-var-list ... body ...+)
 
wc-export = (id contract-expr)
     
result-spec = #:result contract-expr
  | #:results (contract-expr ...)
     
free-var-list = 
  | #:freevar id contract-expr
  | #:freevars ([id contract-expr] ...)
Generates a local contract boundary.

The first with-contract form cannot appear in expression position. +All names defined within the first with-contract form are +visible externally, but those names listed in the wc-export +list are protected with the corresponding contract. The body of +the form allows definition/expression interleaving if its context does.

The second with-contract form must appear in expression position. +The final body expression should return the same number of values +as the number of contracts listed in the result-spec, and each +returned value is contracted with its respective contract. The sequence +of body forms is treated as for let.

The blame-id is used for the positive positions of +contracts paired with exported ids. Contracts broken +within the with-contract body will use the +blame-id for their negative position.

If a free-var-list is given, then any uses of the free variables +inside the body will be protected with contracts that +blame the context of the with-contract form for the positive +positions and the with-contract form for the negative ones.

syntax

(define/contract id contract-expr free-var-list init-value-expr)

(define/contract (head args) contract-expr free-var-list body ...+)
Works like define, except that the contract +contract-expr is attached to the bound value. For the +definition of head and args, see define. +For the definition of free-var-list, see with-contract.

Examples:
> (define/contract distance (>=/c 0) 43.52)
> (define/contract (furlongs->feet fr)
    (-> real? real?)
    (* 660 fr))
; a contract violation expected here:
> (furlongs->feet "not a furlong")

furlongs->feet: contract violation

  expected: real?

  given: "not a furlong"

  in: the 1st argument of

      (-> real? real?)

  contract from: (function furlongs->feet)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:3:0

The define/contract form treats the individual definition as +a contract region. The definition itself is responsible for positive +(co-variant) positions of the contract, and references to +id outside of the definition must meet the negative +positions of the contract. Since the contract boundary is +between the definition and the surrounding context, references to +id inside the define/contract form are not checked.

Examples:
; an unsual predicate that prints when called
> (define (printing-int? x)
    (displayln "I was called")
    (exact-integer? x))
> (define/contract (fact n)
    (-> printing-int? printing-int?)
    (if (zero? n)
        1
        (* n (fact (sub1 n)))))
> (fact 5) ; only prints twice, not for each recursive call

I was called

I was called

120

If a free-var-list is given, then any uses of the free variables +inside the body will be protected with contracts that +blame the context of the define/contract form for the positive +positions and the define/contract form for the negative ones.

Examples:
> (define (integer->binary-string n)
    (number->string n 2))
> (define/contract (numbers->strings lst)
    (-> (listof number?) (listof string?))
    #:freevar integer->binary-string (-> exact-integer? string?)
    ; mistake, lst might contain inexact numbers
    (map integer->binary-string lst))
> (numbers->strings '(4.0 3.3 5.8))

integer->binary-string: contract violation

  expected: exact-integer?

  given: 4.0

  in: the 1st argument of

      (-> exact-integer? string?)

  contract from: top-level

  blaming: (function numbers->strings)

   (assuming the contract is correct)

  at: eval:3:0

syntax

(struct/contract struct-id ([field contract-expr] ...)
                        struct-option ...)
(struct/contract struct-id super-struct-id
                        ([field contract-expr] ...)
                        struct-option ...)
Works like struct, except that the arguments to the constructor, +accessors, and mutators are protected by contracts. For the definitions of +field and struct-option, see struct.

The struct/contract form only allows a subset of the +struct-option keywords: #:mutable, #:transparent, +#:auto-value, #:omit-define-syntaxes, and #:property.

Examples:
> (struct/contract fruit ([seeds number?]))
> (fruit 60)

#<fruit>

> (fruit #f)

fruit: contract violation

  expected: number?

  given: #f

  in: the 1st argument of

      (-> number? symbol? any)

  contract from: (struct fruit)

  blaming: top-level

   (assuming the contract is correct)

> (struct/contract apple fruit ([type string?]))
> (apple 14 "golden delicious")

#<apple>

> (apple 5 30)

apple: contract violation

  expected: string?

  given: 30

  in: the 2nd argument of

      (-> any/c string? symbol? any)

  contract from: (struct apple)

  blaming: top-level

   (assuming the contract is correct)

> (apple #f "granny smith")

fruit: contract violation

  expected: number?

  given: #f

  in: the 1st argument of

      (-> number? symbol? any)

  contract from: (struct fruit)

  blaming: top-level

   (assuming the contract is correct)

syntax

(define-struct/contract struct-id ([field contract-expr] ...)
                        struct-option ...)
(define-struct/contract (struct-id super-struct-id)
                        ([field contract-expr] ...)
                        struct-option ...)
Works like struct/contract, except that the syntax for supplying a +super-struct-id is different, and a constructor-id that +has a make- prefix on struct-id is implicitly +supplied. For the definitions of +field and struct-option, see define-struct. +Like struct versus define-struct, +struct/contract is normally preferred to define-struct/contract.

The define-struct/contract form only allows a subset of the +struct-option keywords: #:mutable, #:transparent, +#:auto-value, #:omit-define-syntaxes, and #:property.

Examples:
> (define-struct/contract fish ([color number?]))
> (make-fish 5)

#<fish>

> (make-fish #f)

make-fish: contract violation

  expected: number?

  given: #f

  in: the 1st argument of

      (-> number? symbol? any)

  contract from: (struct fish)

  blaming: top-level

   (assuming the contract is correct)

> (define-struct/contract (salmon fish) ([ocean symbol?]))
> (make-salmon 5 'atlantic)

#<salmon>

> (make-salmon 5 #f)

make-salmon: contract violation

  expected: symbol?

  given: #f

  in: the 2nd argument of

      (-> any/c symbol? symbol? any)

  contract from: (struct salmon)

  blaming: top-level

   (assuming the contract is correct)

> (make-salmon #f 'pacific)

make-fish: contract violation

  expected: number?

  given: #f

  in: the 1st argument of

      (-> number? symbol? any)

  contract from: (struct fish)

  blaming: top-level

   (assuming the contract is correct)

syntax

(invariant-assertion invariant-expr expr)

Establishes an invariant of expr, determined by invariant-expr.

Unlike the specification of a contract, an +invariant-assertion does not establish a boundary +between two parties. Instead, it simply attaches a logical assertion +to the value. Because the form uses contract machinery to check the +assertion, the surrounding module is treated as the party to be blamed +for any violations of the assertion.

This means, for example, that the assertion is checked on +recursive calls, when an invariant is used on the right-hand +side of a definition:

Examples:
> (define furlongss->feets
    (invariant-assertion
     (-> (listof real?) (listof real?))
     (λ (l)
       (cond
         [(empty? l) empty]
         [else
          (if (= 327 (car l))
              (furlongss->feets (list "wha?"))
              (cons (furlongs->feet (first l))
                    (furlongss->feets (rest l))))]))))
> (furlongss->feets (list 1 2 3))

'(660 1320 1980)

> (furlongss->feets (list 1 327 3))

furlongss->feets: assertion violation

  expected: real?

  given: "wha?"

  in: an element of

      the 1st argument of

      (-> (listof real?) (listof real?))

  contract from: invariant-assertion

  at: eval:5:0

Added in version 6.0.1.11 of package base.

Bound by define-syntax-parameter, this contains +information about the current contract region, used by +the above forms to determine the candidates for blame +assignment.

8.6.2 Low-level Contract Boundaries

syntax

(define-module-boundary-contract id
  orig-id
  contract-expr
  pos-blame-party
  source-loc
  name-for-blame
  context-limit)
 
pos-blame-party = 
  | #:pos-source pos-source-expr
     
source-loc = 
  | #:srcloc srcloc-expr
     
name-for-blame = 
  | #:name-for-blame blame-id
     
context-limit = 
  | #:context-limit limit-expr
Defines id to be orig-id, but with the contract +contract-expr.

The identifier id is defined as a macro transformer that +consults the context of its use to determine the name for negative +blame assignment (using the entire module where a reference appears +as the negative party).

The positive party defaults to the module containing the use of +define-module-boundary-contract, but can be specified explicitly +via the #:pos-source keyword.

The source location used in the blame error messages for the location +of the place where the contract was put on the value defaults to the +source location of the use of define-module-boundary-contract, +but can be specified via the #:srcloc argument, in which case +it can be any of the things that the third argument to datum->syntax +can be.

The name used in the error messages will be orig-id, unless +#:name-for-blame is supplied, in which case the identifier +following it is used as the name in the error messages.

If #:context-limit is supplied, it behaves the same as +it does when supplied to contract.

Examples:
> (module server racket/base
    (require racket/contract/base)
    (define (f x) #f)
    (define-module-boundary-contract g f (-> integer? integer?))
    (provide g))
> (module client racket/base
    (require 'server)
    (define (clients-fault) (g #f))
    (define (servers-fault) (g 1))
    (provide servers-fault clients-fault))
> (require 'client)
> (clients-fault)

g: contract violation

  expected: integer?

  given: #f

  in: the 1st argument of

      (-> integer? integer?)

  contract from: 'server

  blaming: client

   (assuming the contract is correct)

  at: eval:2:0

> (servers-fault)

g: broke its own contract

  promised: integer?

  produced: #f

  in: the range of

      (-> integer? integer?)

  contract from: 'server

  blaming: (quote server)

   (assuming the contract is correct)

  at: eval:2:0

Changed in version 6.7.0.4 of package base: Added the #:name-for-blame argument.
Changed in version 6.90.0.29: Added the #:context-limit argument.

syntax

(contract contract-expr to-protect-expr
          positive-blame-expr negative-blame-expr)
(contract contract-expr to-protect-expr
          positive-blame-expr negative-blame-expr
          #:context-limit limit-expr)
(contract contract-expr to-protect-expr
          positive-blame-expr negative-blame-expr
          value-name-expr source-location-expr)
The primitive mechanism for attaching a contract to a value. The +purpose of contract is as a target for the expansion of some +higher-level contract specifying form.

The contract expression adds the contract specified by +contract-expr to the value produced by +to-protect-expr. The result of a contract expression +is the result of the to-protect-expr expression, but with the +contract specified by contract-expr enforced on +to-protect-expr.

The values of positive-blame-expr and negative-blame-expr +indicate how to assign blame for positive and negative positions of the contract +specified by contract-expr. They may be any value, and are formatted +as by display for purposes of contract violation error messages.

If specified, value-name-expr indicates a name for the protected value +to be used in error messages. If not supplied, or if value-name-expr +produces #f, no name is printed. Otherwise, it is also formatted as by +display. More precisely, the value-name-expr ends up in the +blame-name field of the blame record, which is used as the first portion +of the error message. +

Examples:
> (contract integer? #f 'pos 'neg 'timothy #f)

timothy: broke its own contract

  promised: integer?

  produced: #f

  in: integer?

  contract from: pos

  blaming: pos

   (assuming the contract is correct)

> (contract integer? #f 'pos 'neg #f #f)

broke its own contract

  promised: integer?

  produced: #f

  in: integer?

  contract from: pos

  blaming: pos

   (assuming the contract is correct)

If specified, source-location-expr indicates the source location +reported by contract violations. The expression must produce a srcloc +structure, syntax object, #f, or a list or vector in the format +accepted by the third argument to datum->syntax.

If #:context-limit is supplied, the following expression + must evaluate to either #f or a natural number. If + the expression evaluates to an natural number, the number of + layers of context information is limited to at most that + many. For example, if the number is 0, no context + information is recorded and the error messages do not contain + the section that starts with in:.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/begin.html b/clones/docs.racket-lang.org/reference/begin.html new file mode 100644 index 00000000..ff9d52e2 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/begin.html @@ -0,0 +1,30 @@ + +3.15 Sequencing: begin, begin0, and begin-for-syntax

3.15 Sequencing: begin, begin0, and begin-for-syntax

+Sequencing in The Racket Guide introduces begin and begin0.

syntax

(begin form ...)

(begin expr ...+)
The first form applies when begin appears at the top level, +at module level, or in an internal-definition position (before any +expression in the internal-definition sequence). In that case, the +begin form is equivalent to splicing the forms into +the enclosing context.

The second form applies for begin in an expression position. +In that case, the exprs are evaluated in order, and the +results are ignored for all but the last expr. The last +expr is in tail position with respect to the begin +form.

Examples:
> (begin
    (define x 10)
    x)

10

> (+ 1 (begin
         (printf "hi\n")
         2))

hi

3

> (let-values ([(x y) (begin
                        (values 1 2 3)
                        (values 1 2))])
   (list x y))

'(1 2)

syntax

(begin0 expr ...+)

Evaluates the first expr, then evaluates the other exprss +in order, ignoring their results. The results of the first expr +are the results of the begin0 form; the first expr is +in tail position only if no other exprs are present.

Example:
> (begin0
    (values 1 2)
    (printf "hi\n"))

hi

1

2

syntax

(begin-for-syntax form ...)

Allowed only in a top-level context or module context, +shifts the phase level of each form by one:

See also module for information about expansion order and +partial expansion for begin-for-syntax within a module +context. Evaluation of an expr within +begin-for-syntax is parameterized to set +current-namespace as in let-syntax.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/block.html b/clones/docs.racket-lang.org/reference/block.html new file mode 100644 index 00000000..fc50c0d4 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/block.html @@ -0,0 +1,8 @@ + +3.23 Blocks: block
On this page:
block

3.23 Blocks: block

 (require racket/block) package: base
The bindings documented in this section are provided by the racket/block library, not racket/base or racket.

syntax

(block defn-or-expr ...)

Supports a mixture of expressions and mutually recursive definitions, +as in a module body. Unlike an internal-definition +context, the last defn-or-expr need not be an expression.

The result of the block form is the result +of the last defn-or-expr if it is an expression, +#<void> otherwise. If no defn-or-expr is provided +(after flattening begin forms), the result is #<void>.

The final defn-or-expr is executed in tail position, if it is +an expression.

Examples:
> (define (f x)
    (block
      (define y (add1 x))
      (displayln y)
      (define z (* 2 y))
      (+ 3 z)))
> (f 12)

13

29

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/booleans.html b/clones/docs.racket-lang.org/reference/booleans.html new file mode 100644 index 00000000..3d561a3d --- /dev/null +++ b/clones/docs.racket-lang.org/reference/booleans.html @@ -0,0 +1,22 @@ + +4.2 Booleans

4.2 Booleans

True and false booleans are represented by the values +#t and #f, respectively, though operations that +depend on a boolean value typically treat anything other than +#f as true. The #t value is always eq? to +itself, and #f is always eq? to itself.

See Reading Booleans + for information on reading + booleans and Printing Booleans + for information on printing booleans.

See also and, or, andmap, and ormap.

procedure

(boolean? v)  boolean?

  v : any/c
Returns #t if v is #t or #f, +#f otherwise.

Examples:
> (boolean? #f)

#t

> (boolean? #t)

#t

> (boolean? 'true)

#f

procedure

(not v)  boolean?

  v : any/c
Returns #t if v is #f, #f otherwise.

Examples:
> (not #f)

#t

> (not #t)

#f

> (not 'we-have-no-bananas)

#f

procedure

(immutable? v)  boolean?

  v : any/c
Returns #t if v is an immutable string, +byte string, vector, hash table, or box, +#f otherwise.

Note that immutable? is not a general predicate for +immutability (despite its name). It works only for a handful of +datatypes for which a single predicate—string?, +vector?, etc.recognizes both mutable and immutable variants +of the datatype. In particular, immutable? produces +#f for a pair, even though pairs are immutable, since +pair? implies immutability.

Examples:
> (immutable? 'hello)

#f

> (immutable? "a string")

#t

> (immutable? (box 5))

#f

> (immutable? #(0 1 2 3))

#t

> (immutable? (make-hash))

#f

> (immutable? (make-immutable-hash '([a b])))

#t

> (immutable? #t)

#f

4.2.1 Boolean Aliases

 (require racket/bool) package: base
The bindings documented in this section are provided by the racket/bool and racket libraries, but not racket/base.

value

true : boolean?

An alias for #t.

value

false : boolean?

An alias for #f.

procedure

(symbol=? a b)  boolean?

  a : symbol?
  b : symbol?
Returns (equal? a b) (if a and b are symbols).

procedure

(boolean=? a b)  boolean?

  a : boolean?
  b : boolean?
Returns (equal? a b) (if a and b are booleans).

procedure

(false? v)  boolean?

  v : any/c
Returns (not v).

syntax

(nand expr ...)

Same as (not (and expr ...)).

Examples:
> (nand #f #t)

#t

> (nand #f (error 'ack "we don't get here"))

#t

syntax

(nor expr ...)

Same as (not (or expr ...)).

In the two argument case, returns #t if neither of the +arguments is a true value.

Examples:
> (nor #f #t)

#f

> (nor #t (error 'ack "we don't get here"))

#f

syntax

(implies expr1 expr2)

Checks to be sure that the first +expression implies the second.

Same as (if expr1 expr2 #t).

Examples:
> (implies #f #t)

#t

> (implies #f #f)

#t

> (implies #t #f)

#f

> (implies #f (error 'ack "we don't get here"))

#t

procedure

(xor b1 b2)  any

  b1 : any/c
  b2 : any/c
Returns the exclusive or of b1 and b2.

If exactly one of b1 and b2 is +not #f, then return it. Otherwise, returns +#f.

Examples:
> (xor 11 #f)

11

> (xor #f 22)

22

> (xor 11 22)

#f

> (xor #f #f)

#f

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/boxes.html b/clones/docs.racket-lang.org/reference/boxes.html new file mode 100644 index 00000000..fa3b4daa --- /dev/null +++ b/clones/docs.racket-lang.org/reference/boxes.html @@ -0,0 +1,24 @@ + +4.14 Boxes

4.14 Boxes

+Boxes in The Racket Guide introduces boxes.

A box is like a single-element vector, normally used as +minimal mutable storage.

A box can be mutable or +immutable. When an immutable box is provided to a +procedure like set-box!, the +exn:fail:contract exception is raised. Box constants generated by the +default reader (see Reading Strings) are +immutable. Use immutable? to check whether a box is +immutable.

A literal or printed box starts with #&. See Reading Boxes + for information on reading + boxes and Printing Boxes + for information on printing boxes.

procedure

(box? v)  boolean?

  v : any/c
Returns #t if v is a box, #f otherwise.

procedure

(box v)  box?

  v : any/c
Returns a new mutable box that contains v.

procedure

(box-immutable v)  (and/c box? immutable?)

  v : any/c
Returns a new immutable box that contains v.

procedure

(unbox box)  any/c

  box : box?
Returns the content of box.

For any v, (unbox (box v)) and (unbox (box-immutable v)) returns v.

procedure

(set-box! box v)  void?

  box : (and/c box? (not/c immutable?))
  v : any/c
Sets the content of box to v.

procedure

(unbox* box)  any/c

  box : (and box? (not/c impersonator?))

procedure

(set-box*! box v)  void?

  box : (and/c box? (not/c immutable?) (not/c impersonator?))
  v : any/c
Like unbox and set-box!, but constrained to work on +boxes that are not impersonators.

Added in version 6.90.0.15 of package base.

procedure

(box-cas! box old new)  boolean?

  box : (and/c box? (not/c immutable?) (not/c impersonator?))
  old : any/c
  new : any/c
Atomically updates the contents of box to new, provided +that box currently contains a value that is eq? to +old, and returns #t in that case. If box +does not contain old, then the result is #f.

If no other threads or futures attempt to access +box, the operation is equivalent to

(and (eq? old (unbox box)) (set-box! box new) #t)

except that box-cas! can spuriously fail on some platforms. +That is, with low probability, the result can be #f with the +value in box left unchanged, even if box contains +old.

When Racket is compiled with support for futures, +box-cas! is guaranteed to use a hardware compare and +set operation. Uses of box-cas! be performed safely in a +future (i.e., allowing the future thunk to continue in +parallel). See also Machine Memory Order.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/breakhandler.html b/clones/docs.racket-lang.org/reference/breakhandler.html new file mode 100644 index 00000000..4ce0af18 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/breakhandler.html @@ -0,0 +1,89 @@ + +10.6 Breaks

10.6 Breaks

A break is an asynchronous exception, usually triggered +through an external source controlled by the user, or through the +break-thread procedure. For example, the user may type Ctl-C +in a terminal to trigger a break. On some platforms, the Racket +process may receive SIGINT, SIGHUP, +or SIGTERM; the latter two correspond to hang-up and +terminate breaks as reflected by exn:break:hang-up and +exn:break:terminate, respectively. Multiple breaks may be +collapsed into a single exception, and multiple breaks of different +kinds may be collapsed to a single “strongest” break, where a +terminate break is stronger than a hang-up break which is stronger +than an interrupt break.

A break exception can only occur in a +thread while breaks are enabled. When a break is detected and enabled, +the exn:break (or exn:break:hang-up or +exn:break:terminate) exception is raised +in the thread sometime afterward; if breaking +is disabled when break-thread is called, the break is +suspended until breaking is again enabled for the thread. While a +thread has a suspended break, additional breaks are ignored.

Breaks are enabled through the break-enabled parameter-like +procedure and through the parameterize-break form, which is +analogous to parameterize. The break-enabled +procedure does not represent a parameter to be used with +parameterize, because changing the break-enabled state of a +thread requires an explicit check for breaks, and this check is +incompatible with the tail evaluation of a parameterize +expression’s body.

Certain procedures, such as semaphore-wait/enable-break, +enable breaks temporarily while performing a blocking action. If +breaks are enabled for a thread, and if a break is triggered for the +thread but not yet delivered as an exn:break exception, then +the break is guaranteed to be delivered before breaks can be disabled +in the thread. The timing of exn:break exceptions is not +guaranteed in any other way.

Before calling a with-handlers predicate or handler, an +exception handler, an error display handler, an error escape handler, +an error value conversion handler, or a pre-thunk or +post-thunk for a dynamic-wind, the call is +parameterize-breaked to disable breaks. Furthermore, breaks +are disabled during the transitions among handlers related to +exceptions, during the transitions between pre-thunks and +post-thunks for dynamic-wind, and during other +transitions for a continuation jump. For example, if breaks are +disabled when a continuation is invoked, and if breaks are also +disabled in the target continuation, then breaks will remain disabled +from the time of the invocation until the target continuation +executes unless a relevant dynamic-wind pre-thunk or +post-thunk explicitly enables breaks.

If a break is triggered for a thread that is blocked on a nested +thread (see call-in-nested-thread), and if breaks are enabled +in the blocked thread, the break is implicitly handled by transferring +it to the nested thread.

When breaks are enabled, they can occur at any point within execution, +which makes certain implementation tasks subtle. For example, assuming +breaks are enabled when the following code is executed,

(with-handlers ([exn:break? (lambda (x) (void))])
  (semaphore-wait s))

then it is not the case that a #<void> result means the +semaphore was decremented or a break was received, exclusively. It is +possible that both occur: the break may occur after the +semaphore is successfully decremented but before a #<void> +result is returned by semaphore-wait. A break exception will +never damage a semaphore, or any other built-in construct, but many +built-in procedures (including semaphore-wait) contain +internal sub-expressions that can be interrupted by a break.

In general, it is impossible using only semaphore-wait to +implement the guarantee that either the semaphore is decremented or an +exception is raised, but not both. Racket therefore supplies +semaphore-wait/enable-break (see Semaphores), +which does permit the implementation of such an exclusive guarantee:

(parameterize-break #f
  (with-handlers ([exn:break? (lambda (x) (void))])
    (semaphore-wait/enable-break s)))

In the above expression, a break can occur at any point until breaks +are disabled, in which case a break exception is propagated to the +enclosing exception handler. Otherwise, the break can only occur +within semaphore-wait/enable-break, which guarantees that if +a break exception is raised, the semaphore will not have been +decremented.

To allow similar implementation patterns over blocking port +operations, Racket provides read-bytes-avail!/enable-break, +write-bytes-avail/enable-break, and other procedures.

procedure

(break-enabled)  boolean?

(break-enabled on?)  void?
  on? : any/c
Gets or sets the break enabled state of the current thread. If +on? is not supplied, the result is #t if breaks are +currently enabled, #f otherwise. If on? is supplied +as #f, breaks are disabled, and if on? is a true +value, breaks are enabled.

syntax

(parameterize-break boolean-expr body ...+)

Evaluates +boolean-expr to determine whether breaks are initially +enabled while evaluating the bodys in sequence. The result +of the parameterize-break expression is the result of the last +expr.

As with parameterize, a fresh thread cell is allocated to +hold the break-enabled state of the continuation, and calls to +break-enabled within the continuation access or modify the +new cell. Unlike a parameter, a mutation to the break setting via +break-enabled is not inherited by new threads (i.e., the +thread cell is not preserved).

Analogous to (current-parameterization) (see +Parameters); it returns a break parameterization +(effectively, a thread cell) that holds the current continuation’s +break-enable state.

procedure

(call-with-break-parameterization break-param    
  thunk)  any
  break-param : break-parameterization?
  thunk : (-> any)
Analogous to (call-with-parameterization parameterization thunk) (see Parameters), calls thunk in a +continuation whose break-enabled state is in break-param. The +thunk is not called in tail position with respect to +the call-with-break-parameterization call.

procedure

(break-parameterization? v)  boolean?

  v : any/c
Returns #t if v is a break parameterization as produced by +current-break-parameterization, #f otherwise.

Added in version 6.1.1.8 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/bytestrings.html b/clones/docs.racket-lang.org/reference/bytestrings.html new file mode 100644 index 00000000..50638b18 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/bytestrings.html @@ -0,0 +1,246 @@ + +4.5 Byte Strings

4.5 Byte Strings

+Bytes and Byte Strings in The Racket Guide introduces byte strings.

A byte string is a fixed-length array of bytes. A + byte is an exact integer between 0 and + 255 inclusive.

A byte string can be +mutable or immutable. When an immutable byte +string is provided to a procedure like bytes-set!, the +exn:fail:contract exception is raised. Byte-string constants generated by the +default reader (see Reading Strings) are immutable, +and they are interned in read-syntax mode. +Use immutable? to check whether a byte string is +immutable.

Two byte strings are equal? when they have the same length +and contain the same sequence of bytes.

A byte string can be used as a single-valued sequence (see +Sequences). The bytes of the string serve as elements +of the sequence. See also in-bytes.

See Reading Strings + for information on reading + byte strings and Printing Strings + for information on printing byte strings.

See also: immutable?.

4.5.1 Byte String Constructors, Selectors, and Mutators

procedure

(bytes? v)  boolean?

  v : any/c
Returns #t if v + is a byte string, #f otherwise.

Examples:
> (bytes? #"Apple")

#t

> (bytes? "Apple")

#f

procedure

(make-bytes k [b])  bytes?

  k : exact-nonnegative-integer?
  b : byte? = 0
Returns a new mutable byte string of length k where each +position in the byte string is initialized with the byte b.

Example:
> (make-bytes 5 65)

#"AAAAA"

procedure

(bytes b ...)  bytes?

  b : byte?
Returns a new mutable byte +string whose length is the number of provided bs, and whose +positions are initialized with the given bs.

Example:
> (bytes 65 112 112 108 101)

#"Apple"

procedure

(bytes->immutable-bytes bstr)  (and/c bytes? immutable?)

  bstr : bytes?
Returns an immutable byte string with the same content + as bstr, returning bstr itself if bstr is + immutable.

Examples:
> (bytes->immutable-bytes (bytes 65 65 65))

#"AAA"

> (define b (bytes->immutable-bytes (make-bytes 5 65)))
> (bytes->immutable-bytes b)

#"AAAAA"

> (eq? (bytes->immutable-bytes b) b)

#t

procedure

(byte? v)  boolean?

  v : any/c
Returns #t if v is + a byte (i.e., an exact integer between 0 and 255 + inclusive), #f otherwise.

Examples:
> (byte? 65)

#t

> (byte? 0)

#t

> (byte? 256)

#f

> (byte? -1)

#f

procedure

(bytes-length bstr)  exact-nonnegative-integer?

  bstr : bytes?
Returns the length of bstr.

Example:
> (bytes-length #"Apple")

5

procedure

(bytes-ref bstr k)  byte?

  bstr : bytes?
  k : exact-nonnegative-integer?
Returns the character at position k in bstr. + The first position in the bytes corresponds to 0, so the + position k must be less than the length of the bytes, + otherwise the exn:fail:contract exception is raised.

Example:
> (bytes-ref #"Apple" 0)

65

procedure

(bytes-set! bstr k b)  void?

  bstr : (and/c bytes? (not/c immutable?))
  k : exact-nonnegative-integer?
  b : byte?
Changes the + character position k in bstr to b. The first + position in the byte string corresponds to 0, so the position + k must be less than the length of the bytes, otherwise the + exn:fail:contract exception is raised.

Examples:
> (define s (bytes 65 112 112 108 101))
> (bytes-set! s 4 121)
> s

#"Apply"

procedure

(subbytes bstr start [end])  bytes?

  bstr : bytes?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (bytes-length str)
Returns + a new mutable byte string that is (- end start) bytes long, + and that contains the same bytes as bstr from start + inclusive to end exclusive. The start and + end arguments must be less than or equal to the length of + bstr, and end must be greater than or equal to + start, otherwise the exn:fail:contract exception is raised.

Examples:
> (subbytes #"Apple" 1 3)

#"pp"

> (subbytes #"Apple" 1)

#"pple"

procedure

(bytes-copy bstr)  bytes?

  bstr : bytes?
Returns +(subbytes str 0).

procedure

(bytes-copy! dest    
  dest-start    
  src    
  [src-start    
  src-end])  void?
  dest : (and/c bytes? (not/c immutable?))
  dest-start : exact-nonnegative-integer?
  src : bytes?
  src-start : exact-nonnegative-integer? = 0
  src-end : exact-nonnegative-integer? = (bytes-length src)
Changes the bytes of dest starting at position + dest-start to match the bytes in src from + src-start (inclusive) to src-end (exclusive). The + byte strings dest and src can be the same byte + string, and in that case the destination region can overlap with the + source region; the destination bytes after the copy match the source + bytes from before the copy. If any of dest-start, + src-start, or src-end are out of range (taking into + account the sizes of the byte strings and the source and destination + regions), the exn:fail:contract exception is raised.

Examples:
> (define s (bytes 65 112 112 108 101))
> (bytes-copy! s 4 #"y")
> (bytes-copy! s 0 s 3 4)
> s

#"lpply"

procedure

(bytes-fill! dest b)  void?

  dest : (and/c bytes? (not/c immutable?))
  b : byte?
Changes dest so that every position in the + bytes is filled with b.

Examples:
> (define s (bytes 65 112 112 108 101))
> (bytes-fill! s 113)
> s

#"qqqqq"

procedure

(bytes-append bstr ...)  bytes?

  bstr : bytes?
Returns a new mutable byte string +that is as long as the sum of the given bstrs’ lengths, and +that contains the concatenated bytes of the given bstrs. If +no bstrs are provided, the result is a zero-length byte +string.

Example:
> (bytes-append #"Apple" #"Banana")

#"AppleBanana"

procedure

(bytes->list bstr)  (listof byte?)

  bstr : bytes?
Returns a new + list of bytes corresponding to the content of bstr. That is, + the length of the list is (bytes-length bstr), and the + sequence of bytes in bstr is the same sequence in the + result list.

Example:
> (bytes->list #"Apple")

'(65 112 112 108 101)

procedure

(list->bytes lst)  bytes?

  lst : (listof byte?)
Returns a new + mutable byte string whose content is the list of bytes in lst. + That is, the length of the byte string is (length lst), and + the sequence of bytes in lst is the same sequence in + the result byte string.

Example:
> (list->bytes (list 65 112 112 108 101))

#"Apple"

procedure

(make-shared-bytes k [b])  bytes?

  k : exact-nonnegative-integer?
  b : byte? = 0
Returns a new mutable byte string of length k where each +position in the byte string is initialized with the byte b. +For communication among places, the new byte string is allocated in the +shared memory space.

Example:
> (make-shared-bytes 5 65)

#"AAAAA"

procedure

(shared-bytes b ...)  bytes?

  b : byte?
Returns a new mutable byte +string whose length is the number of provided bs, and whose +positions are initialized with the given bs. +For communication among places, the new byte string is allocated in the +shared memory space.

Example:
> (shared-bytes 65 112 112 108 101)

#"Apple"

4.5.2 Byte String Comparisons

procedure

(bytes=? bstr1 bstr2 ...)  boolean?

  bstr1 : bytes?
  bstr2 : bytes?
Returns + #t if all of the arguments are eqv?.

Examples:
> (bytes=? #"Apple" #"apple")

#f

> (bytes=? #"a" #"as" #"a")

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(bytes<? bstr1 bstr2 ...)  boolean?

  bstr1 : bytes?
  bstr2 : bytes?
Returns #t if the arguments are lexicographically sorted + increasing, where individual bytes are ordered by <, + #f otherwise.

Examples:
> (bytes<? #"Apple" #"apple")

#t

> (bytes<? #"apple" #"Apple")

#f

> (bytes<? #"a" #"b" #"c")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(bytes>? bstr1 bstr2 ...)  boolean?

  bstr1 : bytes?
  bstr2 : bytes?
Like bytes<?, but checks whether the arguments are decreasing.

Examples:
> (bytes>? #"Apple" #"apple")

#f

> (bytes>? #"apple" #"Apple")

#t

> (bytes>? #"c" #"b" #"a")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.5.3 Bytes to/from Characters, Decoding and Encoding

procedure

(bytes->string/utf-8 bstr [err-char start end])  string?

  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Produces a string by decoding the start to end + substring of bstr as a UTF-8 encoding of Unicode code + points. If err-char is not #f, then it is used for + bytes that fall in the range 128 to 255 but are + not part of a valid encoding sequence. (This rule is consistent with + reading characters from a port; see Encodings and Locales for more + details.) If err-char is #f, and if the + start to end substring of bstr is not a + valid UTF-8 encoding overall, then the exn:fail:contract exception is raised.

Example:
> (bytes->string/utf-8 (bytes 195 167 195 176 195 182 194 163))

"çðö£"

procedure

(bytes->string/locale bstr    
  [err-char    
  start    
  end])  string?
  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Produces a string by decoding the start to end substring +of bstr using the current locale’s encoding (see also +Encodings and Locales). If err-char is not +#f, it is used for each byte in bstr that is not part +of a valid encoding; if err-char is #f, and if the +start to end substring of bstr is not a valid +encoding overall, then the exn:fail:contract exception is raised.

procedure

(bytes->string/latin-1 bstr    
  [err-char    
  start    
  end])  string?
  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Produces a string by decoding the start to end substring + of bstr as a Latin-1 encoding of Unicode code points; i.e., + each byte is translated directly to a character using + integer->char, so the decoding always succeeds. + The err-char + argument is ignored, but present for consistency with the other + operations.

Example:
> (bytes->string/latin-1 (bytes 254 211 209 165))

"þÓÑ¥"

procedure

(string->bytes/utf-8 str [err-byte start end])  bytes?

  str : string?
  err-byte : (or/c #f byte?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Produces a byte string by encoding the start to end + substring of str via UTF-8 (always succeeding). The + err-byte argument is ignored, but included for consistency with + the other operations. +

Examples:
> (define b
    (bytes->string/utf-8
     (bytes 195 167 195 176 195 182 194 163)))
> (string->bytes/utf-8 b)

#"\303\247\303\260\303\266\302\243"

> (bytes->string/utf-8 (string->bytes/utf-8 b))

"çðö£"

procedure

(string->bytes/locale str [err-byte start end])  bytes?

  str : string?
  err-byte : (or/c #f byte?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Produces a string by encoding the start to end substring +of str using the current locale’s encoding (see also +Encodings and Locales). If err-byte is not #f, it is used +for each character in str that cannot be encoded for the +current locale; if err-byte is #f, and if the +start to end substring of str cannot be encoded, +then the exn:fail:contract exception is raised.

procedure

(string->bytes/latin-1 str    
  [err-byte    
  start    
  end])  bytes?
  str : string?
  err-byte : (or/c #f byte?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Produces a string by encoding the start to end substring + of str using Latin-1; i.e., each character is translated + directly to a byte using char->integer. If err-byte is + not #f, it is used for each character in str whose + value is greater than 255. + If err-byte is #f, and if the + start to end substring of str has a character + with a value greater than 255, then the + exn:fail:contract exception is raised.

Examples:
> (define b
    (bytes->string/latin-1 (bytes 254 211 209 165)))
> (string->bytes/latin-1 b)

#"\376\323\321\245"

> (bytes->string/latin-1 (string->bytes/latin-1 b))

"þÓÑ¥"

procedure

(string-utf-8-length str [start end])  exact-nonnegative-integer?

  str : string?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (string-length str)
Returns the length in bytes of the UTF-8 encoding of str’s + substring from start to end, but without actually + generating the encoded bytes.

Examples:
> (string-utf-8-length
    (bytes->string/utf-8 (bytes 195 167 195 176 195 182 194 163)))

8

> (string-utf-8-length "hello")

5

procedure

(bytes-utf-8-length bstr [err-char start end])

  (or/c exact-nonnegative-integer? #f)
  bstr : bytes?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Returns the length in characters of the UTF-8 decoding of + bstr’s substring from start to end, but without + actually generating the decoded characters. If err-char is + #f and the substring is not a UTF-8 encoding overall, the + result is #f. Otherwise, err-char is used to resolve + decoding errors as in bytes->string/utf-8.

Examples:
> (bytes-utf-8-length (bytes 195 167 195 176 195 182 194 163))

4

> (bytes-utf-8-length (make-bytes 5 65))

5

procedure

(bytes-utf-8-ref bstr [skip err-char start end])  (or/c char? #f)

  bstr : bytes?
  skip : exact-nonnegative-integer? = 0
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Returns the skipth character in the UTF-8 decoding of + bstr’s substring from start to end, but without + actually generating the other decoded characters. If the substring is + not a UTF-8 encoding up to the skipth character (when + err-char is #f), or if the substring decoding produces + fewer than skip characters, the result is #f. If + err-char is not #f, it is used to resolve decoding + errors as in bytes->string/utf-8.

Examples:
> (bytes-utf-8-ref (bytes 195 167 195 176 195 182 194 163) 0)

#\ç

> (bytes-utf-8-ref (bytes 195 167 195 176 195 182 194 163) 1)

#\ð

> (bytes-utf-8-ref (bytes 195 167 195 176 195 182 194 163) 2)

#\ö

> (bytes-utf-8-ref (bytes 65 66 67 68) 0)

#\A

> (bytes-utf-8-ref (bytes 65 66 67 68) 1)

#\B

> (bytes-utf-8-ref (bytes 65 66 67 68) 2)

#\C

procedure

(bytes-utf-8-index bstr 
  skip 
  [err-char 
  start 
  end]) 
  (or/c exact-nonnegative-integer? #f)
  bstr : bytes?
  skip : exact-nonnegative-integer?
  err-char : (or/c #f char?) = #f
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Returns the offset in bytes into bstr at which the skipth + character’s encoding starts in the UTF-8 decoding of bstr’s + substring from start to end (but without actually + generating the other decoded characters). The result is relative to + the start of bstr, not to start. If the substring is not + a UTF-8 encoding up to the skipth character (when + err-char is #f), or if the substring decoding produces + fewer than skip characters, the result is #f. If + err-char is not #f, it is used to resolve decoding + errors as in bytes->string/utf-8.

Examples:
> (bytes-utf-8-index (bytes 195 167 195 176 195 182 194 163) 0)

0

> (bytes-utf-8-index (bytes 195 167 195 176 195 182 194 163) 1)

2

> (bytes-utf-8-index (bytes 195 167 195 176 195 182 194 163) 2)

4

> (bytes-utf-8-index (bytes 65 66 67 68) 0)

0

> (bytes-utf-8-index (bytes 65 66 67 68) 1)

1

> (bytes-utf-8-index (bytes 65 66 67 68) 2)

2

4.5.4 Bytes to Bytes Encoding Conversion

procedure

(bytes-open-converter from-name to-name)

  (or/c bytes-converter? #f)
  from-name : string?
  to-name : string?
Produces a byte converter to go from the encoding named by +from-name to the encoding named by to-name. If the +requested conversion pair is not available, #f is returned +instead of a converter.

Certain encoding combinations are always available:

  • (bytes-open-converter "UTF-8" "UTF-8") the +identity conversion, except that encoding errors in the input lead +to a decoding failure.

  • (bytes-open-converter "UTF-8-permissive" "UTF-8") +the identity conversion, except that +any input byte that is not part of a valid encoding sequence is +effectively replaced by the UTF-8 encoding sequence for +#\uFFFD. (This handling of invalid sequences is +consistent with the interpretation of port bytes streams into +characters; see Ports.)

  • (bytes-open-converter "" "UTF-8") converts from +the current locale’s default encoding (see Encodings and Locales) +to UTF-8.

  • (bytes-open-converter "UTF-8" "") converts from +UTF-8 to the current locale’s default encoding (see +Encodings and Locales).

  • (bytes-open-converter "platform-UTF-8" "platform-UTF-16") +— converts UTF-8 to UTF-16 on Unix and Mac OS, where each UTF-16 +code unit is a sequence of two bytes ordered by the current +platform’s endianness. On Windows, the conversion is the same +as (bytes-open-converter "WTF-8" "WTF-16") to support +unpaired surrogate code units.

  • (bytes-open-converter "platform-UTF-8-permissive" "platform-UTF-16") +— like (bytes-open-converter "platform-UTF-8" "platform-UTF-16"), +but an input byte that is not part of a valid UTF-8 encoding +sequence (or valid for the unpaired-surrogate extension on +Windows) is effectively replaced with #\uFFFD.

  • (bytes-open-converter "platform-UTF-16" "platform-UTF-8") +— converts UTF-16 (bytes ordered by the current platform’s +endianness) to UTF-8 on Unix and Mac OS. On Windows, the conversion +is the same as (bytes-open-converter "WTF-16" "WTF-8") +to support unpaired surrogates. On Unix and Mac OS, surrogates are +assumed to be paired: a pair of bytes with the bits #xD800 +starts a surrogate pair, and the #x03FF bits are used from +the pair and following pair (independent of the value of the +#xDC00 bits). On all platforms, performance may be poor +when decoding from an odd offset within an input byte string.

  • (bytes-open-converter "WTF-8" "WTF-16") +— converts the WTF-8 [Sapin18] superset of UTF-8 to a +superset of UTF-16 to support unpaired surrogate code units, where +each UTF-16 code unit is a sequence of two bytes ordered by the +current platform’s endianness.

  • (bytes-open-converter "WTF-8-permissive" "WTF-16") +— like (bytes-open-converter "WTF-8" "WTF-16"), +but an input byte that is not part of a valid WTF-8 encoding +sequence is effectively replaced with #\uFFFD.

  • (bytes-open-converter "WTF-16" "WTF-8") +— converts the WTF-16 [Sapin18] superset of UTF-16 to the +WTF-8 superset of UTF-8. The input can include UTF-16 code units +that are unpaired surrogates, and the corresponding output includes +an encoding of each surrogate in a natural extension of UTF-8.

A newly opened byte converter is registered with the current custodian +(see Custodians), so that the converter is closed when +the custodian is shut down. A converter is not registered with a +custodian (and does not need to be closed) if it is one of the +guaranteed combinations not involving "" on Unix, or if it +is any of the guaranteed combinations (including "") on +Windows and Mac OS.

In the Racket software distributions for Windows, a suitable +"iconv.dll" is included with "libmzschVERS.dll".

The set of available encodings and combinations varies by platform, +depending on the iconv library that is installed; the +from-name and to-name arguments are passed on to +iconv_open. On Windows, "iconv.dll" or +"libiconv.dll" must be in the same directory as +"libmzschVERS.dll" (where VERS is a version +number), in the user’s path, in the system directory, or in the +current executable’s directory at run time, and the DLL must either +supply _errno or link to "msvcrt.dll" for _errno; +otherwise, only the guaranteed combinations are available.

Use bytes-convert with the result to convert byte strings.

Changed in version 7.9.0.17 of package base: Added built-in converters for +"WTF-8", +"WTF-8-permissive", and +"WTF-16".

procedure

(bytes-close-converter converter)  void

  converter : bytes-converter?
Closes the given converter, so that it can no longer be used with +bytes-convert or bytes-convert-end.

procedure

(bytes-convert converter 
  src-bstr 
  [src-start-pos 
  src-end-pos 
  dest-bstr 
  dest-start-pos 
  dest-end-pos]) 
  
(or/c bytes? exact-nonnegative-integer?)
exact-nonnegative-integer?
(or/c 'complete 'continues 'aborts 'error)
  converter : bytes-converter?
  src-bstr : bytes?
  src-start-pos : exact-nonnegative-integer? = 0
  src-end-pos : exact-nonnegative-integer?
   = (bytes-length src-bstr)
  dest-bstr : (or/c bytes? #f) = #f
  dest-start-pos : exact-nonnegative-integer? = 0
  dest-end-pos : (or/c exact-nonnegative-integer? #f)
   = 
(and dest-bstr
     (bytes-length dest-bstr))
Converts the bytes from src-start-pos to src-end-pos +in src-bstr.

If dest-bstr is not #f, the converted bytes are +written into dest-bstr from dest-start-pos to +dest-end-pos. If dest-bstr is #f, then a +newly allocated byte string holds the conversion results, and if +dest-end-pos is not #f, the size of the result byte +string is no more than (- dest-end-pos dest-start-pos).

The result of bytes-convert is three values:

  • result-bstr or dest-wrote-amt a byte +string if dest-bstr is #f or not provided, or the +number of bytes written into dest-bstr otherwise.

  • src-read-amt the number of bytes successfully converted +from src-bstr.

  • 'complete, 'continues, +'aborts, or 'error indicates +how conversion terminated:

    • 'complete: The entire input was processed, and +src-read-amt will be equal to (- src-end-pos src-start-pos).

    • 'continues: Conversion stopped due to the limit on +the result size or the space in dest-bstr; in this case, +fewer than (- dest-end-pos dest-start-pos) bytes may be +returned if more space is needed to process the next complete +encoding sequence in src-bstr.

    • 'aborts: The input stopped part-way through an +encoding sequence, and more input bytes are necessary to continue. +For example, if the last byte of input is 195 for a +"UTF-8-permissive" decoding, the result is +'aborts, because another byte is needed to determine how to +use the 195 byte.

    • 'error: The bytes starting at (+ src-start-pos src-read-amt) bytes in src-bstr do not form +a legal encoding sequence. This result is never produced for some +encodings, where all byte sequences are valid encodings. For +example, since "UTF-8-permissive" handles an invalid UTF-8 +sequence by dropping characters or generating “?,” every byte +sequence is effectively valid.

Applying a converter accumulates state in the converter (even when the +third result of bytes-convert is 'complete). This +state can affect both further processing of input and further +generation of output, but only for conversions that involve “shift +sequences” to change modes within a stream. To terminate an input +sequence and reset the converter, use bytes-convert-end.

Examples:
> (define convert (bytes-open-converter "UTF-8" "UTF-16"))
> (bytes-convert convert (bytes 65 66 67 68))

#"\377\376A\0B\0C\0D\0"

4

'complete

> (bytes 195 167 195 176 195 182 194 163)

#"\303\247\303\260\303\266\302\243"

> (bytes-convert convert (bytes 195 167 195 176 195 182 194 163))

#"\347\0\360\0\366\0\243\0"

8

'complete

> (bytes-close-converter convert)

procedure

(bytes-convert-end converter 
  [dest-bstr 
  dest-start-pos 
  dest-end-pos]) 
  
(or/c bytes? exact-nonnegative-integer?)
(or/c 'complete 'continues)
  converter : bytes-converter?
  dest-bstr : (or/c bytes? #f) = #f
  dest-start-pos : exact-nonnegative-integer? = 0
  dest-end-pos : (or/c exact-nonnegative-integer? #f)
   = 
(and dest-bstr
     (bytes-length dest-bstr))
Like bytes-convert, but instead of converting bytes, this +procedure generates an ending sequence for the conversion (sometimes +called a “shift sequence”), if any. Few encodings use shift +sequences, so this function will succeed with no output for most +encodings. In any case, successful output of a (possibly empty) shift +sequence resets the converter to its initial state.

The result of bytes-convert-end is two values:

  • result-bstr or dest-wrote-amt a byte string if +dest-bstr is #f or not provided, or the number of +bytes written into dest-bstr otherwise.

  • 'complete or 'continues +indicates whether conversion completed. If 'complete, then +an entire ending sequence was produced. If 'continues, then +the conversion could not complete due to the limit on the result +size or the space in dest-bstr, and the first result is +either an empty byte string or 0.

procedure

(bytes-converter? v)  boolean?

  v : any/c
Returns #t if v is a byte converter produced +by bytes-open-converter, #f otherwise.

Examples:
> (bytes-converter? (bytes-open-converter "UTF-8" "UTF-16"))

#t

> (bytes-converter? (bytes-open-converter "whacky" "not likely"))

#f

> (define b (bytes-open-converter "UTF-8" "UTF-16"))
> (bytes-close-converter b)
> (bytes-converter? b)

#t

procedure

(locale-string-encoding)  any

Returns a string for the current locale’s encoding (i.e., the encoding +normally identified by ""). See also +system-language+country.

4.5.5 Additional Byte String Functions

 (require racket/bytes) package: base
The bindings documented in this section are provided by the racket/bytes and racket libraries, but not racket/base.

procedure

(bytes-append* str ... strs)  bytes?

  str : bytes?
  strs : (listof bytes?)
Like bytes-append, but the last argument is used as a list +of arguments for bytes-append, so (bytes-append* str ... strs) is the same as (apply bytes-append str ... strs). In other words, the relationship between +bytes-append and bytes-append* is similar to the +one between list and list*.

Examples:
> (bytes-append* #"a" #"b" '(#"c" #"d"))

#"abcd"

> (bytes-append* (cdr (append* (map (lambda (x) (list #", " x))
                                     '(#"Alpha" #"Beta" #"Gamma")))))

#"Alpha, Beta, Gamma"

procedure

(bytes-join strs sep)  bytes?

  strs : (listof bytes?)
  sep : bytes?
Appends the byte strings in strs, inserting sep between +each pair of bytes in strs.

Example:
> (bytes-join '(#"one" #"two" #"three" #"four") #" potato ")

#"one potato two potato three potato four"

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/case.html b/clones/docs.racket-lang.org/reference/case.html new file mode 100644 index 00000000..1e7a8ad9 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/case.html @@ -0,0 +1,14 @@ + +3.13 Dispatch: case
On this page:
case

3.13 Dispatch: case

syntax

(case val-expr case-clause ...)

 
case-clause = [(datum ...) then-body ...+]
  | [else then-body ...+]
Evaluates val-expr and uses the result to select a +case-clause. The selected clause is the first one with a +datum whose quoted form is equal? to the +result of val-expr. If no such datum is present, the +else case-clause is selected; if no else +case-clause is present, either, then the result of the +case form is #<void>.

The case +form of racket differs from that of R6RS: Scheme or R5RS: Legacy Scheme by being based on equal? instead of +eqv? (in addition to allowing internal definitions).

For the selected case-clause, the results of the last +then-body, which is in tail position with respect to the +case form, are the results for the whole case form.

A case-clause that starts with else must be the last +case-clause.

The case form can dispatch to a matching case-clause +in O(log N) time for N datums.

Examples:
> (case (+ 7 5)
   [(1 2 3) 'small]
   [(10 11 12) 'big])

'big

> (case (- 7 5)
   [(1 2 3) 'small]
   [(10 11 12) 'big])

'small

> (case (string-append "do" "g")
   [("cat" "dog" "mouse") "animal"]
   [else "mineral or vegetable"])

"animal"

> (case (list 'y 'x)
   [((a b) (x y)) 'forwards]
   [((b a) (y x)) 'backwards])

'backwards

> (case 'x
   [(x) "ex"]
   [('x) "quoted ex"])

"ex"

> (case (list 'quote 'x)
   [(x) "ex"]
   [('x) "quoted ex"])

"quoted ex"

 

(define (classify c)
  (case (char-general-category c)
   [(ll lu lt ln lo) "letter"]
   [(nd nl no) "number"]
   [else "other"]))

 

> (classify #\A)

"letter"

> (classify #\1)

"number"

> (classify #\!)

"other"

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/channel.html b/clones/docs.racket-lang.org/reference/channel.html new file mode 100644 index 00000000..85f2b640 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/channel.html @@ -0,0 +1,25 @@ + +11.2.2 Channels
11.2.2 Channels

A channel both synchronizes a pair of threads and passes a +value from one to the other. Channels are synchronous; both the sender +and the receiver must block until the (atomic) transaction is +complete. Multiple senders and receivers can access a channel at once, +but a single sender and receiver is selected for each transaction.

Channel synchronization is fair: if a thread is blocked on a +channel and transaction opportunities for the channel occur infinitely +often, then the thread eventually participates in a transaction.

In addition to its use with channel-specific procedures, a channel can +be used as a synchronizable event (see Events). A +channel is ready for synchronization when channel-get +would not block; the channel’s synchronization result is the +same as the channel-get result.

For buffered asynchronous channels, see Buffered Asynchronous Channels.

procedure

(channel? v)  boolean?

  v : any/c
Returns #t if v is a channel, +#f otherwise.

procedure

(make-channel)  channel?

Creates and returns a new channel. The channel can be used with +channel-get, with channel-try-get, or as a +synchronizable event (see Events) to receive a value +through the channel. The channel can be used with channel-put +or through the result of channel-put-evt to send a value +through the channel.

procedure

(channel-get ch)  any

  ch : channel?
Blocks until a sender is ready to provide a value through +ch. The result is the sent value.

procedure

(channel-try-get ch)  any

  ch : channel?
Receives and returns a value from ch if a sender is +immediately ready, otherwise returns #f.

procedure

(channel-put ch v)  void?

  ch : channel?
  v : any/c
Blocks until a receiver is ready to accept the value v +through ch.

procedure

(channel-put-evt ch v)  channel-put-evt?

  ch : channel?
  v : any/c
Returns a fresh synchronizable event for use with +sync. The event is ready for synchronization when +(channel-put ch v) would not block, and the event’s +synchronization result is the event itself.

procedure

(channel-put-evt? v)  boolean?

  v : any/c
Returns #t if v is a channel-put event produced by +channel-put-evt, #f otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/chaperones.html b/clones/docs.racket-lang.org/reference/chaperones.html new file mode 100644 index 00000000..9ba3a728 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/chaperones.html @@ -0,0 +1,469 @@ + +14.5 Impersonators and Chaperones

14.5 Impersonators and Chaperones

An impersonator is a wrapper for a value where the wrapper +redirects some of the value’s operations. Impersonators apply only to procedures, +structures for which an accessor or mutator is available, +structure types, hash tables, vectors, +boxes, channels, and prompt tags. +An impersonator is equal? to the original +value, but not eq? to the original value.

A chaperone is a kind of impersonator whose refinement of a value’s +operation is restricted to side effects (including, in particular, +raising an exception) or chaperoning values supplied to or produced by +the operation. For example, a vector chaperone can redirect +vector-ref to raise an exception if the accessed vector slot +contains a string, or it can cause the result of vector-ref +to be a chaperoned variant of the value that is in the accessed vector +slot, but it cannot redirect vector-ref to produce a value +that is arbitrarily different from the value in the vector slot.

A non-chaperone impersonator, in contrast, can refine an operation to swap one +value for any other. An impersonator cannot be applied to an immutable value +or refine the access to an immutable field in an instance of a structure +type, since arbitrary redirection of an operation amounts to +mutation of the impersonated value.

Beware that each of the following operations can be redirected to an +arbitrary procedure through an impersonator on the operation’s +argument—assuming that the operation is available to the creator of +the impersonator:

Derived operations, such as printing a value, can be redirected +through impersonators due to their use of accessor functions. The +equal?, equal-hash-code, and +equal-secondary-hash-code operations, in contrast, may bypass +impersonators (but they are not obliged to).

In addition to redirecting operations that work on a value, a +impersonator can include impersonator properties for an impersonated +value. An impersonator property is similar to a structure +type property, but it applies to impersonators instead of structure +types and their instances.

procedure

(impersonator? v)  boolean?

  v : any/c
Returns #t if v is an impersonator created by +procedures like impersonate-procedure or +impersonate-struct, #f otherwise.

Programs and libraries generally should avoid impersonator? and +treat impersonators the same as non-impersonator values. In rare cases, +impersonator? may be needed to guard against redirection by an +impersonator of an operation to an arbitrary procedure.

A limitation of impersonator? is that it does not +recognize an impersonator that is created by instantiating a +structure type with the prop:impersonator-of property. The +limitation reflects how those impersonators cannot redirect structure +access and mutation operations to arbitrary procedures.

procedure

(chaperone? v)  boolean?

  v : any/c
Returns #t if v is a chaperone, #f otherwise.

Programs and libraries generally should avoid chaperone? for +the same reason that they should avoid impersonator?. A true +value for chaperone? implies a true value of +impersonator?.

procedure

(impersonator-of? v1 v2)  boolean?

  v1 : any/c
  v2 : any/c
Indicates whether v1 can be considered equivalent modulo +impersonators to v2.

Any two values that are eq? to one another are also impersonator-of?. +For values that include no impersonators, v1 and v2 are +considered impersonators of each other if they are equal?.

If at least one of v1 or v2 is an impersonator: +
  • If v1 impersonates v1* then (impersonator-of? v1 v2) + is #t if and only if (impersonator-of? v1* v2) is #t.

  • If v2 is a non-interposing impersonator that impersonates v2*, i.e., + all of its interposition procedures are #f, then (impersonator-of? v1 v2) + is #t if and only if (impersonator-of? v1 v2*) is #t.

  • When v2 is an impersonator constructed with at least one non-#f interposition procedure, + but v1 is not an impersonator then (impersonator-of? v1 v2) is #f.

Otherwise, if neither v1 or v2 is an impersonator, but either +of them contains an impersonator as a subpart (e.g., v1 is a list with +an impersonator as one of its elements), then (impersonator-of? v1 v2) +proceeds by comparing v1 and v2 recursively (as with +equal?), returning true if all subparts are impersonator-of?.

Examples:
> (impersonator-of? (impersonate-procedure add1 (λ (x) x))
                    add1)

#t

> (impersonator-of? (impersonate-procedure add1 (λ (x) x))
                    sub1)

#f

> (impersonator-of? (impersonate-procedure
                      (impersonate-procedure add1 (λ (x) x)) (λ (x) x))
                    add1)

#t

> (impersonator-of? (impersonate-procedure add1 (λ (x) x))
                    (impersonate-procedure add1 #f))

#t

> (impersonator-of? (impersonate-procedure add1 (λ (x) x))
                    (impersonate-procedure add1 (λ (x) x)))

#f

> (impersonator-of? (list 1 2)
                    (list 1 2))

#t

> (impersonator-of? (list (impersonate-procedure add1 (λ (x) x)) sub1)
                    (list add1 sub1))

#t

procedure

(chaperone-of? v1 v2)  boolean?

  v1 : any/c
  v2 : any/c
Indicates whether v1 can be considered equivalent modulo +chaperones to v2.

For values that include no chaperones or other impersonators, +v1 and v2 can be considered chaperones of each other +if they are equal-always?, which requires that they are +equal? except that corresponding mutable +vectors, boxes, hash tables, strings, byte strings, mutable pairs, and +mutable structures within +v1 and v2 must be eq?.

Otherwise, chaperones and other impersonators within v2 must +be intact within v1 analogous to way that +impersonator-of? requires that impersonators are preserved. +Furthermore, v1 must not have any non-chaperone impersonators +whose corresponding value in v2 is not the same impersonator. +Note that chaperone-of? implies impersonator-of?, +but not vice-versa.

procedure

(impersonator-ephemeron v)  ephemeron?

  v : any/c
Produces an ephemeron that can be used to connect the +reachability of v (in the sense of garbage collection; see +Garbage Collection) with the reachability of any value for which +v is an impersonator. That is, the value v +will be considered reachable as long as the result ephemeron is +reachable in addition to any value that v impersonates +(including itself).

procedure

(procedure-impersonator*? v)  boolean?

  v : any/c
Returns #t for any procedure impersonator that either was produced by +impersonate-procedure* or chaperone-procedure*, or is +an impersonator/chaperone of a value that was created with +impersonate-procedure* or chaperone-procedure* +(possibly transitively).

14.5.1 Impersonator Constructors

procedure

(impersonate-procedure proc 
  wrapper-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c procedure? impersonator?)
  proc : procedure?
  wrapper-proc : (or/c procedure? #f)
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator procedure that has the same arity, name, and +other attributes as proc. When the impersonator procedure is +applied, the arguments are first passed to wrapper-proc +(when it is not #f), and +then the results from wrapper-proc are passed to +proc. The wrapper-proc can also supply a procedure +that processes the results of proc.

The arity of wrapper-proc must include the arity of +proc. The allowed keyword arguments of wrapper-proc +must be a superset of the allowed keywords of proc. The +required keyword arguments of wrapper-proc must be a subset +of the required keywords of proc.

For applications without keywords, the result of wrapper-proc +must be at least the same number of values as supplied to it. +Additional results can be supplied—before the values that correspond +to the supplied values—in the following pattern:

  • An optional procedure, result-wrapper-proc, which +will be applied to the results of proc; followed by

  • any number of repetitions of 'mark key val (i.e., +three values), where the call proc is wrapped to +install a continuation mark key and val.

If result-wrapper-proc is produced, it must be a procedure +that accepts as many results as produced by proc; it must +return the same number of results. If result-wrapper-proc is +not supplied, then proc is called in tail position +with respect to the call to the impersonator.

For applications that include keyword arguments, wrapper-proc +must return an additional value before any other values but after +result-wrapper-proc and 'mark key val +sequences (if any). The additional value must be a +list of replacements for the keyword arguments that were supplied to the +impersonator (i.e., not counting optional arguments that were +not supplied). The arguments must be ordered according to the sorted +order of the supplied arguments’ keywords.

If wrapper-proc is #f, then applying the resulting +impersonator is the same as applying proc. If +wrapper-proc is #f and no prop is provided, then +proc is returned and is not impersonated.

Pairs of prop and prop-val (the number of arguments +to impersonate-procedure must be even) add impersonator properties +or override impersonator-property values of proc.

If any prop is impersonator-prop:application-mark and if the +associated prop-val is a pair, then the call to proc +is wrapped with with-continuation-mark using (car prop-val) as the mark key and (cdr prop-val) as the mark +value. In addition, if the immediate +continuation frame of the call to the impersonated procedure +includes a value for (car prop-val)that is, if +call-with-immediate-continuation-mark would produce a value +for (car prop-val) in the call’s continuation—then the value is +also installed as an immediate value for (car prop-val) as a +mark during the call to wrapper-proc (which allows tail-calls +of impersonators with respect to wrapping impersonators to be detected within +wrapper-proc).

Changed in version 6.3.0.5 of package base: Added support for 'mark key val results from +wrapper-proc.

Examples:
> (define (add15 x) (+ x 15))
> (define add15+print
    (impersonate-procedure add15
                           (λ (x)
                             (printf "called with ~s\n" x)
                             (values (λ (res)
                                       (printf "returned ~s\n" res)
                                       res)
                                     x))))
> (add15 27)

42

> (add15+print 27)

called with 27

returned 42

42

> (define-values (imp-prop:p1 imp-prop:p1? imp-prop:p1-get)
    (make-impersonator-property 'imp-prop:p1))
> (define-values (imp-prop:p2 imp-prop:p2? imp-prop:p2-get)
    (make-impersonator-property 'imp-prop:p2))
> (define add15.2 (impersonate-procedure add15 #f imp-prop:p1 11))
> (add15.2 2)

17

> (imp-prop:p1? add15.2)

#t

> (imp-prop:p1-get add15.2)

11

> (imp-prop:p2? add15.2)

#f

> (define add15.3 (impersonate-procedure add15.2 #f imp-prop:p2 13))
> (add15.3 3)

18

> (imp-prop:p1? add15.3)

#t

> (imp-prop:p1-get add15.3)

11

> (imp-prop:p2? add15.3)

#t

> (imp-prop:p2-get add15.3)

13

> (define add15.4 (impersonate-procedure add15.3 #f imp-prop:p1 101))
> (add15.4 4)

19

> (imp-prop:p1? add15.4)

#t

> (imp-prop:p1-get add15.4)

101

> (imp-prop:p2? add15.4)

#t

> (imp-prop:p2-get add15.4)

13

procedure

(impersonate-procedure* proc 
  wrapper-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c procedure? impersonator?)
  proc : procedure?
  wrapper-proc : (or/c procedure? #f)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-procedure, except that wrapper-proc +receives an additional argument before all other arguments. The +additional argument is the procedure orig-proc that was +originally applied.

If the result of impersonate-procedure* is applied directly, +then orig-proc is that result. If the result is further +impersonated before being applied, however, orig-proc is the +further impersonator.

An orig-proc argument might be useful so that +wrapper-proc can extract impersonator properties +that are overridden by further impersonators, for example.

Added in version 6.1.1.5 of package base.

procedure

(impersonate-struct v    
  [struct-type]    
  orig-proc    
  redirect-proc ...    
  ...    
  prop    
  prop-val ...    
  ...)  any/c
  v : any/c
  struct-type : struct-type? = unspecified
  orig-proc : 
(or/c struct-accessor-procedure?
      struct-mutator-procedure?
      struct-type-property-accessor-procedure?)
  redirect-proc : (or/c procedure? #f)
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator of v, which redirects certain +operations on the impersonated value. The orig-procs +indicate the operations to redirect, and the corresponding +redirect-procs supply the redirections. The optional +struct-type argument, when provided, acts as a witness for +the representation of v, which must be an instance of +struct-type.

The protocol for a redirect-proc depends on the corresponding +orig-proc, where self refers to the value to which +orig-proc is originally applied:

  • A structure-field accessor: redirect-proc +must accept two arguments, self and the value +field-v that orig-proc produces for +v; it must return a replacement for +field-v. The corresponding field must not be +immutable, and either the field’s structure type must be +accessible via the current inspector or one of the other +orig-procs must be a structure-field mutator for the +same field.

  • A structure-field mutator: redirect-proc must accept +two arguments, self and the value field-v +supplied to the mutator; it must return a replacement for +field-v to be propagated to orig-proc and +v.

  • A property accessor: redirect-proc uses the same +protocol as for a structure-field accessor. The accessor’s +property must have been created with 'can-impersonate +as the second argument to make-struct-type-property.

When a redirect-proc is #f, the corresponding +orig-proc is unaffected. Supplying #f for a +redirect-proc is useful to allow its orig-proc to +act as a “witness” of v’s representation and enable the +addition of props.

Pairs of prop and prop-val (the number of arguments +to impersonate-struct must be even if struct-type +is provided, odd otherwise) add impersonator properties +or override impersonator-property values of v.

Each orig-proc must indicate a distinct operation. If no +struct-type and no orig-procs are supplied, then no props must be +supplied. If orig-procs are supplied only with #f +redirect-procs and no props are supplied, then +v is returned and is not impersonated.

If any orig-proc is itself an impersonator, then a use of the +accessor or mutator that orig-proc impersonates is redirected +for the resulting impersonated structure to use orig-proc on +v before redirect-proc (in the case of accessor) or +after redirect-proc (in the case of a mutator).

Changed in version 6.1.1.2 of package base: Changed first argument to an +accessor or mutator +redirect-proc from +v to self.
Changed in version 6.1.1.8: Added optional struct-type +argument.

procedure

(impersonate-vector vec 
  ref-proc 
  set-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c vector? impersonator?)
  vec : (and/c vector? (not/c immutable?))
  ref-proc : (or/c (vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  set-proc : (or/c (vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator of vec, which redirects the +vector-ref and vector-set! operations.

The ref-proc and set-proc arguments must either both be procedures +or both be #f. If they are #f then impersonate-vector does not interpose +on vec, but still allows attaching impersonator properties.

If ref-proc is a procedure it must accept vec, an index passed to +vector-ref, and the value that vector-ref on +vec produces for the given index; it must produce a +replacement for the value, which is the result of vector-ref +on the impersonator.

If set-proc is a procedure it must accept vec, an index passed to +vector-set!, and the value passed to vector-set!; it +must produce a replacement for the value, which is used +with vector-set! on the original vec to install the +value.

Pairs of prop and prop-val (the number of arguments +to impersonate-vector must be odd) add impersonator properties +or override impersonator-property values of vec.

Changed in version 6.9.0.2 of package base: Added non-interposing vector impersonators.

procedure

(impersonate-vector* vec 
  ref-proc 
  set-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c vector? impersonator?)
  vec : (and/c vector? (not/c immutable?))
  ref-proc : (or/c (vector? vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  set-proc : (or/c (vector? vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-vector, except that ref-proc and set-proc each receive +an additional vector as argument before other arguments. The additional argument is the original +impersonated vector, access to which triggered interposition in the first place.

The additional vector argument might be useful so that ref-proc or set-proc +can extract impersonator properties that are overridden by further impersonators, for example.

Added in version 6.9.0.2 of package base.

procedure

(impersonate-box box    
  unbox-proc    
  set-proc    
  prop    
  prop-val ...    
  ...)  (and/c box? impersonator?)
  box : (and/c box? (not/c immutable?))
  unbox-proc : (box? any/c . -> . any/c)
  set-proc : (box? any/c . -> . any/c)
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator of box, which redirects the +unbox and set-box! operations.

The unbox-proc must accept box and the value that +unbox produces on box; it must produce a replacement +value, which is the result of unbox on the impersonator.

The set-proc must accept box and the value passed to +set-box!; it must produce a replacement +value, which is used with set-box! on the original +box to install the value.

Pairs of prop and prop-val (the number of arguments +to impersonate-box must be odd) add impersonator properties +or override impersonator-property values of box.

procedure

(impersonate-hash hash    
  ref-proc    
  set-proc    
  remove-proc    
  key-proc    
  [clear-proc    
  equal-key-proc]    
  prop    
  prop-val ...    
  ...)  (and/c hash? impersonator?)
  hash : (and/c hash? (not/c immutable?))
  ref-proc : 
(hash? any/c . -> . (values
                     any/c
                     (hash? any/c any/c . -> . any/c)))
  set-proc : (hash? any/c any/c . -> . (values any/c any/c))
  remove-proc : (hash? any/c . -> . any/c)
  key-proc : (hash? any/c . -> . any/c)
  clear-proc : (or/c #f (hash? . -> . any)) = #f
  equal-key-proc : (or/c #f (hash? any/c . -> . any/c)) = #f
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator of hash, which redirects the +hash-ref, hash-set! or hash-set (as +applicable), hash-remove or hash-remove! (as +applicable), hash-clear or hash-clear! (as +applicable and if clear-proc is not #f) operations. When +hash-set, hash-remove or hash-clear is used on an impersonator of a hash +table, the result is an impersonator with the same redirecting procedures. +In addition, operations like +hash-iterate-key or hash-map, which extract +keys from the table, use key-proc to replace keys extracted +from the table. Operations like hash-iterate-value or +hash-values implicitly use hash-ref and +therefore redirect through ref-proc. The hash-ref-key +operation uses both ref-proc and key-proc, the +former to lookup the requested key and the latter to extract it.

The ref-proc must accept hash and a key passed +to hash-ref. It must return a replacement key +as well as a procedure. The returned procedure is called only if the +returned key is found in hash via hash-ref, in which +case the procedure is called with hash, the previously +returned key, and the found value. The returned procedure must itself +return a replacement for the found value. The returned procedure +is ignored by hash-ref-key.

The set-proc must accept hash, a key passed to +hash-set! or hash-set, and the value passed to +hash-set! or hash-set; it must produce two values: a +replacement for the key and a replacement for the value. The returned +key and value are used with hash-set! or hash-set on +the original hash to install the value.

The remove-proc must accept hash and a key passed to +hash-remove! or hash-remove; it must produce a +replacement for the key, which is used with hash-remove! or +hash-remove on the original hash to remove any +mapping using the (impersonator-replaced) key.

The key-proc must accept hash and a key that has +been extracted from hash (by hash-ref-key, +hash-iterate-key, or other operations that use +hash-iterate-key internally); it must produce a replacement +for the key, which is then reported as a key extracted from the table.

If clear-proc is not #f, it must accept +hash as an argument, and its result is ignored. The fact that +clear-proc returns (as opposed to raising an exception or +otherwise escaping) grants the capability to remove all keys from hash. +If clear-proc is #f, then hash-clear or +hash-clear! on the impersonator is implemented using +hash-iterate-key and hash-remove or hash-remove!.

If equal-key-proc is not #f, it effectively +interposes on calls to equal?, equal-hash-code, and +equal-secondary-hash-code for the keys of hash. The +equal-key-proc must accept as its arguments hash and +a key that is either mapped by hash or passed to +hash-ref, etc., where the latter has potentially been +adjusted by the corresponding ref-proc, etc. The result +is a value that is passed to equal?, +equal-hash-code, and equal-secondary-hash-code as +needed to hash and compare keys. In the case of hash-set! or +hash-set, the key that is passed to equal-key-proc +is the one stored in the hash table for future lookup.

The hash-iterate-value, hash-map, or +hash-for-each functions use a combination of +hash-iterate-key and hash-ref. If a key +produced by key-proc does not yield a value through +hash-ref, then the exn:fail:contract exception is raised.

Pairs of prop and prop-val add impersonator properties +or override impersonator-property values of hash.

In the case of an immutable hash table, two impersonated hash tables count as +“the same value” (for purposes of impersonator-of?) when their +redirection procedures were originally attached to a hash table by the same +call to impersonate-hash or chaperone-hash (and potentially +propagated by hash-set, hash-remove, or hash-clear), +as long as the content of the first hash table is impersonator-of? of +the second hash table.

Changed in version 6.3.0.11 of package base: Added the equal-key-proc +argument.

procedure

(impersonate-channel channel 
  get-proc 
  put-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c channel? impersonator?)
  channel : channel?
  get-proc : (channel? . -> . (values channel? (any/c . -> . any/c)))
  put-proc : (channel? any/c . -> . any/c)
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator of channel, which redirects the +channel-get and channel-put operations.

The get-proc generator is called on channel-get +or any other operation that fetches results from the channel (such +as a sync on the channel). The get-proc must return +two values: a channel that is an impersonator of channel, and a +procedure that is used to check the channel’s contents.

The put-proc must accept channel and the value passed to +channel-put; it must produce a replacement +value, which is used with channel-put on the original +channel to send the value over the channel.

Pairs of prop and prop-val (the number of arguments +to impersonate-channel must be odd) add impersonator properties +or override impersonator-property values of channel.

procedure

(impersonate-prompt-tag prompt-tag 
  handle-proc 
  abort-proc 
  [cc-guard-proc 
  callcc-impersonate-proc] 
  prop 
  prop-val ... 
  ...) 
  (and/c continuation-prompt-tag? impersonator?)
  prompt-tag : continuation-prompt-tag?
  handle-proc : procedure?
  abort-proc : procedure?
  cc-guard-proc : procedure? = values
  callcc-impersonate-proc : (procedure? . -> . procedure?)
   = (lambda (p) p)
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator of prompt-tag, which redirects +the call-with-continuation-prompt and +abort-current-continuation operations.

The handle-proc must accept the values that the handler +of a continuation prompt would take and it must produce replacement +values, which will be passed to the handler.

The abort-proc must accept the values passed to +abort-current-continuation; it must produce replacement +values, which are aborted to the appropriate prompt.

The cc-guard-proc must accept the values produced by +call-with-continuation-prompt in the case that a +non-composable continuation is applied to replace the continuation +that is delimited by the prompt, but only if +abort-current-continuation is not later used to abort the +continuation delimited by the prompt (in which case +abort-proc is used).

The callcc-impersonate-proc must accept a procedure that +guards the result of a continuation captured by +call-with-current-continuation with the impersonated prompt +tag. The callcc-impersonate-proc is applied (under a +continuation barrier) when the captured continuation is applied +to refine a guard function (initially values) that is +specific to the delimiting prompt; this prompt-specific guard is +ultimately composed with any cc-guard-proc that is in effect +at the delimiting prompt, and it is not used in the same case that a +cc-guard-proc is not used (i.e., when +abort-current-continuation is used to abort to the +prompt). In the special case where the delimiting prompt at +application time is a thread’s built-in initial prompt, +callcc-impersonate-proc is ignored (partly on the grounds +that the initial prompt’s result is ignored).

Pairs of prop and prop-val (the number of arguments +to impersonate-prompt-tag must be odd) add impersonator properties +or override impersonator-property values of prompt-tag.

Examples:
> (define tag
    (impersonate-prompt-tag
     (make-continuation-prompt-tag)
     (lambda (n) (* n 2))
     (lambda (n) (+ n 1))))
> (call-with-continuation-prompt
    (lambda ()
      (abort-current-continuation tag 5))
    tag
    (lambda (n) n))

12

procedure

(impersonate-continuation-mark-key key 
  get-proc 
  set-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c continuation-mark? impersonator?)
  key : continuation-mark-key?
  get-proc : procedure?
  set-proc : procedure?
  prop : impersonator-property?
  prop-val : any/c
Returns an impersonator of key, which redirects +with-continuation-mark and continuation mark accessors such +as continuation-mark-set->list.

The get-proc must accept the value attached to a +continuation mark and it must produce a replacement +value, which will be returned by the continuation mark accessor.

The set-proc must accept a value passed to +with-continuation-mark; it must produce a replacement +value, which is attached to the continuation frame.

Pairs of prop and prop-val (the number of arguments +to impersonate-continuation-mark-key must be odd) add impersonator properties +or override impersonator-property values of key.

Examples:
> (define mark-key
    (impersonate-continuation-mark-key
     (make-continuation-mark-key)
     (lambda (l) (map char-upcase l))
     (lambda (s) (string->list s))))
> (with-continuation-mark mark-key "quiche"
    (continuation-mark-set-first
     (current-continuation-marks)
     mark-key))

'(#\Q #\U #\I #\C #\H #\E)

A structure type property (see Structure Type Properties) that +supplies a procedure for extracting an impersonated value from a structure +that represents an impersonator. The property is used for impersonator-of? +as well as equal?.

The property value must be a procedure of one argument, which is a +structure whose structure type has the property. The result can be +#f to indicate the structure does not represent an impersonator, +otherwise the result is a value for which the original structure is an +impersonator (so the original structure is an impersonator-of? and +equal? to the result value). The result value must have the +same prop:impersonator-of and prop:equal+hash property +values as the original structure, if any, and the property values must be +inherited from the same structure type (which ensures some consistency +between impersonator-of? and equal?).

Impersonator property predicates and accessors applied to a +structure with the prop:impersonator-of property first check +for the property on the immediate structure, and if it is not found, +the value produced by the prop:impersonator-of procedure is +checked (recursively).

Changed in version 6.1.1.8 of package base: Made impersonator property +predicates and accessors sensitive +to prop:impersonator-of.

A structure type property that declares a structure type as +authentic. The value associated with the property is ignored; +the presence of the property itself makes the structure type +authentic.

Instances of an authentic structure type cannot be impersonated +via impersonate-struct or chaperoned via +chaperone-struct. As a consequence, an instance of an +authentic structure type can be given a contract (see +struct/c) only if it is a flat contract.

Declaring a structure type as authentic can prevent unwanted +structure impersonation, but exposed structure types normally should +support impersonators or chaperones to facilitate contracts. Declaring +a structure type as authentic can also slightly improve the +performance of structure predicates, selectors, and mutators, which +can be appropriate for data structures that are private +and frequently used within a library.

Added in version 6.9.0.4 of package base.

14.5.2 Chaperone Constructors

procedure

(chaperone-procedure proc 
  wrapper-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c procedure? chaperone?)
  proc : procedure?
  wrapper-proc : (or/c procedure? #f)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-procedure, but for each value supplied to +wrapper-proc, the corresponding result must be the same or a +chaperone of (in the sense of chaperone-of?) the supplied +value. The additional result, if any, that precedes the chaperoned +values must be a procedure that accepts as many results as produced by +proc; it must return the same number of results, each of +which is the same or a chaperone of the corresponding original result.

For applications that include keyword arguments, wrapper-proc +must return an additional value before any other values but after the +result-chaperoning procedure (if any). The additional value must be a +list of chaperones of the keyword arguments that were supplied to the +chaperone procedure (i.e., not counting optional arguments that were +not supplied). The arguments must be ordered according to the sorted +order of the supplied arguments’ keywords.

procedure

(chaperone-procedure* proc 
  wrapper-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c procedure? chaperone?)
  proc : procedure?
  wrapper-proc : (or/c procedure? #f)
  prop : impersonator-property?
  prop-val : any/c
Like chaperone-procedure, but wrapper-proc receives +an extra argument as with impersonate-procedure*.

Added in version 6.1.1.5 of package base.

procedure

(chaperone-struct v    
  [struct-type]    
  orig-proc    
  redirect-proc ...    
  ...    
  prop    
  prop-val ...    
  ...)  any/c
  v : any/c
  struct-type : struct-type? = unspecified
  orig-proc : 
(or/c struct-accessor-procedure?
      struct-mutator-procedure?
      struct-type-property-accessor-procedure?
      (one-of/c struct-info))
  redirect-proc : (or/c procedure? #f)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-struct, but with the following refinements, +where self refers to the value to which +a orig-proc is originally applied:

  • With a structure-field accessor as orig-proc, +redirect-proc must accept two arguments, self and +the value field-v that orig-proc produces for +v; it must return a chaperone of field-v. The +corresponding field may be immutable.

  • With structure-field mutator as orig-proc, +redirect-proc must accept two arguments, self and +the value field-v supplied to the mutator; it must +return a chaperone of field-v to be propagated to +orig-proc and v.

  • A property accessor can be supplied as orig-proc, and +the property need not have been created with +'can-impersonate. The corresponding +redirect-proc uses the same protocol as for a +structure-field accessor.

  • With struct-info as orig-proc, the +corresponding redirect-proc must accept two values, +which are the results of struct-info on v; it +must return each values or a chaperone of each value. The +redirect-proc is not called if struct-info +would return #f as its first argument. An +orig-proc can be struct-info only if +struct-type or some other orig-proc is supplied.

  • Any accessor or mutator orig-proc that is an +impersonator must be specifically a chaperone.

Supplying a property accessor for orig-proc enables +prop arguments, the same as supplying an accessor, mutator, +or structure type.

Changed in version 6.1.1.2 of package base: Changed first argument to an +accessor or mutator +redirect-proc from +v to self.
Changed in version 6.1.1.8: Added optional struct-type +argument.

procedure

(chaperone-vector vec    
  ref-proc    
  set-proc    
  prop    
  prop-val ...    
  ...)  (and/c vector? chaperone?)
  vec : vector?
  ref-proc : (or/c (vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  set-proc : (or/c (vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-vector, but with support for immutable vectors. The +ref-proc procedure must produce the same value or a chaperone +of the original value, and set-proc must produce the value +that is given or a chaperone of the value. The set-proc will +not be used if vec is immutable.

procedure

(chaperone-vector* vec    
  ref-proc    
  set-proc    
  prop    
  prop-val ...    
  ...)  (and/c vector? chaperone?)
  vec : (and/c vector? (not/c immutable?))
  ref-proc : (or/c (vector? vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  set-proc : (or/c (vector? vector? exact-nonnegative-integer? any/c . -> . any/c) #f)
  prop : impersonator-property?
  prop-val : any/c
Like chaperone-vector, but ref-proc and set-proc receive an extra argument +as with impersonate-vector*.

Added in version 6.9.0.2 of package base.

procedure

(chaperone-box box    
  unbox-proc    
  set-proc    
  prop    
  prop-val ...    
  ...)  (and/c box? chaperone?)
  box : box?
  unbox-proc : (box? any/c . -> . any/c)
  set-proc : (box? any/c . -> . any/c)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-box, but with support for immutable boxes. The +unbox-proc procedure must produce the same value or a +chaperone of the original value, and set-proc must produce +the same value or a chaperone of the value that it is given. The +set-proc will not be used if box is immutable.

procedure

(chaperone-hash hash    
  ref-proc    
  set-proc    
  remove-proc    
  key-proc    
  [clear-proc    
  equal-key-proc]    
  prop    
  prop-val ...    
  ...)  (and/c hash? chaperone?)
  hash : hash?
  ref-proc : 
(hash? any/c . -> . (values
                     any/c
                     (hash? any/c any/c . -> . any/c)))
  set-proc : (hash? any/c any/c . -> . (values any/c any/c))
  remove-proc : (hash? any/c . -> . any/c)
  key-proc : (hash? any/c . -> . any/c)
  clear-proc : (or/c #f (hash? . -> . any)) = #f
  equal-key-proc : (or/c #f (hash? any/c . -> . any/c)) = #f
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-hash, but with constraints on the given functions +and support for immutable hashes. The ref-proc procedure must +return a found value or a chaperone of the value. The +set-proc procedure must produce two values: the key that it +is given or a chaperone of the key and the value that it is given or a +chaperone of the value. The remove-proc, key-proc, +and equal-key-proc +procedures must produce the given key or a chaperone of the key.

Changed in version 6.3.0.11 of package base: Added the equal-key-proc +argument.

procedure

(chaperone-struct-type struct-type 
  struct-info-proc 
  make-constructor-proc 
  guard-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c struct-type? chaperone?)
  struct-type : struct-type?
  struct-info-proc : procedure?
  make-constructor-proc : (procedure? . -> . procedure?)
  guard-proc : procedure?
  prop : impersonator-property?
  prop-val : any/c
Returns a chaperoned value like struct-type, but with +struct-type-info and struct-type-make-constructor +operations on the chaperoned structure type redirected. In addition, +when a new structure type is created as a subtype of the chaperoned +structure type, guard-proc is interposed as an extra guard on +creation of instances of the subtype.

The struct-info-proc must accept 8 arguments—the result of +struct-type-info on struct-type. It must return 8 +values, where each is the same or a chaperone of the corresponding +argument. The 8 values are used as the results of +struct-type-info for the chaperoned structure type.

The make-constructor-proc must accept a single procedure +argument, which is a constructor produced by +struct-type-make-constructor on struct-type. It must +return the same or a chaperone of the procedure, which is used as the +result of struct-type-make-constructor on the chaperoned +structure type.

The guard-proc is like a guard argument to +make-struct-type: it must accept one more argument +than a constructor for struct-type, where the last argument +is the name the name of the instantiated structure type. +It must return the number of values needed by the constructor +(i.e. one value for each argument but the last), +and each returned value must be the same as +or a chaperone of the corresponding argument. +The guard-proc is added as a constructor guard when a subtype is +created of the chaperoned structure type.

Pairs of prop and prop-val (the number of arguments +to chaperone-struct-type must be even) add impersonator properties +or override impersonator-property values of struct-type.

procedure

(chaperone-evt evt proc prop prop-val ... ...)

  (and/c evt? chaperone?)
  evt : evt?
  proc : (evt? . -> . (values evt? (any/c . -> . any/c)))
  prop : impersonator-property?
  prop-val : any/c
Returns a chaperoned value like evt, but with proc +as an event generator when the result is synchronized with functions +like sync.

The proc generator is called on synchronization, much like +the procedure passed to guard-evt, except that proc +is given evt. The proc must return two values: a +synchronizable event that is a chaperone of evt, and a +procedure that is used to check the event’s result if it is chosen in +a selection. The latter procedure accepts the result of evt, +and it must return a chaperone of that value.

Pairs of prop and prop-val (the number of arguments +to chaperone-evt must be even) add impersonator properties +or override impersonator-property values of evt.

The result is chaperone-of? the argument evt. +However, if evt is a thread, semaphore, +input port, output port, or will executor, the +result is not recognized as such. For example, thread? +applied to the result of chaperone-evt will always produce +#f.

procedure

(chaperone-channel channel    
  get-proc    
  put-proc    
  prop    
  prop-val ...    
  ...)  (and/c channel? chaperone?)
  channel : channel?
  get-proc : (channel? . -> . (values channel? (any/c . -> . any/c)))
  put-proc : (channel? any/c . -> . any/c)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-channel, but with restrictions on the +get-proc and put-proc procedures.

The get-proc must return two values: a channel +that is a chaperone of channel, and a procedure that +is used to check the channel’s contents. The latter procedure +must return the original value or a chaperone of that value.

The put-proc must produce a replacement value that is +either the original value communicated on the channel or a +chaperone of that value.

Pairs of prop and prop-val (the number of arguments +to chaperone-channel must be odd) add impersonator properties +or override impersonator-property values of channel.

procedure

(chaperone-prompt-tag prompt-tag 
  handle-proc 
  abort-proc 
  [cc-guard-proc 
  callcc-chaperone-proc] 
  prop 
  prop-val ... 
  ...) 
  (and/c continuation-prompt-tag? chaperone?)
  prompt-tag : continuation-prompt-tag?
  handle-proc : procedure?
  abort-proc : procedure?
  cc-guard-proc : procedure? = values
  callcc-chaperone-proc : (procedure? . -> . procedure?)
   = (lambda (p) p)
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-prompt-tag, but produces a chaperoned value. +The handle-proc procedure must produce the same values or +chaperones of the original values, abort-proc must produce +the same values or chaperones of the values that it is given, and +cc-guard-proc must produce the same values or chaperones of +the original result values, and callcc-chaperone-proc must +produce a procedure that is a chaperone or the same as the given +procedure.

Examples:
> (define bad-chaperone
    (chaperone-prompt-tag
     (make-continuation-prompt-tag)
     (lambda (n) (* n 2))
     (lambda (n) (+ n 1))))
> (call-with-continuation-prompt
    (lambda ()
      (abort-current-continuation bad-chaperone 5))
    bad-chaperone
    (lambda (n) n))

abort-current-continuation: non-chaperone result; received a

prompt-abort argument that is not a chaperone of the

original prompt-abort argument

  original: 5

  received: 6

> (define good-chaperone
    (chaperone-prompt-tag
     (make-continuation-prompt-tag)
     (lambda (n) (if (even? n) n (error "not even")))
     (lambda (n) (if (even? n) n (error "not even")))))
> (call-with-continuation-prompt
    (lambda ()
      (abort-current-continuation good-chaperone 2))
    good-chaperone
    (lambda (n) n))

2

procedure

(chaperone-continuation-mark-key key 
  get-proc 
  set-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c continuation-mark-key? chaperone?)
  key : continuation-mark-key?
  get-proc : procedure?
  set-proc : procedure?
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-continuation-mark-key, but produces a +chaperoned value. The get-proc procedure must produce the +same value or a chaperone of the original value, and set-proc +must produce the same value or a chaperone of the value that it is +given.

Examples:
> (define bad-chaperone
    (chaperone-continuation-mark-key
     (make-continuation-mark-key)
     (lambda (l) (map char-upcase l))
     string->list))
> (with-continuation-mark bad-chaperone "timballo"
    (continuation-mark-set-first
     (current-continuation-marks)
     bad-chaperone))

with-continuation-mark: non-chaperone result; received a

value that is not a chaperone of the original value

  original: "timballo"

  received: '(#\t #\i #\m #\b #\a #\l #\l #\o)

> (define (checker s)
    (if (> (string-length s) 5)
        s
        (error "expected string of length at least 5")))
> (define good-chaperone
    (chaperone-continuation-mark-key
     (make-continuation-mark-key)
     checker
     checker))
> (with-continuation-mark good-chaperone "zabaione"
    (continuation-mark-set-first
     (current-continuation-marks)
     good-chaperone))

"zabaione"

14.5.3 Impersonator Properties

Creates a new impersonator property and returns three values:

  • an impersonator property descriptor, for use with +impersonate-procedure, chaperone-procedure, +and other impersonator constructors;

  • an impersonator property predicate procedure, which takes +an arbitrary value and returns #t if the value is an +impersonator with a value for the property, #f +otherwise;

  • an impersonator property accessor procedure, which +returns the value associated with an impersonator for the property; +if a value given to the accessor is not an impersonator or does not +have a value for the property (i.e. if the corresponding impersonator +property predicate returns #f), then a second optional argument +to the selector determines its response: the exn:fail:contract exception is raised +if a second argument is not provided, the second argument is tail-called +with zero arguments if it is a procedure, and the second argument is returned +otherwise.

procedure

(impersonator-property? v)  boolean?

  v : any/c
Returns #t if v is a impersonator property +descriptor value, #f otherwise.

Returns #t if v is an accessor procedure produced +by make-impersonator-property, #f otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/characters.html b/clones/docs.racket-lang.org/reference/characters.html new file mode 100644 index 00000000..cf4e0064 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/characters.html @@ -0,0 +1,71 @@ + +4.6 Characters

4.6 Characters

+Characters in The Racket Guide introduces characters.

Characters range over Unicode +scalar values, which includes +characters whose values range from #x0 to +#x10FFFF, but not including #xD800 to +#xDFFF. The scalar values are a subset of the Unicode +code points.

Two characters are eqv? if they correspond to the same scalar +value. For each scalar value less than 256, character values that are +eqv? are also eq?. Characters produced by the default +reader are interned in read-syntax mode.

See Reading Characters + for information on reading + characters and Printing Characters + for information on printing characters.

Changed in version 6.1.1.8 of package base: Updated from Unicode 5.0.1 to Unicode 7.0.0.

4.6.1 Characters and Scalar Values

procedure

(char? v)  boolean?

  v : any/c
Return #t if v is a character, #f +otherwise.

procedure

(char->integer char)  exact-integer?

  char : char?
Returns a character’s code-point number.

Example:
> (char->integer #\A)

65

procedure

(integer->char k)  char?

  k : 
(and/c exact-integer?
       (or/c (integer-in 0 #xD7FF)
             (integer-in #xE000 #x10FFFF)))
Return the character whose code-point number is k. For +k less than 256, the result is the same object for +the same k.

Example:
> (integer->char 65)

#\A

procedure

(char-utf-8-length char)  (integer-in 1 6)

  char : char?
Produces the same result as (bytes-length (string->bytes/utf-8 (string char))).

4.6.2 Character Comparisons

procedure

(char=? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Returns #t if all of the arguments are eqv?.

Examples:
> (char=? #\a #\a)

#t

> (char=? #\a #\A #\a)

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char<? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Returns #t if the arguments are sorted increasing, where +two characters are ordered by their scalar values, #f +otherwise.

Examples:
> (char<? #\A #\a)

#t

> (char<? #\a #\A)

#f

> (char<? #\a #\b #\c)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char<=? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Like char<?, but checks whether the arguments are nondecreasing.

Examples:
> (char<=? #\A #\a)

#t

> (char<=? #\a #\A)

#f

> (char<=? #\a #\b #\b)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char>? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Like char<?, but checks whether the arguments are decreasing.

Examples:
> (char>? #\A #\a)

#f

> (char>? #\a #\A)

#t

> (char>? #\c #\b #\a)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char>=? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Like char<?, but checks whether the arguments are nonincreasing.

Examples:
> (char>=? #\A #\a)

#f

> (char>=? #\a #\A)

#t

> (char>=? #\c #\b #\b)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char-ci=? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Returns #t if all of the arguments are eqv? after + locale-insensitive case-folding via char-foldcase.

Examples:
> (char-ci=? #\A #\a)

#t

> (char-ci=? #\a #\a #\a)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char-ci<? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Like char<?, but checks whether the arguments would be in + increasing order if each was first case-folded using + char-foldcase (which is locale-insensitive).

Examples:
> (char-ci<? #\A #\a)

#f

> (char-ci<? #\a #\b)

#t

> (char-ci<? #\a #\b #\c)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char-ci<=? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Like char-ci<?, but checks whether the arguments would be nondecreasing after case-folding.

Examples:
> (char-ci<=? #\A #\a)

#t

> (char-ci<=? #\a #\A)

#t

> (char-ci<=? #\a #\b #\b)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char-ci>? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Like char-ci<?, but checks whether the arguments would be decreasing after case-folding.

Examples:
> (char-ci>? #\A #\a)

#f

> (char-ci>? #\b #\A)

#t

> (char-ci>? #\c #\b #\a)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(char-ci>=? char1 char2 ...)  boolean?

  char1 : char?
  char2 : char?
Like char-ci<?, but checks whether the arguments would be nonincreasing after case-folding.

Examples:
> (char-ci>=? #\A #\a)

#t

> (char-ci>=? #\a #\A)

#t

> (char-ci>=? #\c #\b #\b)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.6.3 Classifications

procedure

(char-alphabetic? char)  boolean?

  char : char?
Returns #t if char has the Unicode “Alphabetic” +property.

procedure

(char-lower-case? char)  boolean?

  char : char?
Returns #t if char has the Unicode “Lowercase” +property.

procedure

(char-upper-case? char)  boolean?

  char : char?
Returns #t if char has the Unicode “Uppercase” +property.

procedure

(char-title-case? char)  boolean?

  char : char?
Returns #t if char’s Unicode general category is +Lt, #f otherwise.

procedure

(char-numeric? char)  boolean?

  char : char?
Returns #t if char has a Unicode “Numeric_Type” +property value that is not None.

procedure

(char-symbolic? char)  boolean?

  char : char?
Returns #t if char’s Unicode general category is +Sm, Sc, Sk, or So, #f otherwise.

procedure

(char-punctuation? char)  boolean?

  char : char?
Returns #t if char’s Unicode general category is +Pc, Pd, Ps, Pe, Pi, Pf, or +Po, #f otherwise.

procedure

(char-graphic? char)  boolean?

  char : char?
Returns #t if char’s Unicode general category is +Ll, Lm, Lo, Lt, Lu, Nd, Nl, No, +Mn, Mc, or Me, or if one of the following produces +#t when applied to char: char-alphabetic?, +char-numeric?, char-symbolic?, or +char-punctuation?.

procedure

(char-whitespace? char)  boolean?

  char : char?
Returns #t if char has the Unicode “White_Space” +property.

procedure

(char-blank? char)  boolean?

  char : char?
Returns #t if char’s Unicode general category is +Zs or if char is #\tab. (These correspond to +horizontal whitespace.)

procedure

(char-iso-control? char)  boolean?

  char : char?
Return #t if char is between #\nul and +#\u001F inclusive or #\rubout and #\u009F +inclusive.

procedure

(char-general-category char)  symbol?

  char : char?
Returns a symbol representing the character’s Unicode general +category, which is 'lu, 'll, +'lt, 'lm, 'lo, +'mn, 'mc, 'me, +'nd, 'nl, 'no, +'ps, 'pe, 'pi, +'pf, 'pd, 'pc, +'po, 'sc, 'sm, +'sk, 'so, 'zs, +'zp, 'zl, 'cc, +'cf, 'cs, 'co, or +'cn.

procedure

(make-known-char-range-list)

  
(listof (list/c exact-nonnegative-integer?
                exact-nonnegative-integer?
                boolean?))
Produces a list of three-element lists, where each three-element list +represents a set of consecutive code points for which the Unicode +standard specifies character properties. Each three-element list +contains two integers and a boolean; the first integer is a starting +code-point value (inclusive), the second integer is an ending +code-point value (inclusive), and the boolean is #t when all +characters in the code-point range have identical results for all of +the character predicates above, have analogous transformations +(shifting by the same amount, if any, in code-point space) for +char-downcase, char-upcase, and +char-titlecase, and have the same +decomposition–normalization behavior. +The three-element lists are ordered in +the overall result list such that later lists represent larger +code-point values, and all three-element lists are separated from +every other by at least one code-point value that is not specified by +Unicode.

4.6.4 Character Conversions

procedure

(char-upcase char)  char?

  char : char?
Produces a character consistent with the 1-to-1 code point mapping +defined by Unicode. If char has no upcase mapping, +char-upcase produces char.

String procedures, such as string-upcase, handle +the case where Unicode defines a locale-independent mapping from the +code point to a code-point sequence (in addition to the 1-1 mapping on +scalar values).

Examples:
> (char-upcase #\a)

#\A

> (char-upcase #\λ)

#\Λ

> (char-upcase #\space)

#\space

procedure

(char-downcase char)  char?

  char : char?
Like char-upcase, but for the Unicode downcase mapping.

Examples:
> (char-downcase #\A)

#\a

> (char-downcase #\Λ)

#\λ

> (char-downcase #\space)

#\space

procedure

(char-titlecase char)  char?

  char : char?
Like char-upcase, but for the Unicode titlecase mapping.

Examples:
> (char-upcase #\a)

#\A

> (char-upcase #\λ)

#\Λ

> (char-upcase #\space)

#\space

procedure

(char-foldcase char)  char?

  char : char?
Like char-upcase, but for the Unicode case-folding mapping.

Examples:
> (char-foldcase #\A)

#\a

> (char-foldcase #\Σ)

#\σ

> (char-foldcase #\ς)

#\σ

> (char-foldcase #\space)

#\space

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/collapsible.html b/clones/docs.racket-lang.org/reference/collapsible.html new file mode 100644 index 00000000..f4422ade --- /dev/null +++ b/clones/docs.racket-lang.org/reference/collapsible.html @@ -0,0 +1,57 @@ + +8.10 Collapsible Contracts

8.10 Collapsible Contracts

Added in version 7.1.0.10 of package base.

Collapsible contracts are an optimization in the contract system designed +to avoid a particular pathological build up of contract wrappers on higher-order +values. The vectorof, vector/c, and -> contract +combinators support collapsing for vector contracts and function contracts for +functions returning a single value.

Intuitively, a collapsible contract is a tree structure. +The tree nodes represent higher-order contracts + (e.g., ->) and the tree leaves + represent sequences of flat contracts. +Two trees can collapse into one tree via the merge procedure, + which removes unnecessary flat contracts from the leaves.

For more information on the motivation and design of collapsible contracts, + see [Feltey18]. +For the theoretical foundations, see [Greenberg15].

Warning: the features described in this section are experimental +and may not be sufficient to implement new collapsible contracts. Implementing +new collapsible contracts requires the use of unsafe chaperones and impersonators +which are only supported for vector and procedure values. This documentation exists +primarily to allow future maintenance of the racket/contract/collapsible +library. End Warning

Returns the collapsible-late-neg projection for c.

If c does not have a collapsible-late-neg projection, +then this function uses the original projection for it and constructs a leaf +as its collapsible representation.

Key used by continuation marks that are present during collapsible contract checking. +The value of these marks are #t if the current contract is collapsible.

Inserts a continuation mark that informs the contract profiler that the current contract +is collapsible.

Structures implementing this property are usable as collapsible contracts. The value +associated with this property should be constructed by calling +build-collapsible-contract-property.

procedure

(collapsible-contract? v)  boolean?

  v : any/c
A predicate recognizing structures with the prop:collapsible-contract property.

procedure

(merge new-cc new-neg old-cc old-neg)  collapsible-contract?

  new-cc : collapsible-contract?
  new-neg : any/c
  old-cc : collapsible-contract?
  old-neg : any/c
Combine two collapsible contracts into a single collapsible contract. +The new-neg and old-neg arguments are expected to be +blame parties similar to those passed to a late neg projection.

procedure

(collapsible-guard cc val neg-party)  any/c

  cc : collapsible-contract?
  val : any/c
  neg-party : any/c
Similar to a late neg projection, this function guards the value val +with the collapsible contract cc.

procedure

(collapsible-contract-property? v)  boolean?

  v : any/c
This predicate indicates that a value can be used as the property for +prop:collapsible-contract.

procedure

(build-collapsible-contract-property 
  [#:try-merge try-merge 
  #:collapsible-guard collapsible-guard]) 
  collapsible-contract-property?
  try-merge : 
(or/c #f
      (-> collapsible-contract?
          any/c
          collapsible-contract?
          any/c
          (or/c #f collapsible-contract?)))
 = #f
  collapsible-guard : (-> collapsible-contract? any/c any/c any/c)
   = 
(λ (cc v neg)
  (error
   "internal error: contract does not support `collapsible-guard`" cc))
Constructs a collapsible contract property from a merging function and a guard. +The try-merge argument is similar to merge, but may return #f instead +of a collapsible contract and may be specialized to a particular collapsible contract. +The collapsible-guard argument should be specialized to the particular collapsible +contract being implemented.

struct

(struct collapsible-ho/c (latest-blame missing-party latest-ctc))

  latest-blame : blame?
  missing-party : any/c
  latest-ctc : contract?
A common parent structure for collapsible contracts for higher-order values. +The latest-blame field holds the blame object for the most recent +contract attached. Similarly, the missing-party field holds the latest +missing party passed to the contract. The latest-contract field stores +the most recent contract attached to the value.

struct

(struct collapsible-leaf/c (proj-list
    contract-list
    blame-list
    missing-party-list))
  proj-list : (listof (-> any/c any/c any/c))
  contract-list : (listof contract?)
  blame-list : (listof blame?)
  missing-party-list : (listof any/c)
A structure representing the leaf nodes of a collapsible contract. The proj-list +field holds a list of partially applied late neg projections. The contract-list, +blame-list, and missing-party-list fields hold a list of contracts, +blame objects, and blame missing parties respectively.

An impersonator property (and its accessors) that should be attached to chaperoned or impersonated +values that are guarded with a collapsible contract.

struct

(struct collapsible-property (c-c neg-party ref))

  c-c : collapsible-contract?
  neg-party : any/c
  ref : (or/c #f impersonator?)
The parent struct of properties that should be attached to chaperones or impersonators +of values protected with a collapsible contract. The c-c field stores the collapsible +contract that is or will in the future be attached to the the value. The neg-party field +stores the latest missing blame party passed to the contract on the value. The ref field +is mutable and stores a reference to the chaperone or impersonator to which this property is +attached. This is necessary to determine whether an unknown chaperone has been attached to a value +after it has been protected by a collapsible contract. +
This property is associated with the impersonator-prop:collapsible property before +the value completely enters the collapsible mode. These properties keep track of the number of +contracts on a value in the count field, and hold a reference to the previous +count property in the prev field or the original value without a contract. This +allows the contract system to traverse the chain of attached contracts and merge them into a single +collapsible contract to protect the original value. +

struct

(struct collapsible-wrapper-property collapsible-property
  (checking-wrapper)
  checking-wrapper : impersonator?
This property is used when a value is guarded by a collapsible contract. The +checking-wrapper field holds a chaperone or impersonator that dispatches to the +collapsible contract stored in this property to perform any necessary contract checks. When +the value receives another contract and merging happens, the checking wrapper will remain the +same even though the specific collapsible contract attached to the value may change.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/collects.html b/clones/docs.racket-lang.org/reference/collects.html new file mode 100644 index 00000000..e5a59b54 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/collects.html @@ -0,0 +1,205 @@ + +18.2 Libraries and Collections

18.2 Libraries and Collections

A library is module declaration for use by multiple +programs. Racket further groups libraries into collections. +Typically, collections are added via packages (see +Package Management in Racket); the package manager +works outside of the Racket core, but it configures the core run-time +system through collection links files.

Libraries in collections are referenced through lib paths +(see require) or symbolic shorthands. For example, the +following module uses the "getinfo.rkt" library module from +the "setup" collection, and the "cards.rkt" library +module from the "games" collection’s "cards" +subcollection:

#lang racket
(require (lib "setup/getinfo.rkt")
         (lib "games/cards/cards.rkt"))
....

This example is more compactly and more commonly written using +symbolic shorthands:

#lang racket
(require setup/getinfo
         games/cards/cards)
....

When an identifier id is used in a require form, it +is converted to (lib rel-string) where rel-string +is the string form of id.

A rel-string in (lib rel-string) consists of one +or more path elements that name collections, and then a final path +element that names a library file; the path elements are separated by +/. If rel-string contains no /s, then +/main.rkt is implicitly appended to the path. If +rel-string contains / but does not end with a file +suffix, then .rkt is implicitly appended to the path.

Libraries also can be distributed via PLaneT packages. Such +libraries are referenced through a planet module path (see +require) and are downloaded by Racket on demand, instead of +referenced through collections.

The translation of a planet or lib path to a +module declaration is determined by the module name +resolver, as specified by the current-module-name-resolver +parameter.

18.2.1 Collection Search Configuration

For the default module name resolver, the search path for +collections is determined by the +current-library-collection-links parameter and the +current-library-collection-paths parameter:

To resolve a module reference rel-string, the default +module name resolver searches collection links in +current-library-collection-links from first to last to locate +the first directory that contains rel-string, splicing a +search through in current-library-collection-paths where in +current-library-collection-links contains #f. The +filesystem tree for each element in the link table and search path is +effectively spliced together with the filesystem trees of other path +elements that correspond to the same collection. Some Racket tools +rely on unique resolution of module path names, so an installation and +configuration should not allow multiple files to match the same +collection and file combination.

The value of the current-library-collection-links parameter +is initialized by the racket executable to the result of +(find-library-collection-links), and the value of the +current-library-collection-paths parameter is initialized to +the result of (find-library-collection-paths).

18.2.2 Collection Links

Collection links files are used by +collection-file-path, collection-path, and the +default module name resolver to locate collections before +trying the (current-library-collection-paths) search +path. The collection links files to use are determined by the +current-library-collection-links parameter, which is +initialized to the result of find-library-collection-links.

A collection links file is read with default reader +parameter settings to obtain a list. Every element of the list must be +a link specification with one of the forms (list string encoded-path), (list string encoded-path regexp), (list 'root encoded-path), (list 'root encoded-path regexp), (list 'static-root encoded-path), (list 'static-root encoded-path regexp). +A string names a +top-level collection, in which case encoded-path describes a path +that can be used as the collection’s path (directly, as opposed to a +subdirectory of encoded-path named by string). A +'root entry, in contrast, acts like an path in +(current-library-collection-paths). A +'static-root entry is like a 'root entry, but +where the immediate content of the directory is assumed not to change unless the +collection links file changes. +Each encoded-path is either a string, a +byte string that is converted to a path with bytes->path, +or a list of relative path-element byte strings, 'up, and 'same +indicators that are combined with build-path with the byte +strings converted with bytes->path-element. +If encoded-path describes a +relative path, it is relative to the directory containing the +collection links file. If regexp is specified in a +link, then the link is used only if (regexp-match? regexp (version)) produces a true result.

A single top-level collection can have multiple links in a +collection links file, and any number of 'root entries +can appear. The corresponding paths are effectively spliced together, +since the paths are tried in order to locate a file or sub-collection.

The raco link command-link tool can display, install, and +remove links in a collection links file. See raco link: Library Collection Links in raco: Racket Command-Line Tools for more information.

Changed in version 8.1.0.6 of package base: Changed encoded-path to +allow bytes strings and lists.

18.2.3 Collection Paths and Parameters

procedure

(find-library-collection-paths [pre-extras    
  post-extras    
  config]    
  name)  (listof path?)
  pre-extras : (listof path-string?) = null
  post-extras : (listof path-string?) = null
  config : hash? = (read-installation-configuration-table)
  name : (get-installation-name config)
Produces a list of paths, which is normally used to initialize +current-library-collection-paths, as follows:

  • The path produced by (build-path (find-system-path 'addon-dir) name "collects") is the first element of the +default collection path list, unless the value of the +use-user-specific-search-paths parameter is #f.

  • Extra directories provided in pre-extras are included +next to the default collection path list, converted to complete +paths relative to the executable.

  • If the directory specified by (find-system-path 'collects-dir) is absolute, or if it is relative (to the +executable) and it exists, then it is added to the end of the +default collection path list.

  • Extra directories provided in post-extras are included +last in the default collection path list, converted to complete +paths relative to the executable.

  • If config has a value for +'collects-search-dirs, then it is used in place of the +default collection path list (as constructed by the preceding three +bullets), and the default is spliced in place of any #f +within the 'collects-search-dirs list. If config +does not have a 'collects-search-dirs value, then the +default collection path list is used.

  • If the PLTCOLLECTS environment variable is +defined, it is combined with the default list using +path-list-string->path-list, as long as the value of +use-user-specific-search-paths is true. If it is not +defined or if the value use-user-specific-search-paths is +#f, the collection path list as constructed by the +preceding four bullets is used directly.

    Note that on Unix and Mac OS, paths are separated by :, and +on Windows by ;. Also, +path-list-string->path-list splices the default paths at an +empty path, for example, with many Unix shells you can set +PLTCOLLECTS to ":pwd", "pwd:", or +"pwd" to specify search the current directory after, before, +or instead of the default paths, respectively.

Changed in version 8.4.0.3 of package base: Added the config and +name arguments.

procedure

(find-library-collection-links [config] name)

  (listof (or/c #f (and/c path? complete-path?)))
  config : hash? = (read-installation-configuration-table)
  name : (get-installation-name config)
Produces a list of paths and #f, which is normally used to +initialize current-library-collection-links, as follows:

Changed in version 8.4.0.3 of package base: Added the config and +name arguments.

procedure

(collection-file-path file 
  collection ...+ 
  [#:check-compiled? check-compiled?]) 
  path?
  file : path-string?
  collection : path-string?
  check-compiled? : any/c = (regexp-match? #rx"[.]rkt$" file)
(collection-file-path file    
  collection ...+    
  #:fail fail-proc    
  [#:check-compiled? check-compiled?])  any
  file : path-string?
  collection : path-string?
  fail-proc : (string? . -> . any)
  check-compiled? : any/c = (regexp-match? #rx"[.]rkt$" file)
Returns the path to the file indicated by file in the +collection specified by the collections, where the second +collection (if any) names a sub-collection, and so on. The +search uses the values of current-library-collection-links +and current-library-collection-paths.

See also collection-search in +setup/collection-search.

If file is not found, but file ends in +".rkt" and a file with the suffix ".ss" exists, then +the directory of the ".ss" file is used. If file is +not found and the ".rkt"/".ss" conversion does not +apply, but a directory corresponding to the collections is +found, then a path using the first such directory is +returned.

If check-compiled? is true, then the search also depends on +use-compiled-file-paths and +current-compiled-file-roots; if file is not found, +then a compiled form of file with the suffix ".zo" +is checked in the same way as the default compiled-load +handler. If a compiled file is found, the result from +collection-file-path reports the location that file +itself would occupy (if it existed) for the found compiled file.

Finally, if the collection is not found, and if fail-proc is +provided, then fail-proc is applied to an error message (that +does not start "collection-file-path:" or otherwise claim a +source), and its result is the result of +collection-file-path. If fail-proc is not provided +and the collection is not found, then the +exn:fail:filesystem exception is raised.

Examples:
> (collection-file-path "main.rkt" "racket" "base")

#<path:path/to/collects/racket/base/main.rkt>

> (collection-file-path "sandwich.rkt" "bologna")

collection-file-path: collection not found

  collection: "bologna"

  in collection directories:

   /home/scheme/pltbuild/racket/racket/collects/

   ... [245 additional linked and package directories]

Changed in version 6.0.1.12 of package base: Added the check-compiled? argument.

procedure

(collection-path collection ...+)  path?

  collection : path-string?
(collection-path collection    
  ...+    
  #:fail fail-proc)  any
  collection : path-string?
  fail-proc : (string? . -> . any)

NOTE: This function is deprecated; use collection-file-path, instead. Collection splicing implies that a given collection can have +multiple paths, such as when multiple packages provide modules for a +collection.

Like collection-file-path, but without a specified file name, +so that a directory indicated by collections is returned.

When multiple directories correspond to the collection, the first one +found in the search sequence (see Collection Search Configuration) is returned.

Parameter that determines a list of complete directory paths for +finding libraries (as referenced in require, for example) +through the default module name resolver and for finding paths +through collection-path and +collection-file-path. See Collection Search Configuration for more +information.

parameter

(current-library-collection-links)

  
(listof (or/c #f
              (and/c path? complete-path?)
              (hash/c (or/c (and/c symbol? module-path?) #f)
                      (listof (and/c path? complete-path?)))))
(current-library-collection-links paths)  void?
  paths : 
(listof (or/c #f
              (and/c path-string? complete-path?)
              (hash/c (or/c (and/c symbol? module-path?) #f)
                      (listof (and/c path-string? complete-path?)))))

Parameter that determines collection links files, additional +paths, and the relative search order of +current-library-collection-paths for finding libraries (as +referenced in require, for example) through the default +module name resolver and for finding paths through +collection-path and collection-file-path. See +Collection Search Configuration for more information.

Parameter that determines whether user-specific paths, which are in +the directory produced by (find-system-path 'addon-dir), are +included in search paths for collections and other files. For example, +the initial value of find-library-collection-paths omits the +user-specific collection directory when this parameter’s value is +#f.

If -U or --no-user-path argument to racket, then +use-user-specific-search-paths is initialized to +#f.

Parameter that determines whether collection links files are +included in the result of find-library-collection-links.

If this parameter’s value is #f on start-up, then +collection links files are effectively disabled permanently for +the Racket process. In particular, if an empty string is provided as +the -X or --collects argument to racket, then not +only is current-library-collection-paths initialized to the +empty list, but use-collection-link-paths is initialized to +#f.

Returns the content of the installation’s "config.rktd" file +(see Installation Configuration and Search Paths) as long as that content is +a hash table, and otherwise returns an empty hash table.

Added in version 8.4.0.3 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/compiler.html b/clones/docs.racket-lang.org/reference/compiler.html new file mode 100644 index 00000000..f932d4f4 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/compiler.html @@ -0,0 +1,70 @@ + +18.7 Controlling and Inspecting Compilation

18.7 Controlling and Inspecting Compilation

Racket programs and expressions are compiled automatically and +on-the-fly. The raco make tool (see raco make: Compiling Source to Bytecode) can compile a Racket module to a compiled ".zo" +file, but that kind of ahead-to-time compilation simply allows a +program takes to start more quickly, and it does not affect the +performance of a Racket program.

18.7.1 Compilation Modes

All Racket variants suppose a machine-independent compilation mode, +which generates compiled ".zo" files that work with all +Racket variants on all platforms. To select machine-independent +compilation mode, set the current-compile-target-machine +parameter to #f or supplying the --compile-any/-M +flag on startup. See current-compile-target-machine for more +information.

Other compilation modes depend on the Racket implementation (see +Implementations).

18.7.1.1 BC Compilation Modes

The BC implementation of Racket supports two +compilation modes: bytecode and machine-independent. The bytecode +format is also machine-independent in the sense that it works the same +on all operating systems for the BC implementation +of Racket, but it does not work with the CS implementation of Racket.

Bytecode is further compiled to machine code at run time, unless the +JIT compiler is disabled. See eval-jit-enabled.

18.7.1.2 CS Compilation Modes

The CS implementation of Racket supports several compilation modes: +machine code, machine-independent, interpreted, and JIT. Machine code +is the primary mode, and the machine-independent mode is the same as +for BC. Interpreted mode uses an interpreter at +the level of core linklet forms with no compilation. JIT mode +triggers compilation of individual function forms on demand.

The default mode is a hybrid of machine-code and interpreter modes, +where interpreter mode is used only for the outer contour of an +especially large linklet, and machine-code mode is used for functions +that are small enough within that outer contour. “Small enough” is +determined by the PLT_CS_COMPILE_LIMIT environment +variable, and the default value of 10000 means that most Racket +modules have no interpreted component.

JIT compilation mode is used only if the PLT_CS_JIT +environment variable is set on startup, otherwise pure interpreter +mode is used only if PLT_CS_INTERP is set on startup, +and the default hybrid machine code and interpreter mode is used if +PLT_CS_MACH is set and PLT_CS_JIT is not set +or if none of those environment variables is set. A module compiled in +any mode can be loaded into the CS variant of Racket independent of +the current compilation mode.

The PLT_CS_DEBUG environment variable, as described in +Debugging, affects only compilation in machine-code mode. +Generated machine code is much larger when PLT_CS_DEBUG is +enabled, but performance is not otherwise affected.

18.7.2 Inspecting Compiler Passes

When the PLT_LINKLET_SHOW environment variable is set +on startup, the Racket process’s standard output shows intermediate +compiled forms whenever a Racket form is compiled. For all Racket +variants, the output shows one or more linklets that are +generated from the original Racket form.

For the CS implementation of Racket, a “schemified” version of the linklet +is also shown as the translation of the linklet form to a +Chez Scheme procedure form. The following environment variables imply +PLT_LINKLET_SHOW and show additional intermediate compiled +forms or adjust the way forms are displayed:

  • PLT_LINKLET_SHOW_GENSYM prints full +generated names, instead of abbreviations that may conflate +different symbols

  • PLT_LINKLET_SHOW_PRE_JIT shows a +schemified forms before a transformation to JIT mode, which +applies only when PLT_CS_JIT is set

  • PLT_LINKLET_SHOW_LAMBDA shows individual +schemified forms that are compiled within a larger form that +has an interpreted outer contour

  • PLT_LINKLET_SHOW_POST_LAMBDA shows an +outer form after inner individual forms are compiled

  • PLT_LINKLET_SHOW_POST_INTERP shows an +outer form after its transformation to interpretable form

  • PLT_LINKLET_SHOW_JIT_DEMAND shows JIT +compilation of form that were previously prepared by +compilation with PLT_CS_JIT set

  • PLT_LINKLET_SHOW_PATHS show lifted +path and serialization information alongside a schemified form

  • PLT_LINKLET_SHOW_KNOWN show recorded +known-binding information alongside a schemified form

  • PLT_LINKLET_SHOW_CP0 show a schemified +form after transformation by Chez Scheme’s front-end +optimizer

  • PLT_LINKLET_SHOW_PASSES show the +intermediate form of a schemified linklet after the specified +passes (listed space-separated) in Chez Scheme’s internal +representation

  • PLT_LINKLET_SHOW_ASSEMBLY show the +compiled form of a schemified linklet in Chez Scheme’s +abstraction of machine instructions

When the PLT_LINKLET_TIMES environment variable is +set on startup, then Racket prints cumulative timing information about +compilation and evaluation times on exit. When the +PLT_EXPANDER_TIMES environment variable is set, +information about macro-expansion time is printed on exit.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/compoundunits.html b/clones/docs.racket-lang.org/reference/compoundunits.html new file mode 100644 index 00000000..8221de00 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/compoundunits.html @@ -0,0 +1,46 @@ + +7.3 Linking Units and Creating Compound Units

7.3 Linking Units and Creating Compound Units

syntax

(compound-unit
  (import link-binding ...)
  (export tagged-link-id ...)
  (link linkage-decl ...))
 
link-binding = (link-id : tagged-sig-id)
     
tagged-link-id = (tag id link-id)
  | link-id
     
linkage-decl = ((link-binding ...) unit-expr tagged-link-id ...)
Links several units into one new compound unit without immediately +invoking any of the linked units. The unit-exprs in the +link clause determine the units to be linked in creating the +compound unit. The unit-exprs are evaluated when the +compound-unit form is evaluated.

The import clause determines the imports of the compound +unit. Outside the compound unit, these imports behave as for a plain +unit; inside the compound unit, they are propagated to some of the +linked units. The export clause determines the exports of the +compound unit. Again, outside the compound unit, these exports are +treated the same as for a plain unit; inside the compound unit, they +are drawn from the exports of the linked units. Finally, the left-hand +and right-hand parts of each declaration in the link clause +specify how the compound unit’s imports and exports are propagated to +the linked units.

Individual elements of an imported or exported signature are not +available within the compound unit. Instead, imports and exports are +connected at the level of whole signatures. Each specific import or +export (i.e., an instance of some signature, possibly tagged) is given +a link-id name. Specifically, a link-id is bound by +the import clause or the left-hand part of a declaration in +the link clause. A bound link-id is referenced in +the right-hand part of a declaration in the link clause or by +the export clause.

The left-hand side of a link declaration gives names to each +expected export of the unit produced by the corresponding +unit-expr. The actual unit may export additional signatures, +and it may export an extension of a specific signature instead of just +the specified one. If the unit does not export one of the specified +signatures (with the specified tag, if any), the +exn:fail:contract exception is raised when the compound-unit form is +evaluated.

The right-hand side of a link declaration specifies the +imports to be supplied to the unit produced by the corresponding +unit-expr. The actual unit may import fewer signatures, and +it may import a signature that is extended by the specified one. If +the unit imports a signature (with a particular tag) that is not +included in the supplied imports, the exn:fail:contract exception is raised +when the compound-unit form is evaluated. Each +link-id supplied as an import must be bound either in the +import clause or in some declaration within the link +clause.

The order of declarations in the link clause determines the +order of invocation of the linked units. When the compound unit is +invoked, the unit produced by the first unit-expr is invoked +first, then the second, and so on. If the order specified in the +link clause is inconsistent with init-depend +declarations of the actual units, then the +exn:fail:contract exception is raised when the compound-unit form is +evaluated.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/concurrency.html b/clones/docs.racket-lang.org/reference/concurrency.html new file mode 100644 index 00000000..d441d561 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/concurrency.html @@ -0,0 +1,6 @@ + +11 Concurrency and Parallelism

11 Concurrency and Parallelism

Racket supports multiple threads of control within a program, +thread-local storage, some primitive synchronization mechanisms, and a +framework for composing synchronization abstractions. In addition, the +racket/future and racket/place libraries provide +support for parallelism to improve performance.

    11.1 Threads

      11.1.1 Creating Threads

      11.1.2 Suspending, Resuming, and Killing Threads

      11.1.3 Synchronizing Thread State

      11.1.4 Thread Mailboxes

    11.2 Synchronization

      11.2.1 Events

      11.2.2 Channels

      11.2.3 Semaphores

      11.2.4 Buffered Asynchronous Channels

        11.2.4.1 Creating and Using Asynchronous Channels

        11.2.4.2 Contracts and Impersonators on Asynchronous Channels

    11.3 Thread-Local Storage

      11.3.1 Thread Cells

      11.3.2 Parameters

    11.4 Futures

      11.4.1 Creating and Touching Futures

      11.4.2 Future Semaphores

      11.4.3 Future Performance Logging

    11.5 Places

      11.5.1 Using Places

      11.5.2 Syntactic Support for Using Places

      11.5.3 Places Logging

    11.6 Engines

    11.7 Machine Memory Order

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/cont.html b/clones/docs.racket-lang.org/reference/cont.html new file mode 100644 index 00000000..359f1b86 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/cont.html @@ -0,0 +1,177 @@ + +10.4 Continuations

10.4 Continuations

+Continuations in The Racket Guide introduces continuations.

See Sub-expression Evaluation and Continuations and Prompts, Delimited Continuations, and Barriers for general +information about continuations. Racket’s support for prompts and +composable continuations most closely resembles Dorai Sitaram’s +% and fcontrol operator [Sitaram93].

Racket installs a continuation barrier around evaluation in the +following contexts, preventing full-continuation jumps into the +evaluation context protected by the barrier:

In addition, extensions of Racket may install barriers in +additional contexts. Finally, +call-with-continuation-barrier applies a thunk barrier +between the application and the current continuation.

procedure

(call-with-continuation-prompt proc    
  [prompt-tag    
  handler]    
  arg ...)  any
  proc : procedure?
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
  handler : (or/c procedure? #f) = #f
  arg : any/c
Applies proc to the given args with the current +continuation extended by a prompt. The prompt is tagged by +prompt-tag, which must be a result from either +default-continuation-prompt-tag (the default) or +make-continuation-prompt-tag. The call to +call-with-continuation-prompt returns the result of +proc.

The handler argument specifies a handler procedure to be +called in tail position with respect to the +call-with-continuation-prompt call when the installed prompt +is the target of an abort-current-continuation call with +prompt-tag; the remaining arguments of +abort-current-continuation are supplied to the handler +procedure. If handler is #f, the default handler +accepts a single abort-thunk argument and calls +(call-with-continuation-prompt abort-thunk prompt-tag #f); +that is, the default handler re-installs the prompt and continues with +a given thunk.

procedure

(abort-current-continuation prompt-tag    
  v ...)  any
  prompt-tag : any/c
  v : any/c
Resets the current continuation to that of the nearest prompt tagged +by prompt-tag in the current continuation; if no such prompt exists, +the exn:fail:contract:continuation exception is raised. The vs are delivered +as arguments to the target prompt’s handler procedure.

The protocol for vs supplied to an abort is specific to the +prompt-tag. When abort-current-continuation is used with +(default-continuation-prompt-tag), generally, a single thunk +should be supplied that is suitable for use with the default prompt +handler. Similarly, when call-with-continuation-prompt is +used with (default-continuation-prompt-tag), the associated +handler should generally accept a single thunk argument.

Each thread’s continuation starts with a prompt for +(default-continuation-prompt-tag) that uses the default +handler, which accepts a single thunk to apply (with the prompt +intact).

Creates a prompt tag that is not equal? to the result of any +other value (including prior or future results from +make-continuation-prompt-tag). The optional name +argument, if supplied, specifies the name of the prompt tag +for printing or object-name.

Changed in version 7.9.0.13 of package base: The name argument +gives the name of the prompt tag.

Returns a constant prompt tag for which a prompt is installed at the +start of every thread’s continuation; the handler for each thread’s +initial prompt accepts any number of values and returns. The result of +default-continuation-prompt-tag is the default tag for +any procedure that accepts a prompt tag.

procedure

(call-with-current-continuation proc    
  [prompt-tag])  any
  proc : (continuation? . -> . any)
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
Captures the current continuation up to the nearest prompt tagged by +prompt-tag; if no such prompt exists, the +exn:fail:contract:continuation exception is raised. The truncated continuation +includes only continuation marks and dynamic-wind frames +installed since the prompt.

The captured continuation is delivered to proc, which is +called in tail position with respect to the +call-with-current-continuation call.

If the continuation argument to proc is ever applied, then it +removes the portion of the current continuation up to the nearest +prompt tagged by prompt-tag (not including the prompt; if no +such prompt exists, the exn:fail:contract:continuation exception is raised), or +up to the nearest continuation frame (if any) shared by the current +and captured continuations—whichever is first. While removing +continuation frames, dynamic-wind post-thunks are +executed. Finally, the (unshared portion of the) captured continuation +is appended to the remaining continuation, applying +dynamic-wind pre-thunks.

The arguments supplied to an applied procedure become the result +values for the restored continuation. In particular, if multiple +arguments are supplied, then the continuation receives multiple +results.

If, at application time, a continuation barrier would be +introduced by replacing the current continuation with the applied one, +then the exn:fail:contract:continuation exception is raised.

A continuation can be invoked from the thread (see +Threads) other than the one where it was captured.

procedure

(call/cc proc [prompt-tag])  any

  proc : (continuation? . -> . any)
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
The call/cc binding is an alias for call-with-current-continuation.

procedure

(call-with-composable-continuation proc    
  [prompt-tag])  any
  proc : (continuation? . -> . any)
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
Similar to call-with-current-continuation, but applying +the resulting continuation procedure does not remove any portion of +the current continuation. Instead, application always extends the +current continuation with the captured continuation (without +installing any prompts other than those captured in the +continuation).

When call-with-composable-continuation is called, if a +continuation barrier appears in the continuation before the closest +prompt tagged by prompt-tag, the +exn:fail:contract:continuation exception is raised (because attempting to apply +the continuation would always fail).

procedure

(call-with-escape-continuation proc)  any

  proc : (continuation? . -> . any)
Like call-with-current-continuation, but proc is not +called in tail position, and the continuation procedure supplied to +proc can only be called during the dynamic extent of the +call-with-escape-continuation call.

A continuation obtained from call-with-escape-continuation is +actually a kind of prompt. Escape continuations are provided mainly +for backwards compatibility, since they pre-date general prompts in +Racket. In the BC implementation of Racket, +call-with-escape-continuation is implemented more efficiently +than call-with-current-continuation, so +call-with-escape-continuation can sometimes replace +call-with-current-continuation to improve performance in +those older Racket variants.

procedure

(call/ec proc)  any

  proc : (continuation? . -> . any)
The call/ec binding is an alias for call-with-escape-continuation.

procedure

(call-in-continuation k proc)  any

  k : continuation?
  proc : (-> any)
Similar to applying the continuation k, but instead of +delivering values to the continuation, proc is called with +k as the continuation of the call (so the result of +proc is returned to the continuation). If k +is a composable continuation, the continuation of the call to +proc is the current continuation extended with k.

Examples:
> (+ 1
     (call/cc (lambda (k)
                (call-in-continuation k (lambda () 4)))))

5

> (+ 1
     (call/cc (lambda (k)
                (let ([n 0])
                  (dynamic-wind
                   void
                   (lambda ()
                     ; n accessed after post thunk
                     (call-in-continuation k (lambda () n)))
                   (lambda ()
                     (set! n 4)))))))

5

> (+ 1
     (with-continuation-mark
      'n 4
       (call/cc (lambda (k)
                  (with-continuation-mark
                   'n 0
                   (call-in-continuation
                    k
                    (lambda ()
                      ; 'n mark accessed in continuation
                      (continuation-mark-set-first #f 'n))))))))

5

Added in version 7.6.0.17 of package base.

syntax

(let/cc k body ...+)

Equivalent to (call/cc (lambda (k) body ...)).

syntax

(let/ec k body ...+)

Equivalent to (call/ec (lambda (k) body ...)).

procedure

(call-with-continuation-barrier thunk)  any

  thunk : (-> any)
Applies thunk with a continuation barrier between the +application and the current continuation. The results of +thunk are the results of the +call-with-continuation-barrier call.

procedure

(continuation-prompt-available? prompt-tag    
  [cont])  any
  prompt-tag : continuation-prompt-tag?
  cont : continuation? = (call/cc values)
Returns #t if cont, which must be a continuation, +includes a prompt tagged by prompt-tag, #f +otherwise.

procedure

(continuation? v)  boolean?

  v : any/c
Return #t if +v is a continuation as produced by +call-with-current-continuation, +call-with-composable-continuation, or +call-with-escape-continuation, #f otherwise.

procedure

(continuation-prompt-tag? v)  boolean?

  v : any/c
Returns #t if v is a continuation prompt tag as produced by +default-continuation-prompt-tag or make-continuation-prompt-tag.

procedure

(dynamic-wind pre-thunk    
  value-thunk    
  post-thunk)  any
  pre-thunk : (-> any)
  value-thunk : (-> any)
  post-thunk : (-> any)
Applies its three thunk arguments in order. The value of a +dynamic-wind expression is the value returned by +value-thunk. The pre-thunk procedure is invoked +before calling value-thunk and post-thunk is invoked +after value-thunk returns. The special properties of +dynamic-wind are manifest when control jumps into or out of +the value-thunk application (either due to a prompt abort or +a continuation invocation): every time control jumps into the +value-thunk application, pre-thunk is invoked, and +every time control jumps out of value-thunk, +post-thunk is invoked. (No special handling is performed for +jumps into or out of the pre-thunk and post-thunk +applications.)

When dynamic-wind calls pre-thunk for normal +evaluation of value-thunk, the continuation of the +pre-thunk application calls value-thunk (with +dynamic-wind’s special jump handling) and then +post-thunk. Similarly, the continuation of the +post-thunk application returns the value of the preceding +value-thunk application to the continuation of the entire +dynamic-wind application.

When pre-thunk is called due to a continuation jump, the +continuation of pre-thunk

  • jumps to a more deeply nested pre-thunk, if any, or jumps +to the destination continuation; then

  • continues with the context of the pre-thunk’s +dynamic-wind call.

Normally, the second part of this continuation is never reached, due +to a jump in the first part. However, the second part is relevant +because it enables jumps to escape continuations that are contained in +the context of the dynamic-wind call. Furthermore, it means +that the continuation marks (see Continuation Marks) and +parameterization (see Parameters) for pre-thunk +correspond to those of the dynamic-wind call that installed +pre-thunk. The pre-thunk call, however, is +parameterize-breaked to disable breaks (see also +Breaks).

Similarly, when post-thunk is called due to a continuation +jump, the continuation of post-thunk jumps to a less deeply +nested post-thunk, if any, or jumps to a pre-thunk +protecting the destination, if any, or jumps to the destination +continuation, then continues from the post-thunk’s +dynamic-wind application. As for pre-thunk, the +parameterization of the original dynamic-wind call is +restored for the call, and the call is parameterize-breaked +to disable breaks.

In both cases, the target for a jump is recomputed after each +pre-thunk or post-thunk completes. When a +prompt-delimited continuation (see Prompts, Delimited Continuations, and Barriers) is +captured in a post-thunk, it might be delimited and +instantiated in such a way that the target of a jump turns out to be +different when the continuation is applied than when the continuation +was captured. There may even be no appropriate target, if a relevant +prompt or escape continuation is not in the continuation after the +restore; in that case, the first step in a pre-thunk or +post-thunk’s continuation can raise an exception.

Examples:
> (let ([v (let/ec out
             (dynamic-wind
              (lambda () (display "in "))
              (lambda ()
                (display "pre ")
                (display (call/cc out))
                #f)
              (lambda () (display "out "))))])
    (when v (v "post ")))

in pre out in post out

> (let/ec k0
    (let/ec k1
      (dynamic-wind
       void
       (lambda () (k0 'cancel))
       (lambda () (k1 'cancel-canceled)))))

'cancel-canceled

> (let* ([x (make-parameter 0)]
         [l null]
         [add (lambda (a b)
                (set! l (append l (list (cons a b)))))])
    (let ([k (parameterize ([x 5])
               (dynamic-wind
                   (lambda () (add 1 (x)))
                   (lambda () (parameterize ([x 6])
                                (let ([k+e (let/cc k (cons k void))])
                                  (add 2 (x))
                                  ((cdr k+e))
                                  (car k+e))))
                   (lambda () (add 3 (x)))))])
      (parameterize ([x 7])
        (let/cc esc
          (k (cons void esc)))))
    l)

'((1 . 5) (2 . 6) (3 . 5) (1 . 5) (2 . 6) (3 . 5))

10.4.1 Additional Control Operators

The bindings documented in this section are provided by the racket/control library, not racket/base or racket.

The racket/control library provides various control operators +from the research literature on higher-order control operators, plus a +few extra convenience forms. These control operators are implemented +in terms of call-with-continuation-prompt, +call-with-composable-continuation, etc., and they generally +work sensibly together. Many are redundant; for example, +reset and prompt are aliases.

procedure

(call/prompt proc [prompt-tag handler] arg ...)  any

  proc : procedure?
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
  handler : (or/c procedure? #f) = #f
  arg : any/c
The call/prompt binding is an alias for call-with-continuation-prompt.

procedure

(abort/cc prompt-tag v ...)  any

  prompt-tag : any/c
  v : any/c
The abort/cc binding is an alias for abort-current-continuation.

procedure

(call/comp proc [prompt-tag])  any

  proc : (continuation? . -> . any)
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
The call/comp binding is an alias for call-with-composable-continuation.

procedure

(abort v ...)  any

  v : any/c
Returns the vs to a prompt using the default continuation +prompt tag and the default abort handler.

That is, (abort v ...) is equivalent to

(abort-current-continuation
 (default-continuation-prompt-tag)
 (lambda () (values v ...)))

Example:
> (prompt
    (printf "start here\n")
    (printf "answer is ~a\n" (+ 2 (abort 3))))

start here

3

syntax

(% expr)

(% expr handler-expr)
(% expr handler-expr #:tag tag-expr)

procedure

(fcontrol v #:tag prompt-tag)  any

  v : any/c
  prompt-tag : (default-continuation-prompt-tag)

Sitaram’s operators [Sitaram93].

The essential reduction rules are:

(% val proc) => val
(% E[(fcontrol val)] proc) => (proc val (lambda (x) E[x]))
  ; where E has no %

When handler-expr is omitted, % is the same as +prompt. If prompt-tag is provided, % +uses specific prompt tags like prompt-at.

Examples:
> (% (+ 2 (fcontrol 5))
     (lambda (v k)
       (k v)))

7

> (% (+ 2 (fcontrol 5))
     (lambda (v k)
       v))

5

syntax

(prompt expr ...+)

syntax

(control id expr ...+)

Among the earliest operators for higher-order control +[Felleisen88a, Felleisen88, Sitaram90].

The essential reduction rules are: +
(prompt val) => val
(prompt E[(control k expr)]) => (prompt ((lambda (k) expr)
                                         (lambda (v) E[v])))
  ; where E has no prompt

Examples:
> (prompt
    (+ 2 (control k (k 5))))

7

> (prompt
    (+ 2 (control k 5)))

5

> (prompt
    (+ 2 (control k (+ 1 (control k1 (k1 6))))))

7

> (prompt
    (+ 2 (control k (+ 1 (control k1 (k 6))))))

8

> (prompt
    (+ 2 (control k (control k1 (control k2 (k2 6))))))

6

syntax

(prompt-at prompt-tag-expr expr ...+)

syntax

(control-at prompt-tag-expr id expr ...+)

Like prompt and control, but using specific prompt +tags:

(prompt-at tag val) => val
(prompt-at tag E[(control-at tag k expr)]) => (prompt-at tag
                                               ((lambda (k) expr)
                                                (lambda (v) E[v])))
  ; where E has no prompt-at for tag

syntax

(reset expr ...+)

syntax

(shift id expr ...+)

Danvy and Filinski’s operators [Danvy90].

The essential reduction rules are:

(reset val) => val
(reset E[(shift k expr)]) => (reset ((lambda (k) expr)
                                     (lambda (v) (reset E[v]))))
  ; where E has no reset

The reset and prompt forms are interchangeable.

syntax

(reset-at prompt-tag-expr expr ...+)

syntax

(shift-at prompt-tag-expr identifier expr ...+)

Like reset and shift, but using the specified prompt +tags.

syntax

(prompt0 expr ...+)

syntax

(reset0 expr ...+)

syntax

(control0 id expr ...+)

syntax

(shift0 id expr ...+)

Generalizations of prompt, etc. [Shan04].

The essential reduction rules are:

(prompt0 val) => val
(prompt0 E[(control0 k expr)]) => ((lambda (k) expr)
                                   (lambda (v) E[v]))
(reset0 val) => val
(reset0 E[(shift0 k expr)]) => ((lambda (k) expr)
                                (lambda (v) (reset0 E[v])))

The reset0 and prompt0 forms are interchangeable. +Furthermore, the following reductions apply:

(prompt E[(control0 k expr)]) => (prompt ((lambda (k) expr)
                                          (lambda (v) E[v])))
(reset E[(shift0 k expr)]) => (reset ((lambda (k) expr)
                                      (lambda (v) (reset0 E[v]))))
(prompt0 E[(control k expr)]) => (prompt0 ((lambda (k) expr)
                                           (lambda (v) E[v])))
(reset0 E[(shift k expr)]) => (reset0 ((lambda (k) expr)
                                       (lambda (v) (reset E[v]))))

That is, both the prompt/reset and +control/shift sites must agree for 0-like +behavior, otherwise the non-0 behavior applies.

syntax

(prompt0-at prompt-tag-expr expr ...+)

syntax

(reset0-at prompt-tag-expr expr ...+)

syntax

(control0-at prompt-tag-expr id expr ...+)

syntax

(shift0-at prompt-tag-expr id expr ...+)

Variants of prompt0, etc., that accept a prompt tag.

procedure

(spawn proc)  any

  proc : ((any/c . -> . any) . -> . any)
The operators of Hieb and Dybvig [Hieb90].

The essential reduction rules are:

(prompt-at tag obj) => obj
(spawn proc) => (prompt tag (proc (lambda (x) (abort tag x))))
(prompt-at tag E[(abort tag proc)])
  => (proc (lambda (x) (prompt-at tag E[x])))
  ; where E has no prompt-at for tag

procedure

(splitter proc)  any

  proc : 
(((-> any) . -> . any)
 ((continuation? . -> . any) . -> . any)
 . -> . any)
The operator of Queinnec and Serpette [Queinnec91].

The essential reduction rules are: +
(splitter proc) => (prompt-at tag
                    (proc (lambda (thunk)
                              (abort tag thunk))
                            (lambda (proc)
                              (control0-at tag k (proc k)))))
(prompt-at tag E[(abort tag thunk)]) => (thunk)
  ; where E has no prompt-at for tag
(prompt-at tag E[(control0-at tag k expr)]) => ((lambda (k) expr)
                                                (lambda (x) E[x]))
  ; where E has no prompt-at for tag

procedure

(new-prompt)  any

syntax

(set prompt-expr expr ...+)

syntax

(cupto prompt-expr id expr ...+)

The operators of Gunter et al. [Gunter95].

In this library, new-prompt is an alias for +make-continuation-prompt-tag, set is an alias for +prompt0-at, and cupto is an alias for control0-at.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/contmarks.html b/clones/docs.racket-lang.org/reference/contmarks.html new file mode 100644 index 00000000..70abdf36 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/contmarks.html @@ -0,0 +1,110 @@ + +10.5 Continuation Marks

10.5 Continuation Marks

See Continuation Frames and Marks and Prompts, Delimited Continuations, and Barriers for +general information about continuation marks.

The list of continuation marks for a key k and a continuation +C that extends C0 is defined as follows:

  • If C is an empty continuation, then the mark list is +null.

  • If C’s first frame contains a mark m for k, +then the mark list for C is (cons m lst), +where lst is the mark list for k in C0.

  • If C’s first frame does not contain a mark keyed by +k, then the mark list for C is the mark list for +C0.

The with-continuation-mark form installs a mark on the first +frame of the current continuation (see Continuation Marks: with-continuation-mark). Procedures +such as current-continuation-marks allow inspection of marks.

Whenever Racket creates an exception record for a primitive exception, +it fills the continuation-marks field with the value of +(current-continuation-marks), thus providing a snapshot of +the continuation marks at the time of the exception.

When a continuation procedure returned by +call-with-current-continuation or +call-with-composable-continuation is invoked, it restores the +captured continuation, and also restores the marks in the +continuation’s frames to the marks that were present when +call-with-current-continuation or +call-with-composable-continuation was invoked.

procedure

(continuation-marks cont [prompt-tag])  continuation-mark-set?

  cont : (or/c continuation? thread? #f)
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
Returns an opaque value containing the set of continuation marks for +all keys in the continuation cont (or the current +continuation of cont if it is a thread) up to the prompt +tagged by prompt-tag. If cont is #f, the +resulting set of continuation marks is empty. If cont is an escape +continuation (see Prompts, Delimited Continuations, and Barriers), then the current +continuation must extend cont, or the +exn:fail:contract exception is raised. If cont was not captured with +respect to prompt-tag and does not include a prompt for +prompt-tag, the exn:fail:contract exception is raised. If +cont is a dead thread, the result is an empty set of +continuation marks.

Returns an opaque value containing the set of continuation marks for +all keys in the current continuation up to prompt-tag. In +other words, it produces the same value as

(call-with-current-continuation
  (lambda (k)
    (continuation-marks k prompt-tag))
  prompt-tag)

procedure

(continuation-mark-set->list mark-set    
  key-v    
  [prompt-tag])  list?
  mark-set : (or/c continuation-mark-set? #f)
  key-v : any/c
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
Returns a newly-created list containing the marks for key-v +in mark-set, which is a set of marks returned by +current-continuation-marks or #f as a shorthand for +(current-continuation-marks prompt-tag). The result list is truncated at +the first point, if any, where continuation frames were originally +separated by a prompt tagged with prompt-tag. Producing the result +takes time proportional to the size of the continuation reflected by +mark-set.

Changed in version 8.0.0.1 of package base: Changed to allow mark-set as #f.

procedure

(continuation-mark-set->list* mark-set    
  key-list    
  [none-v    
  prompt-tag])  (listof vector?)
  mark-set : (or/c continuation-mark-set? #f)
  key-list : (listof any/c)
  none-v : any/c = #f
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
Returns a newly-created list containing vectors of marks in +mark-set for the keys in key-list, up to +prompt-tag, where a #f value for mark-set +is equivalent to (current-continuation-marks prompt-tag). +The length of each vector in the result list is +the same as the length of key-list, and a value in a +particular vector position is the value for the corresponding key in +key-list. Values for multiple keys appear in a single vector +only when the marks are for the same continuation frame in +mark-set. The none-v argument is used for vector +elements to indicate the lack of a value. Producing the result +takes time proportional to the size of the continuation reflected by +mark-set times the length of key-list.

Changed in version 8.0.0.1 of package base: Changed to allow mark-set as #f.

procedure

(continuation-mark-set->iterator mark-set 
  key-list 
  [none-v 
  prompt-tag]) 
  (-> (values (or/c vector? #f) procedure?))
  mark-set : (or/c continuation-mark-set? #f)
  key-list : (listof any/c)
  none-v : any/c = #f
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
Like continuation-mark-set->list*, but instead of returning a +list of values, returns a functional iterator in the form of a +procedure that returns one element of the would-be list and a new +iterator function for the rest of the would-be list. An iterator +procedure returns #f instead of a vector when no more +elements are available; in that case, the returned iterator +procedure is like the called one, producing no further values. +The time required for each step is proportional to the length of +key-list times the size of the segment of the continuation +reflected by mark-set between frames that have keys in +key-list.

Added in version 7.5.0.7 of package base.
Changed in version 8.0.0.1: Changed to allow mark-set as #f.

procedure

(continuation-mark-set-first mark-set    
  key-v    
  [none-v    
  prompt-tag])  any
  mark-set : (or/c continuation-mark-set? #f)
  key-v : any/c
  none-v : any/c = #f
  prompt-tag : continuation-prompt-tag?
   = (default-continuation-prompt-tag)
Returns the first element of the list that would be returned by +(continuation-mark-set->list (or mark-set (current-continuation-marks prompt-tag)) key-v prompt-tag), or +none-v if the result would be the empty list.

The result +is produced in (amortized) constant time. Typically, this +result can be computed more quickly using +continuation-mark-set-first than using +continuation-mark-set->list or by using +continuation-mark-set->iterator and iterating just once.

Although #f and (current-continuation-marks prompt-tag) are equivalent for mark-set, providing #f +as mark-set can enable shortcuts that make it even faster.

procedure

(call-with-immediate-continuation-mark key-v    
  proc    
  [default-v])  any
  key-v : any/c
  proc : (any/c . -> . any)
  default-v : any/c = #f
Calls proc with the value associated with key-v in +the first frame of the current continuation (i.e., a value that would +be replaced if the call to +call-with-immediate-continuation-mark were replaced with a +with-continuation-mark form using key-v as the key +expression). If no such value exists in the first frame, +default-v is passed to proc. The proc is +called in tail position with respect to the +call-with-immediate-continuation-mark call.

This function could be implemented with a combination of +with-continuation-mark, current-continuation-marks, +and continuation-mark-set->list*, as shown below, but +call-with-immediate-continuation-mark is implemented more +efficiently; it inspects only the first frame of the current +continuation.

; Equivalent, but inefficient:
(define (call-with-immediate-continuation-mark key-v proc [default-v #f])
  (define private-key (gensym))
  (with-continuation-mark
   private-key #t
   (let ([vecs (continuation-mark-set->list* (current-continuation-marks)
                                             (list key-v private-key)
                                             default-v)])
     (proc (vector-ref (car vecs) 0)))))

Creates a continuation mark key that is not equal? to the result +of any other value (including prior and future results from +make-continuation-mark-key). The continuation mark key can be used +as the key argument for with-continuation-mark or accessor procedures +like continuation-mark-set-first. The mark key can be chaperoned +or impersonated, unlike other values that are used as the mark key.

The optional sym argument, if provided, is used when printing +the continuation mark.

procedure

(continuation-mark-key? v)  boolean?

  v : any/c
Returns #t if v is a mark key created by +make-continuation-mark-key, #f otherwise.

procedure

(continuation-mark-set? v)  boolean?

  v : any/c
Returns #t if v is a mark set created by +continuation-marks or current-continuation-marks, +#f otherwise.

procedure

(continuation-mark-set->context mark-set    
  [realms?])  list?
  mark-set : continuation-mark-set?
  realms? : any/c = #f
Returns a list representing an approximate “stack trace” for mark-set’s continuation. +The list contains pairs if realms? is #f, where the +car of each pair contains either #f or a symbol for +a procedure name, and the cdr of each pair contains either +#f or a srcloc value for the procedure’s source +location (see Counting Positions, Lines, and Columns); the car and cdr +are never both #f. If realms? is true, the list +contains 3-element vectors, where the first two elements are like the +values for a pair, and the third element is a realm symbol.

Conceptually, the stack-trace list is the result of +continuation-mark-set->list with mark-set and +Racket’s private key for procedure-call marks. The implementation may +be different, however, and the results may merely approximate the +correct answer. Thus, while the result may contain useful hints to +humans about the context of an expression, it is not reliable enough +for programmatic use.

A stack trace is extracted from an exception and displayed by the +default error display handler (see +error-display-handler) for exceptions other than +exn:fail:user (see raise-user-error in +Raising Exceptions).

Examples:
> (define (extract-current-continuation-marks key)
    (continuation-mark-set->list
     (current-continuation-marks)
     key))
> (with-continuation-mark 'key 'mark
    (extract-current-continuation-marks 'key))

'(mark)

> (with-continuation-mark 'key1 'mark1
    (with-continuation-mark 'key2 'mark2
      (list
       (extract-current-continuation-marks 'key1)
       (extract-current-continuation-marks 'key2))))

'((mark1) (mark2))

> (with-continuation-mark 'key 'mark1
    (with-continuation-mark 'key 'mark2 ; replaces previous mark
      (extract-current-continuation-marks 'key)))

'(mark2)

> (with-continuation-mark 'key 'mark1
    (list ; continuation extended to evaluate the argument
     (with-continuation-mark 'key 'mark2
        (extract-current-continuation-marks 'key))))

'((mark2 mark1))

> (let loop ([n 1000])
    (if (zero? n)
        (extract-current-continuation-marks 'key)
        (with-continuation-mark 'key n
          (loop (sub1 n)))))

'(1)

Changed in version 8.4.0.2 of package base: Added the realms? argument.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/contract-utilities.html b/clones/docs.racket-lang.org/reference/contract-utilities.html new file mode 100644 index 00000000..f293ed17 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/contract-utilities.html @@ -0,0 +1,98 @@ + +8.8 Contract Utilities

8.8 Contract Utilities

procedure

(contract? v)  boolean?

  v : any/c
Returns #t if its argument is a contract (i.e., constructed +with one of the combinators described in this section or a value that +can be used as a contract) and #f otherwise.

procedure

(chaperone-contract? v)  boolean?

  v : any/c
Returns #t if its argument is a chaperone contract, +i.e., one that guarantees that +it returns a value which passes chaperone-of? when compared to +the original, uncontracted value.

procedure

(impersonator-contract? v)  boolean?

  v : any/c
Returns #t if its argument is an impersonator contract, +i.e., a contract that is neither a chaperone contract +nor a flat contract.

procedure

(flat-contract? v)  boolean?

  v : any/c
Returns #t when its argument is a contract that can be +checked immediately (unlike, say, a function contract).

For example, +flat-contract constructs flat contracts from predicates, and +symbols, booleans, numbers, and other ordinary Racket values +(that are defined as contracts) are also +flat contracts.

procedure

(list-contract? v)  boolean?

  v : any/c
Recognizes certain contract? values that accept list?s.

A list contract is one that insists that its argument +is a list?, meaning that the value cannot be cyclic +and must either be the empty list or a pair constructed +with cons and another list.

Added in version 6.0.1.13 of package base.

procedure

(contract-name c)  any/c

  c : contract?
Produces the name used to describe the contract in error messages.

procedure

(value-contract v)  (or/c contract? #f)

  v : has-contract?
Returns the contract attached to v, if recorded. +Otherwise it returns #f.

To support value-contract and value-contract +in your own contract combinators, use prop:contracted or +impersonator-prop:contracted.

procedure

(has-contract? v)  boolean?

  v : any/c
Returns #t if v is a value that +has a recorded contract attached to it.

procedure

(value-blame v)  (or/c blame? #f)

  v : has-blame?
Returns the blame object for the contract attached +to v, if recorded. Otherwise it returns #f.

To support value-contract and value-blame +in your own contract combinators, use prop:blame or +impersonator-prop:blame.

Added in version 6.0.1.12 of package base.

procedure

(has-blame? v)  boolean?

  v : any/c
Returns #t if v is a value that +has a contract with blame information attached to it.

Added in version 6.0.1.12 of package base.

procedure

(contract-late-neg-projection c)

  (-> blame? (-> any/c (or/c #f any/c) any/c))
  c : contract?
Produces the projection defining a contract’s behavior.

The first argument, blame? object encapsulates information about +the contract checking, mostly used to create a meaningful error message if +a contract violation is detected. The resulting function’s first argument +is the value that should have the contract and its second argument is +a missing party for the blame object, to be passed to raise-contract-error.

If possible, use this function instead of contract-val-first-projection or +contract-projection.

procedure

(contract-projection c)  (-> blame? (-> any/c any/c))

  c : contract?
Produces a projection defining a contract’s behavior. +This projection is a curried function of two arguments: the first application +accepts a blame object, and the second accepts a value to protect with the +contract.

If possible, use contract-late-neg-projection instead.

procedure

(contract-val-first-projection c)

  (-> blame? (-> any/c (-> any/c any/c)))
  c : contract?
Produces a projection defining a contract’s behavior. +This projection is similar to the result of contract-late-neg-projection +except with an extra layer of currying.

If possible, use contract-late-neg-projection instead.

procedure

(make-none/c sexp-name)  contract?

  sexp-name : any/c
Makes a contract that accepts no values, and reports the +name sexp-name when signaling a contract violation.

syntax

(recursive-contract contract-expr recursive-contract-option ...)

(recursive-contract contract-expr type recursive-contract-option ...)
 
recursive-contract-option = #:list-contract?
  | #:extra-delay
     
type = #:impersonator
  | #:chaperone
  | #:flat
Delays the evaluation of its argument until the contract is checked, +making recursive contracts possible. +If type is not given, an impersonator contract is created.

If the recursive-contract-option +#:list-contract? is given, then the result is a +list-contract? and the contract-expr must +evaluate to a list-contract?.

If the recursive-contract-option #:extra-delay is given, +then the contract-expr expression is evaluated only when the first +value to be checked against the contract is supplied to the contract. +Without it, the contract-expr is evaluated earlier. This option +is supported only when type is #:flat.

Examples:
> (define even-length-list/c
    (or/c null?
          (cons/c any/c
                  (cons/c any/c
                          (recursive-contract even-length-list/c #:flat)))))
> (even-length-list/c '(A B))

#t

> (even-length-list/c '(1 2 3))

#f

Changed in version 6.0.1.13 of package base: Added the #:list-contract? option.
Changed in version 6.7.0.3: Added the #:extra-delay option.

syntax

(opt/c contract-expr maybe-name)

 
maybe-name = 
  | #:error-name id
This optimizes its argument contract expression by +traversing its syntax and, for known contract combinators, +fuses them into a single contract combinator that avoids as +much allocation overhead as possible. The result is a +contract that should behave identically to its argument, +except faster.

If the #:error-name argument is present, and +contract-expr evaluates to a non-contract +expression, then opt/c raises an error using +id as the name of the primitive, instead of using +the name opt/c.

Examples:
> (define/contract (f x)
    (opt/c '(not-a-contract))
    x)

opt/c: contract violation

  expected: contract?

  given: '(not-a-contract)

> (define/contract (f x)
    (opt/c '(not-a-contract) #:error-name define/contract)
    x)

define/contract: contract violation

  expected: contract?

  given: '(not-a-contract)

syntax

(define-opt/c (id id ...) expr)

This defines a recursive contract and simultaneously +optimizes it. As long as the defined function terminates, +define-opt/c behaves just as if +the -opt/c were not present, defining a function on +contracts (except that the body expression must return a +contract). But, it also optimizes that contract definition, +avoiding extra allocation, much like opt/c does.

For example,

(define-contract-struct bt (val left right))
 
(define-opt/c (bst-between/c lo hi)
  (or/c null?
        (bt/c [val (real-in lo hi)]
              [left (val) (bst-between/c lo val)]
              [right (val) (bst-between/c val hi)])))
 
(define bst/c (bst-between/c -inf.0 +inf.0))

defines the bst/c contract that checks the binary +search tree invariant. Removing the -opt/c also +makes a binary search tree contract, but one that is +(approximately) 20 times slower.

Note that in some cases, a call to a function defined by +define-opt/c may terminate, even if the corresponding +define-based function would not terminate. This is a +shortcoming in define-opt/c that we hope to understand +and fix at some point, but have no concrete plans currently.

Key used by continuation marks that are present during contract checking. +The value of these marks are the blame objects that correspond to the contract +currently being checked.

Added in version 6.4.0.4 of package base.

procedure

(contract-custom-write-property-proc c    
  p    
  mode)  void?
  c : contract?
  p : output-port?
  mode : (or/c #f #t 0 1)
Prints c to p using the contract’s name.

Added in version 6.1.1.5 of package base.

procedure

(rename-contract contract name)  contract?

  contract : contract?
  name : any/c
Produces a contract that acts like contract but with the name +name.

The resulting contract is a flat contract if contract is a +flat contract.

Added in version 6.3 of package base.

syntax

(contract-first-order-okay-to-give-up?)

This form returns a boolean that controls the result +of first-order contact checks. More specifically, if +it returns #t, then a first-order check may +return #t even when the entire first-order +checks have not happened. If it returns #f +then the first order checks must continue until a +definitive answer is returned.

This will only return #t in the dynamic +extent of or/c or first-or/c’s +checking to determine which branch to use.

Added in version 6.3.0.9 of package base.

syntax

(contract-first-order-try-less-hard e)

Encourages first-order checks that happen in the +dynamic-extent of e to be more likely to +give up. That is, makes it more likely that +contract-first-order-okay-to-give-up? might +return #t.

If not in the dynamic-extent of or/c’s or +first-or/c’s checking to determine the branch, +then this form has no effect.

Added in version 6.3.0.9 of package base.

procedure

(if/c predicate then-contract else-contract)  contract?

  predicate : (-> any/c any/c)
  then-contract : contract?
  else-contract : contract?
Produces a contract that, when applied to a value, first tests the +value with predicate; if predicate returns true, the +then-contract is applied; otherwise, the +else-contract is applied. The resulting contract is a +flat contract if both then-contract and else-contract are +flat contracts.

For example, the following contract enforces that if a value is a +procedure, it is a thunk; otherwise it can be any (non-procedure) +value: +
Note that the following contract is not equivalent: +

(or/c (-> any) any/c) ; wrong!

The last contract is the same as any/c because +or/c tries flat contracts before higher-order contracts.

Added in version 6.3 of package base.

A contract that describes the failure result arguments of procedures +such as hash-ref.

Equivalent to (if/c procedure? (-> any) any/c).

Added in version 6.3 of package base.

procedure

(get/build-val-first-projection c)

  (-> blame? (-> any/c (-> any/c any/c)))
  c : contract?
Returns the val-first projection for c.

See make-contract for more details.

Added in version 6.1.1.5 of package base.

procedure

(get/build-late-neg-projection c)

  (-> blame? (-> any/c any/c any/c))
  c : contract?
Returns the late-neg projection for c.

If c does not have a late-neg contract, +then this function uses the original projection for it +and logs a warning to the 'racket/contract logger.

See make-contract for more details.

Added in version 6.2.900.11 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/contracts.html b/clones/docs.racket-lang.org/reference/contracts.html new file mode 100644 index 00000000..a8566ffc --- /dev/null +++ b/clones/docs.racket-lang.org/reference/contracts.html @@ -0,0 +1,47 @@ + +8 Contracts

8 Contracts

+Contracts in The Racket Guide introduces contracts.

The contract system guards one part of a program from +another. Programmers specify the behavior of a module’s exports via +(provide (contract-out ....)), and the contract system enforces those +constraints.

The bindings documented in this section are provided by the racket/contract and racket libraries, but not racket/base.

Contracts come in two forms: those constructed by the +various operations listed in this section of the manual, and various +ordinary Racket values that double as contracts, including +
  • symbols, booleans, keywords, and +null, which are treated as contracts that recognize +themselves, using eq?,

  • strings, byte strings, characters, ++nan.0, and +nan.f, which are treated +as contracts that recognize themselves using equal?,

  • numbers (except +nan.0 and + +nan.f), which are treated as contracts +that recognize themselves using =,

  • regular expressions, which are treated as contracts + that recognize byte strings and strings that + match the regular expression, and

  • predicates: any procedure of arity 1 is treated as a +predicate. During contract checking, it is applied to the values that +appear and should return #f to indicate that the contract +failed, and anything else to indicate it passed.

Contract combinators are functions such as -> and +listof that take contracts and produce other contracts.

Contracts in Racket are subdivided into three different categories: +
  • Flat contracts can be fully checked immediately for + a given value. These kinds of contracts are essentially + predicate functions. Using flat-contract-predicate, + you can extract the predicate from an arbitrary flat contract; some + flat contracts can be applied like functions, in which case + they accept a single argument and return #t or + #f to indicate if the given value would be accepted + by the contract. All of the flat contracts returned by functions + in this library can be used directly as predicates, but ordinary + Racket values that double as flat contracts (e.g., numbers or symbols) + cannot.

    The function flat-contract? recognizes a flat contract.

  • Chaperone contracts may wrap a value in such + a way that it signals contract violations later, as the value + is used, but are guaranteed to not otherwise change behavior. + For example, a function contract wraps a function value and + later checks inputs and outputs; any properties that the + function value had before being wrapped by the contract are + preserved by the contract wrapper.

    All flat contracts may be used where chaperone contracts are expected + (but not vice-versa). The function chaperone-contract? + recognizes a chaperone contract.

  • Impersonator contracts may wrap values and do + not provide any guarantees. Impersonator contracts + may hide properties of values, or even make them completely + opaque (e.g, new-∀/c).

    All contracts may be used where impersonator contracts are expected. + The function impersonator-contract? recognizes an + impersonator contract.

For more about this hierarchy, see the section “Impersonators and Chaperones” +as well as a research paper [Strickland12] on chaperones, impersonators, +and how they can be used to implement contracts.

Changed in version 6.1.1.8 of package base: Changed +nan.0 and +nan.f to + be equal?-based contracts.

    8.1 Data-structure Contracts

    8.2 Function Contracts

    8.3 Parametric Contracts

    8.4 Lazy Data-structure Contracts

    8.5 Structure Type Property Contracts

    8.6 Attaching Contracts to Values

      8.6.1 Nested Contract Boundaries

      8.6.2 Low-level Contract Boundaries

    8.7 Building New Contract Combinators

      8.7.1 Blame Objects

      8.7.2 Contracts as structs

      8.7.3 Obligation Information in Check Syntax

      8.7.4 Utilities for Building New Combinators

    8.8 Contract Utilities

    8.9 racket/contract/base

    8.10 Collapsible Contracts

    8.11 Legacy Contracts

    8.12 Random generation

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/control.html b/clones/docs.racket-lang.org/reference/control.html new file mode 100644 index 00000000..3dae2f71 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/control.html @@ -0,0 +1,2 @@ + +10 Control Flow
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/createclass.html b/clones/docs.racket-lang.org/reference/createclass.html new file mode 100644 index 00000000..790fb0a4 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/createclass.html @@ -0,0 +1,324 @@ + +6.2 Creating Classes

6.2 Creating Classes

+Classes and Objects in The Racket Guide introduces classes and objects.

value

object% : class?

A built-in class that has no methods fields, implements only its own +interface (class->interface object%), and is transparent +(i.e,. its inspector is #f, so all immediate instances are +equal?). All other classes are derived from object%.

syntax

(class* superclass-expr (interface-expr ...)
  class-clause
  ...)
 
class-clause = (inspect inspector-expr)
  | (init init-decl ...)
  | (init-field init-decl ...)
  | (field field-decl ...)
  | (inherit-field maybe-renamed ...)
  | (init-rest id)
  | (init-rest)
  | (public maybe-renamed ...)
  | (pubment maybe-renamed ...)
  | (public-final maybe-renamed ...)
  | (override maybe-renamed ...)
  | (overment maybe-renamed ...)
  | (override-final maybe-renamed ...)
  | (augment maybe-renamed ...)
  | (augride maybe-renamed ...)
  | (augment-final maybe-renamed ...)
  | (private id ...)
  | (abstract id ...)
  | (inherit maybe-renamed ...)
  | (inherit/super maybe-renamed ...)
  | (inherit/inner maybe-renamed ...)
  | (rename-super renamed ...)
  | (rename-inner renamed ...)
  | method-definition
  | definition
  | expr
  | (begin class-clause ...)
     
init-decl = id
  | (renamed)
  | (maybe-renamed default-value-expr)
     
field-decl = (maybe-renamed default-value-expr)
     
maybe-renamed = id
  | renamed
     
renamed = (internal-id external-id)
     
method-definition = (define-values (id) method-procedure)
     
method-procedure = (lambda kw-formals expr ...+)
  | (case-lambda (formals expr ...+) ...)
  | (#%plain-lambda formals expr ...+)
  | 
(let-values ([(id) method-procedure] ...)
  method-procedure)
  | 
(letrec-values ([(id) method-procedure] ...)
  method-procedure)
  | 
(let-values ([(id) method-procedure] ...+)
  id)
  | 
(letrec-values ([(id) method-procedure] ...+)
  id)
  | 
(chaperone-procedure method-procedure wrapper-proc
                     other-arg-expr ...)
Produces a class value.

The superclass-expr expression is evaluated when the +class* expression is evaluated. The result must be a class +value (possibly object%), otherwise the +exn:fail:object exception is raised. The result of the +superclass-expr expression is the new class’s superclass.

The interface-expr expressions are also evaluated when the +class* expression is evaluated, after +superclass-expr is evaluated. The result of each +interface-expr must be an interface value, otherwise the +exn:fail:object exception is raised. The interfaces returned by the +interface-exprs are all implemented by the class. For each +identifier in each interface, the class (or one of its ancestors) must +declare a public method with the same name, otherwise the +exn:fail:object exception is raised. The class’s superclass must satisfy the +implementation requirement of each interface, otherwise the +exn:fail:object exception is raised.

An inspect class-clause selects an inspector (see +Structure Inspectors) for the class extension. The +inspector-expr must evaluate to an inspector or #f +when the class* form is evaluated. Just as for structure +types, an inspector controls access to the class’s fields, including +private fields, and also affects comparisons using equal?. If +no inspect clause is provided, access to the class is +controlled by the parent of the current inspector (see +Structure Inspectors). A syntax error is reported if more than one +inspect clause is specified.

The other class-clauses define initialization arguments, +public and private fields, and public and private methods. For each +id or maybe-renamed in a public, +override, augment, pubment, +overment, augride, public-final, +override-final, augment-final, or private +clause, there must be one method-definition. All other +definition class-clauses create private fields. All remaining +exprs are initialization expressions to be evaluated when the +class is instantiated (see Creating Objects).

The result of a class* expression is a new class, derived +from the specified superclass and implementing the specified +interfaces. Instances of the class are created with the +instantiate form or make-object procedure, as +described in Creating Objects.

Each class-clause is (partially) macro-expanded to reveal its +shapes. If a class-clause is a begin expression, its +sub-expressions are lifted out of the begin and treated as +class-clauses, in the same way that begin is +flattened for top-level and embedded definitions.

Within a class* form for instances of the new class, +this is bound to the object itself; +this% is bound to the class of the object; +super-instantiate, super-make-object, and +super-new are bound to forms to initialize fields in the +superclass (see Creating Objects); super is +available for calling superclass methods (see +Method Definitions); and inner is available for +calling subclass augmentations of methods (see +Method Definitions).

syntax

(class superclass-expr class-clause ...)

Like class*, but omits the interface-exprs, for the case that none are needed.

Example:
(define book-class%
  (class object%
    (field (pages 5))
    (define/public (letters)
      (* pages 500))
    (super-new)))

syntax

this

Within a class* form, this refers +to the current object (i.e., the object being initialized or whose +method was called). Use outside the body of a class* form is +a syntax error.

Examples:
(define (describe obj)
  (printf "Hello ~a\n" obj))
(define table%
  (class object%
    (define/public (describe-self)
      (describe this))
    (super-new)))

 

> (send (new table%) describe-self)

Hello #(struct:object:table% ...)

syntax

this%

Within a class* form, this% refers to the class +of the current object (i.e., the object being initialized or whose +method was called). Use outside the body of a class* form is +a syntax error.

Examples:
(define account%
  (class object%
    (super-new)
    (init-field balance)
    (define/public (add n)
      (new this% [balance (+ n balance)]))))
(define savings%
  (class account%
    (super-new)
    (inherit-field balance)
    (define interest 0.04)
    (define/public (add-interest)
      (send this add (* interest balance)))))

 

> (let* ([acct (new savings% [balance 500])]
         [acct (send acct add 500)]
         [acct (send acct add-interest)])
    (printf "Current balance: ~a\n" (get-field balance acct)))

Current balance: 1040.0

syntax

(inspect inspector-expr)

See class*; use outside the body of a class* form is a syntax error.

syntax

(init init-decl ...)

See class* and Initialization Variables; use outside the body of a class* form is a syntax error.

Example:
> (class object%
    (super-new)
    (init turnip
          [(internal-potato potato)]
          [carrot 'good]
          [(internal-rutabaga rutabaga) 'okay]))

#<class:eval:10:0>

syntax

(init-field init-decl ...)

See class*, Initialization Variables, and Fields; use outside the body of a class* form is a syntax error.

Example:
> (class object%
    (super-new)
    (init-field turkey
                [(internal-ostrich ostrich)]
                [chicken 7]
                [(internal-emu emu) 13]))

#<class:eval:11:0>

syntax

(field field-decl ...)

See class* and Fields; use outside the body of a class* form is a syntax error.

Example:
> (class object%
    (super-new)
    (field [minestrone 'ready]
           [(internal-coq-au-vin coq-au-vin) 'stewing]))

#<class:eval:12:0>

syntax

(inherit-field maybe-renamed ...)

See class* and Fields; use outside the body of a class* form is a syntax error.

Examples:
(define cookbook%
  (class object%
    (super-new)
    (field [recipes '(caldo-verde oyakodon eggs-benedict)]
           [pages 389])))

 

> (class cookbook%
    (super-new)
    (inherit-field recipes
                   [internal-pages pages]))

#<class:eval:14:0>

syntax

(init-rest id)

(init-rest)
See class* and Initialization Variables; use outside the body of a class* form is a syntax error.

Examples:
(define fruit-basket%
  (class object%
    (super-new)
    (init-rest fruits)
    (displayln fruits)))

 

> (make-object fruit-basket% 'kiwi 'lychee 'melon)

(kiwi lychee melon)

(object:fruit-basket% ...)

syntax

(public maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define jumper%
  (class object%
    (super-new)
    (define (skip) 'skip)
    (define (hop) 'hop)
    (public skip [hop jump])))

 

> (send (new jumper%) skip)

'skip

> (send (new jumper%) jump)

'hop

syntax

(pubment maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define runner%
  (class object%
    (super-new)
    (define (run) 'run)
    (define (trot) 'trot)
    (pubment run [trot jog])))

 

> (send (new runner%) run)

'run

> (send (new runner%) jog)

'trot

syntax

(public-final maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define point%
  (class object%
    (super-new)
    (init-field [x 0] [y 0])
     (define (get-x) x)
    (define (do-get-y) y)
    (public-final get-x [do-get-y get-y])))

 

> (send (new point% [x 1] [y 3]) get-y)

3

> (class point%
    (super-new)
    (define (get-x) 3.14)
    (override get-x))

class*: cannot override or augment final method

  method name: get-x

  class name: eval:25:0

syntax

(override maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define sheep%
  (class object%
    (super-new)
    (define/public (bleat)
      (displayln "baaaaaaaaah"))))

 

(define confused-sheep%
  (class sheep%
    (super-new)
    (define (bleat)
      (super bleat)
      (displayln "???"))
    (override bleat)))

 

> (send (new sheep%) bleat)

baaaaaaaaah

> (send (new confused-sheep%) bleat)

baaaaaaaaah

???

syntax

(overment maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define turkey%
  (class object%
    (super-new)
    (define/public (gobble)
      (displayln "gobble gobble"))))

 

(define extra-turkey%
  (class turkey%
    (super-new)
    (define (gobble)
      (super gobble)
      (displayln "gobble gobble gobble")
      (inner (void) gobble))
    (overment gobble)))

 

(define cyborg-turkey%
  (class extra-turkey%
    (super-new)
    (define/augment (gobble)
      (displayln "110011111011111100010110001011011001100101"))))

 

> (send (new extra-turkey%) gobble)

gobble gobble

gobble gobble gobble

> (send (new cyborg-turkey%) gobble)

gobble gobble

gobble gobble gobble

110011111011111100010110001011011001100101

syntax

(override-final maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define meeper%
  (class object%
    (super-new)
    (define/public (meep)
      (displayln "meep"))))

 

(define final-meeper%
  (class meeper%
    (super-new)
    (define (meep)
      (super meep)
      (displayln "This meeping ends with me"))
    (override-final meep)))

 

> (send (new meeper%) meep)

meep

> (send (new final-meeper%) meep)

meep

This meeping ends with me

syntax

(augment maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define buzzer%
  (class object%
    (super-new)
    (define/pubment (buzz)
      (displayln "bzzzt")
      (inner (void) buzz))))

 

(define loud-buzzer%
  (class buzzer%
    (super-new)
    (define (buzz)
      (displayln "BZZZZZZZZZT"))
    (augment buzz)))

 

> (send (new buzzer%) buzz)

bzzzt

> (send (new loud-buzzer%) buzz)

bzzzt

BZZZZZZZZZT

syntax

(augride maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

syntax

(augment-final maybe-renamed ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

syntax

(private id ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define light%
  (class object%
    (super-new)
    (define on? #t)
    (define (toggle) (set! on? (not on?)))
    (private toggle)
    (define (flick) (toggle))
    (public flick)))

 

> (send (new light%) toggle)

send: no such method

  method name: toggle

  class name: light%

> (send (new light%) flick)

syntax

(abstract id ...)

See class* and Method Definitions; use outside the body of a class* form is a syntax error.

Examples:
(define train%
  (class object%
    (super-new)
    (abstract get-speed)
    (init-field [position 0])
    (define/public (move)
      (new this% [position (+ position (get-speed))]))))

 

(define acela%
  (class train%
    (super-new)
    (define/override (get-speed) 241)))

 

(define talgo-350%
  (class train%
    (super-new)
    (define/override (get-speed) 330)))

 

> (new train%)

instantiate: cannot instantiate class with abstract methods

  class: #<class:train%>

  abstract methods:

   get-speed

> (send (new acela%) move)

(object:acela% ...)

syntax

(inherit maybe-renamed ...)

See class* and Inherited and Superclass Methods; use outside the body of a class* form is a syntax error.

Examples:
(define alarm%
  (class object%
    (super-new)
    (define/public (alarm)
      (displayln "beeeeeeeep"))))

 

(define car-alarm%
  (class alarm%
    (super-new)
    (init-field proximity)
    (inherit alarm)
    (when (< proximity 10)
      (alarm))))

 

> (new car-alarm% [proximity 5])

beeeeeeeep

(object:car-alarm% ...)

syntax

(inherit/super maybe-renamed ...)

See class* and Inherited and Superclass Methods; use outside the body of a class* form is a syntax error.

syntax

(inherit/inner maybe-renamed ...)

See class* and Inherited and Superclass Methods; use outside the body of a class* form is a syntax error.

syntax

(rename-super renamed ...)

See class* and Inherited and Superclass Methods; use outside the body of a class* form is a syntax error.

syntax

(rename-inner renamed ...)

See class* and Inherited and Superclass Methods; use outside the body of a class* form is a syntax error.

syntax

(public* (id expr) ...)

Shorthand for (begin (public id) ... (define id expr) ...).

syntax

(pubment* (id expr) ...)

Shorthand for (begin (pubment id) ... (define id expr) ...).

syntax

(public-final* (id expr) ...)

Shorthand for (begin (public-final id) ... (define id expr) ...).

syntax

(override* (id expr) ...)

Shorthand for (begin (override id) ... (define id expr) ...).

syntax

(overment* (id expr) ...)

Shorthand for (begin (overment id) ... (define id expr) ...).

syntax

(override-final* (id expr) ...)

Shorthand for (begin (override-final id) ... (define id expr) ...).

syntax

(augment* (id expr) ...)

Shorthand for (begin (augment id) ... (define id expr) ...).

syntax

(augride* (id expr) ...)

Shorthand for (begin (augride id) ... (define id expr) ...).

syntax

(augment-final* (id expr) ...)

Shorthand for (begin (augment-final id) ... (define id expr) ...).

syntax

(private* (id expr) ...)

Shorthand for (begin (private id) ... (define id expr) ...).

syntax

(define/public id expr)

(define/public (id . formals) body ...+)
Shorthand for (begin (public id) (define id expr)) or (begin (public id) (define (id . formals) body ...+))

syntax

(define/pubment id expr)

(define/pubment (id . formals) body ...+)
Shorthand for (begin (pubment id) (define id expr)) or (begin (pubment id) (define (id . formals) body ...+))

syntax

(define/public-final id expr)

(define/public-final (id . formals) body ...+)
Shorthand for (begin (public-final id) (define id expr)) or (begin (public-final id) (define (id . formals) body ...+))

syntax

(define/override id expr)

(define/override (id . formals) body ...+)
Shorthand for (begin (override id) (define id expr)) or (begin (override id) (define (id . formals) body ...+))

syntax

(define/overment id expr)

(define/overment (id . formals) body ...+)
Shorthand for (begin (overment id) (define id expr)) or (begin (overment id) (define (id . formals) body ...+))

syntax

(define/override-final id expr)

(define/override-final (id . formals) body ...+)
Shorthand for (begin (override-final id) (define id expr)) or (begin (override-final id) (define (id . formals) body ...+))

syntax

(define/augment id expr)

(define/augment (id . formals) body ...+)
Shorthand for (begin (augment id) (define id expr)) or (begin (augment id) (define (id . formals) body ...+))

syntax

(define/augride id expr)

(define/augride (id . formals) body ...+)
Shorthand for (begin (augride id) (define id expr)) or (begin (augride id) (define (id . formals) body ...+))

syntax

(define/augment-final id expr)

(define/augment-final (id . formals) body ...+)
Shorthand for (begin (augment-final id) (define id expr)) or (begin (augment-final id) (define (id . formals) body ...+))

syntax

(define/private id expr)

(define/private (id . formals) body ...+)
Shorthand for (begin (private id) (define id expr)) or (begin (private id) (define (id . formals) body ...+))

syntax

(class/derived original-datum
  (name-id super-expr (interface-expr ...) deserialize-id-expr)
  class-clause
  ...)
Like class*, but includes a sub-expression to be used as the +source for all syntax errors within the class definition. For example, +define-serializable-class expands to class/derived +so that errors in the body of the class are reported in terms of +define-serializable-class instead of class.

The original-datum is the original expression to use for +reporting errors.

The name-id is used to name the resulting class; if it +is #f, the class name is inferred.

The super-expr, interface-exprs, and +class-clauses are as for class*.

If the deserialize-id-expr is not literally #f, then +a serializable class is generated, and the result is two values +instead of one: the class and a deserialize-info structure produced by +make-deserialize-info. The deserialize-id-expr +should produce a value suitable as the second argument to +make-serialize-info, and it should refer to an export whose +value is the deserialize-info structure.

Future optional forms may be added to the sequence that currently ends +with deserialize-id-expr.

6.2.1 Initialization Variables

A class’s initialization variables, declared with init, +init-field, and init-rest, are instantiated +for each object of a class. Initialization variables can be used in +the initial value expressions of fields, default value expressions +for initialization arguments, and in initialization expressions. Only +initialization variables declared with init-field can be +accessed from methods; accessing any other initialization variable +from a method is a syntax error.

The values bound to initialization variables are

  • the arguments provided with instantiate or passed to +make-object, if the object is created as a direct instance +of the class; or,

  • the arguments passed to the superclass initialization form or +procedure, if the object is created as an instance of a derived +class.

If an initialization argument is not provided for an initialization +variable that has an associated default-value-expr, then the +default-value-expr expression is evaluated to obtain a value +for the variable. A default-value-expr is only evaluated when +an argument is not provided for its variable. The environment of +default-value-expr includes all of the initialization +variables, all of the fields, and all of the methods of the class. If +multiple default-value-exprs are evaluated, they are +evaluated from left to right. Object creation and field initialization +are described in detail in Creating Objects.

If an initialization variable has no default-value-expr, then +the object creation or superclass initialization call must supply an +argument for the variable, otherwise the exn:fail:object exception is raised.

Initialization arguments can be provided by name or by position. The +external name of an initialization variable can be used with +instantiate or with the superclass initialization form. Those +forms also accept by-position arguments. The make-object +procedure and the superclass initialization procedure accept only +by-position arguments.

Arguments provided by position are converted into by-name arguments +using the order of init and init-field clauses and +the order of variables within each clause. When an instantiate +form provides both by-position and by-name arguments, the converted +arguments are placed before by-name arguments. (The order can be +significant; see also Creating Objects.)

Unless a class contains an init-rest clause, when the number +of by-position arguments exceeds the number of declared initialization +variables, the order of variables in the superclass (and so on, up the +superclass chain) determines the by-name conversion.

If a class expression contains an init-rest clause, there +must be only one, and it must be last. If it declares a variable, then +the variable receives extra by-position initialization arguments as a +list (similar to a dotted “rest argument” in a procedure). An +init-rest variable can receive by-position initialization +arguments that are left over from a by-name conversion for a derived +class. When a derived class’s superclass initialization provides even +more by-position arguments, they are prefixed onto the by-position +arguments accumulated so far.

If too few or too many by-position initialization arguments are +provided to an object creation or superclass initialization, then the +exn:fail:object exception is raised. Similarly, if extra by-position arguments +are provided to a class with an init-rest clause, the +exn:fail:object exception is raised.

Unused (by-name) arguments are to be propagated to the superclass, as +described in Creating Objects. Multiple initialization +arguments can use the same name if the class derivation contains +multiple declarations (in different classes) of initialization +variables with the name. See Creating Objects for further +details.

See also Internal and External Names for information about internal and +external names.

6.2.2 Fields

Each field, init-field, and non-method +define-values clause in a class declares one or more new +fields for the class. Fields declared with field or +init-field are public. Public fields can be accessed and +mutated by subclasses using inherit-field. Public fields are +also accessible outside the class via class-field-accessor +and mutable via class-field-mutator (see +Field and Method Access). Fields declared with define-values +are accessible only within the class.

A field declared with init-field is both a public field and +an initialization variable. See Initialization Variables for +information about initialization variables.

An inherit-field declaration makes a public field defined by +a superclass directly accessible in the class expression. If the +indicated field is not defined in the superclass, the +exn:fail:object exception is raised when the class expression is evaluated. +Every field in a superclass is present in a derived class, even if it +is not declared with inherit-field in the derived class. The +inherit-field clause does not control inheritance, but merely +controls lexical scope within a class expression.

When an object is first created, all of its fields have the +#<undefined> value (see Void). The fields of a +class are initialized at the same time that the class’s initialization +expressions are evaluated; see Creating Objects for more +information.

See also Internal and External Names for information about internal and +external names.

6.2.3 Methods
6.2.3.1 Method Definitions

Each public, override, augment, +pubment, overment, augride, +public-final, override-final, +augment-final, and private +clause in a class declares one or more method names. Each method name +must have a corresponding method-definition. The order of +public, etc., clauses and their corresponding definitions +(among themselves, and with respect to other clauses in the class) +does not matter.

As shown in the grammar for class*, a method definition is +syntactically restricted to certain procedure forms, as defined by the +grammar for method-procedure; in the last two forms of +method-procedure, the body id must be one of the +ids bound by let-values or letrec-values. A +method-procedure expression is not evaluated +directly. Instead, for each method, a class-specific method procedure +is created; it takes an initial object argument, in addition to the +arguments the procedure would accept if the method-procedure +expression were evaluated directly. The body of the procedure is +transformed to access methods and fields through the object argument.

A method declared with public, pubment, or +public-final introduces a new method into a class. The method +must not be present already in the superclass, otherwise the +exn:fail:object exception is raised when the class expression is evaluated. A +method declared with public can be overridden in a subclass +that uses override, overment, or +override-final. A method declared with pubment can +be augmented in a subclass that uses augment, +augride, or augment-final. A method declared with +public-final cannot be overridden or augmented in a subclass.

A method declared with override, overment, or +override-final overrides a definition already present in the +superclass. If the method is not already present, the +exn:fail:object exception is raised when the class expression is evaluated. A +method declared with override can be overridden again in a +subclass that uses override, overment, or +override-final. A method declared with overment can +be augmented in a subclass that uses augment, +augride, or augment-final. A method declared with +override-final cannot be overridden further or augmented in a +subclass.

A method declared with augment, augride, or +augment-final augments a definition already present in the +superclass. If the method is not already present, the +exn:fail:object exception is raised when the class expression is evaluated. A +method declared with augment can be augmented further in a +subclass that uses augment, augride, or +augment-final. A method declared with augride can be +overridden in a subclass that uses override, +overment, or override-final. (Such an override +merely replaces the augmentation, not the method that is augmented.) +A method declared with augment-final cannot be overridden or +augmented further in a subclass.

A method declared with private is not accessible outside the +class expression, cannot be overridden, and never overrides a method +in the superclass.

When a method is declared with override, overment, +or override-final, then the superclass implementation of the +method can be called using super form.

When a method is declared with pubment, augment, or +overment, then a subclass augmenting method can be called +using the inner form. The only difference between +public-final and pubment without a corresponding +inner is that public-final prevents the declaration +of augmenting methods that would be ignored.

A method declared with abstract must be declared without +an implementation. Subclasses may implement abstract methods via the +override, overment, or override-final +forms. Any class that contains or inherits any abstract methods is +considered abstract and cannot be instantiated.

syntax

(super id arg ...)

(super id arg ... . arg-list-expr)
Always accesses the superclass method, independent of whether the +method is overridden again in subclasses. Using the super +form outside of class* is a syntax error. Each arg +is as for #%app: either arg-expr or +keyword arg-expr.

The second form is analogous to using apply with a procedure; +the arg-list-expr must not be a parenthesized expression.

syntax

(inner default-expr id arg ...)

(inner default-expr id arg ... . arg-list-expr)
If the object’s class does not supply an augmenting method, then +default-expr is evaluated, and the arg expressions +are not evaluated. Otherwise, the augmenting method is called with the +arg results as arguments, and default-expr is not +evaluated. If no inner call is evaluated for a particular +method, then augmenting methods supplied by subclasses are never +used. Using the inner form outside of class* is an +syntax error.

The second form is analogous to using apply with a procedure; +the arg-list-expr must not be a parenthesized expression.

6.2.3.2 Inherited and Superclass Methods

Each inherit, inherit/super, inherit/inner, +rename-super, and rename-inner clause declares one +or more methods that are defined in the class, but must be present in +the superclass. The rename-super and rename-inner +declarations are rarely used, since inherit/super and +inherit/inner provide the same access. Also, superclass and +augmenting methods are typically accessed through super and +inner in a class that also declares the methods, instead of +through inherit/super, inherit/inner, +rename-super, or rename-inner.

Method names declared with inherit, inherit/super, +or inherit/inner access overriding declarations, if any, at +run time. Method names declared with inherit/super can also +be used with the super form to access the superclass +implementation, and method names declared with inherit/inner +can also be used with the inner form to access an augmenting +method, if any.

Method names declared with rename-super always access the +superclass’s implementation at run-time. Methods declared with +rename-inner access a subclass’s augmenting method, if any, +and must be called with the form

(id (lambda () default-expr) arg ...)

so that a default-expr is available to evaluate when no +augmenting method is available. In such a form, lambda is a +literal identifier to separate the default-expr from the +arg. When an augmenting method is available, it receives the +results of the arg expressions as arguments.

Methods that are present in the superclass but not declared with +inherit, inherit/super, or inherit/inner or +rename-super are not directly accessible in the class +(though they can be called with send). Every public method +in a superclass is present in a derived class, even if it is not +declared with inherit in the derived class; the +inherit clause does not control inheritance, but merely +controls lexical scope within a class expression.

If a method declared with inherit, inherit/super, +inherit/inner, rename-super, or +rename-inner is not present in the superclass, the +exn:fail:object exception is raised when the class expression is evaluated.

6.2.3.3 Internal and External Names

Each method declared with public, override, +augment, pubment, overment, +augride, public-final, override-final, +augment-final, inherit, inherit/super, +inherit/inner, rename-super, and +rename-inner can have separate internal and external names +when (internal-id external-id) is used for declaring the +method. The internal name is used to access the method directly within +the class expression (including within super or +inner forms), while the external name is used with +send and generic (see Field and Method Access). If +a single id is provided for a method declaration, the +identifier is used for both the internal and external names.

Method inheritance, overriding, and augmentation are based on external +names only. Separate internal and external names are required for +rename-super and rename-inner (for historical +reasons, mainly).

Each init, init-field, field, or +inherit-field variable similarly has an internal and an +external name. The internal name is used within the class to access +the variable, while the external name is used outside the class when +providing initialization arguments (e.g., to instantiate), +inheriting a field, or accessing a field externally (e.g., with +class-field-accessor). As for methods, when inheriting a +field with inherit-field, the external name is matched to an +external field name in the superclass, while the internal name is +bound in the class expression.

A single identifier can be used as an internal identifier and an +external identifier, and it is possible to use the same identifier as +internal and external identifiers for different bindings. Furthermore, +within a single class, a single name can be used as an external method +name, an external field name, and an external initialization argument +name. Overall, each internal identifier must be distinct from all +other internal identifiers, each external method name must be distinct +from all other method names, each external field name must be distinct +from all other field names, and each initialization argument name must +be distinct from all other initialization argument names.

By default, external names have no lexical scope, which means, for +example, that an external method name matches the same syntactic +symbol in all uses of send. The +define-local-member-name and define-member-name forms +introduce scoped external names.

When a class expression is compiled, identifiers used in +place of external names must be symbolically distinct (when the +corresponding external names are required to be distinct), otherwise a +syntax error is reported. When no external name is bound by +define-member-name, then the actual external names are +guaranteed to be distinct when class expression is evaluated. +When any external name is bound by define-member-name, the +exn:fail:object exception is raised by class if the actual external +names are not distinct.

syntax

(define-local-member-name id ...)

Unless it appears as the top-level definition, binds each id +so that, within the scope of the definition, each use of each +id as an external name is resolved to a hidden name generated +by the define-local-member-name declaration. Thus, methods, +fields, and initialization arguments declared with such external-name +ids are accessible only in the scope of the +define-local-member-name declaration. As a top-level +definition, define-local-member-name binds id to its +symbolic form.

The binding introduced by define-local-member-name is a +syntax binding that can be exported and imported with +modules. Each evaluation of a +define-local-member-name declaration generates a distinct +hidden name (except as a top-level definition). The +interface->method-names procedure does not expose hidden +names.

Examples:
(define-values (r o)
  (let ()
    (define-local-member-name m)
    (define c% (class object%
                 (define/public (m) 10)
                 (super-new)))
    (define o (new c%))
 
    (values (send o m)
            o)))

 

> r

10

> (send o m)

send: no such method

  method name: m

  class name: c%

syntax

(define-member-name id key-expr)

Maps a single external name to an external name that is determined by +an expression. The value of key-expr must be the result of either a +member-name-key expression or a generate-member-key call.

syntax

(member-name-key identifier)

Produces a representation of the external name for id in the +environment of the member-name-key expression.

Produces a hidden name, just like the binding for +define-local-member-name.

procedure

(member-name-key? v)  boolean?

  v : any/c
Returns #t for values produced by member-name-key +and generate-member-key, #f +otherwise.

procedure

(member-name-key=? a-key b-key)  boolean?

  a-key : member-name-key?
  b-key : member-name-key?
Produces #t if member-name keys a-key and +b-key represent the same external name, #f +otherwise.

procedure

(member-name-key-hash-code a-key)  integer?

  a-key : member-name-key?
Produces an integer hash code consistent with +member-name-key=? comparisons, analogous to +equal-hash-code.

Examples:
(define (make-c% key)
  (define-member-name m key)
  (class object%
    (define/public (m) 10)
    (super-new)))

 

> (send (new (make-c% (member-name-key m))) m)

10

> (send (new (make-c% (member-name-key p))) m)

send: no such method

  method name: m

  class name: make-c%

> (send (new (make-c% (member-name-key p))) p)

10

 

(define (fresh-c%)
  (let ([key (generate-member-key)])
    (values (make-c% key) key)))
 
(define-values (fc% key) (fresh-c%))

 

> (send (new fc%) m)

send: no such method

  method name: m

  class name: make-c%

> (let ()
    (define-member-name p key)
    (send (new fc%) p))

10

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/createinterface.html b/clones/docs.racket-lang.org/reference/createinterface.html new file mode 100644 index 00000000..2b0f3ee8 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/createinterface.html @@ -0,0 +1,30 @@ + +6.1 Creating Interfaces

6.1 Creating Interfaces

+Classes and Objects in The Racket Guide introduces classes, objects, and interfaces.

syntax

(interface (super-interface-expr ...) name-clause ...)

 
name-clause = id
  | (id contract-expr)
Produces an interface. The ids must be mutually distinct.

Each super-interface-expr is evaluated (in order) when the +interface expression is evaluated. The result of each +super-interface-expr must be an interface value, otherwise +the exn:fail:object exception is raised. The interfaces returned by the +super-interface-exprs are the new interface’s +superinterfaces, which are all extended by the new interface. Any +class that implements the new interface also implements all of the +superinterfaces.

The result of an interface expression is an interface that +includes all of the specified ids, plus all identifiers from +the superinterfaces. Duplicate identifier names among the +superinterfaces are ignored, but if a superinterface contains one of +the ids in the interface expression, the +exn:fail:object exception is raised. A given id may be paired with +a corresponding contract-expr.

If no super-interface-exprs are provided, then the derivation +requirement of the resulting interface is trivial: any class that +implements the interface must be derived from object%. +Otherwise, the implementation requirement of the resulting interface +is the most specific requirement from its superinterfaces. If the +superinterfaces specify inconsistent derivation requirements, the +exn:fail:object exception is raised.

Examples:
(define file-interface<%>
  (interface () open close read-byte write-byte))
(define directory-interface<%>
  (interface (file-interface<%>)
    [file-list (->m (listof (is-a?/c file-interface<%>)))]
    parent-directory))

syntax

(interface* (super-interface-expr ...)
            ([property-expr val-expr] ...)
  name-clause ...)
 
name-clause = id
  | (id contract-expr)
Like interface, but also associates to the interface the +structure-type properties produced by the property-exprs with +the corresponding val-exprs.

Whenever the resulting interface (or a sub-interface derived from it) +is explicitly implemented by a class through the class* form, +each property is attached with its value to a structure type that +instantiated by instances of the class. Specifically, the property is +attached to a structure type with zero immediate fields, which is +extended to produce the internal structure type for instances of the +class (so that no information about fields is accessible to the +structure type property’s guard, if any).

Example:
(define i<%> (interface* () ([prop:custom-write
                              (lambda (obj port mode) (void))])
               method1 method2 method3))

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/creatingmorestructs.html b/clones/docs.racket-lang.org/reference/creatingmorestructs.html new file mode 100644 index 00000000..08618347 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/creatingmorestructs.html @@ -0,0 +1,88 @@ + +5.2 Creating Structure Types

5.2 Creating Structure Types

procedure

(make-struct-type name 
  super-type 
  init-field-cnt 
  auto-field-cnt 
  [auto-v 
  props 
  inspector 
  proc-spec 
  immutables 
  guard 
  constructor-name]) 
  
struct-type?
struct-constructor-procedure?
struct-predicate-procedure?
struct-accessor-procedure?
struct-mutator-procedure?
  name : symbol?
  super-type : (or/c struct-type? #f)
  init-field-cnt : exact-nonnegative-integer?
  auto-field-cnt : exact-nonnegative-integer?
  auto-v : any/c = #f
  props : 
(listof (cons/c struct-type-property?
                any/c))
 = null
  inspector : (or/c inspector? #f 'prefab) = (current-inspector)
  proc-spec : 
(or/c procedure?
      exact-nonnegative-integer?
      #f)
 = #f
  immutables : (listof exact-nonnegative-integer?) = null
  guard : (or/c procedure? #f) = #f
  constructor-name : (or/c symbol? #f) = #f
Creates a new structure type, unless inspector is +'prefab, in which case make-struct-type accesses a +prefab structure type. The name argument is used +as the type name. If super-type is not #f, the +resulting type is a subtype of the corresponding structure type.

The resulting structure type has +init-field-cnt+auto-field-cnt fields (in +addition to any fields from super-type), but only +init-field-cnt constructor arguments (in addition to any +constructor arguments from super-type). The remaining fields +are initialized with auto-v. The total field count (including +super-type fields) must be no more than 32768.

The props argument is a list of pairs, where the car +of each pair is a structure type property descriptor, and the +cdr is an arbitrary value. A property can be specified +multiple times in props (including properties that are +automatically added by properties that are directly included in +props) only if the associated values are eq?, +otherwise the exn:fail:contract exception is raised. See Structure Type Properties +for more information about properties. When inspector is +'prefab, then props must be null.

The inspector argument normally controls access to reflective +information about the structure type and its instances; see +Structure Inspectors for more information. If inspector is +'prefab, then the resulting prefab structure type and +its instances are always transparent. If inspector is +#f, then the structure type’s instances are transparent.

If proc-spec is an integer or procedure, instances of the +structure type act as procedures. See prop:procedure for +further information. Providing a non-#f value for +proc-spec is the same as pairing the value with +prop:procedure at the end of props, plus including +proc-spec in immutables when proc-spec is +an integer.

The immutables argument provides a list of field +positions. Each element in the list must be unique, otherwise +exn:fail:contract exception is raised. Each element must also fall in the range +0 (inclusive) to init-field-cnt (exclusive), otherwise +exn:fail:contract exception is raised.

The guard argument is either a procedure of n+1 +arguments or #f, where n is the number of arguments +for the new structure type’s constructor (i.e., +init-field-cnt plus constructor arguments implied by +super-type, if any). If guard is a procedure, then +the procedure is called whenever an instance of the type is +constructed, or whenever an instance of a subtype is created. The +arguments to guard are the values provided for the +structure’s first n fields, followed by the name of the +instantiated structure type (which is name, unless a subtype +is instantiated). The guard result must be n values, +which become the actual values for the structure’s fields. The +guard can raise an exception to prevent creation of a +structure with the given field values. If a structure subtype has its +own guard, the subtype guard is applied first, and the first n +values produced by the subtype’s guard procedure become the first +n arguments to guard. When inspector is +'prefab, then guard must be #f.

If constructor-name is not #f, it is used as the +name of the generated constructor procedure as returned by +object-name or in the printed form of the constructor value.

The result of make-struct-type is five values:

  • a structure type descriptor,

  • a constructor procedure,

  • a predicate procedure,

  • an accessor procedure, which consumes a structure and a field +index between 0 (inclusive) and +init-field-cnt+auto-field-cnt (exclusive), +and

  • a mutator procedure, which consumes a structure, a field +index, and a field value.

Examples:
(define-values (struct:a make-a a? a-ref a-set!)
  (make-struct-type 'a #f 2 1 'uninitialized))
(define an-a (make-a 'x 'y))

 

> (a-ref an-a 1)

'y

> (a-ref an-a 2)

'uninitialized

> (define a-first (make-struct-field-accessor a-ref 0))
> (a-first an-a)

'x

 

(define-values (struct:b make-b b? b-ref b-set!)
  (make-struct-type 'b struct:a 1 2 'b-uninitialized))
(define a-b (make-b 'x 'y 'z))

 

> (a-ref a-b 1)

'y

> (a-ref a-b 2)

'uninitialized

> (b-ref a-b 0)

'z

> (b-ref a-b 1)

'b-uninitialized

> (b-ref a-b 2)

'b-uninitialized

 

(define-values (struct:c make-c c? c-ref c-set!)
  (make-struct-type
   'c struct:b 0 0 #f null (make-inspector) #f null
   ; guard checks for a number, and makes it inexact
   (lambda (a1 a2 b1 name)
     (unless (number? a2)
       (error (string->symbol (format "make-~a" name))
              "second field must be a number"))
     (values a1 (exact->inexact a2) b1))))

 

> (make-c 'x 'y 'z)

make-c: second field must be a number

> (define a-c (make-c 'x 2 'z))
> (a-ref a-c 1)

2.0

 

(define p1 #s(p a b c))
(define-values (struct:p make-p p? p-ref p-set!)
  (make-struct-type 'p #f 3 0 #f null 'prefab #f '(0 1 2)))

 

> (p? p1)

#t

> (p-ref p1 0)

'a

> (make-p 'x 'y 'z)

'#s(p x y z)

procedure

(make-struct-field-accessor accessor-proc    
  field-pos    
  [field/proc-name    
  arg-contract-str    
  realm])  procedure?
  accessor-proc : struct-accessor-procedure?
  field-pos : exact-nonnegative-integer?
  field/proc-name : (or/c symbol? #f)
   = (symbol->string (format "field~a" field-pos))
  arg-contract-str : (or/c string? symbol? #f) = #f
  realm : symbol? = 'racket
Returns a field accessor that is equivalent to (lambda (s) (accessor-proc s field-pos)). The accessor-proc must be +an accessor returned by make-struct-type.

The field/proc-name argument determines the name of the +resulting procedure for error reporting and debugging purposes. If +field/proc-name is a symbol and arg-contract-str is not +#f, then field/proc-name is used as the procedure +name. If field/proc-name is a symbol and +arg-contract-str is #f, then field/proc-name is +combined with the name of accessor-proc’s structure type to +form the procedure name. If field/proc-name is #f, +then 'accessor is used as the procedure name.

The arg-contract-str argument determines how the accessor +procedure reports an error when it is applied to a value that is not +an instance of the accessor-proc’s structure type. If it is a +string or symbol, the text of the string or symbol is used as a +contract for error reporting. Otherwise, contract text is synthesized +from the name of accessor-proc’s structure type.

The realm argument is also used for error reporting. It +specifies a realm that an error-message adjuster may use to +determine how to adjust an error message. The realm argument +also determines the result of procedure-realm for the +accessor procedure.

For examples, see make-struct-type.

Changed in version 8.4.0.2 of package base: Added the arg-contract-str + and realm arguments.

procedure

(make-struct-field-mutator mutator-proc    
  field-pos    
  [field/proc-name    
  arg-contract-str    
  realm])  procedure?
  mutator-proc : struct-mutator-procedure?
  field-pos : exact-nonnegative-integer?
  field/proc-name : (or/c symbol? #f)
   = (symbol->string (format "field~a" field-pos))
  arg-contract-str : (or/c string? symbol? #f) = #f
  realm : symbol? = 'racket
Returns a field mutator that is equivalent to (lambda (s v) (mutator-proc s field-pos v)). The mutator-proc must be +a mutator returned by make-struct-type.

The field-name, arg-contract-str, and realm +arguments are used for error and debugging purposes analogous to the +same arguments to make-struct-field-accessor.

For examples, see make-struct-type.

Changed in version 8.4.0.2 of package base: Added the arg-contract-str + and realm arguments.

A structure type property that declares a structure type as +sealed. The value associated with the property is ignored; +the presence of the property itself makes the structure type +sealed.

A sealed structure type cannot be used as the supertype of +another structure type. Declaring a structure type as sealed is +typically just a performance hint, since checking for an instance of a +sealed structure type can be slightly faster than checking for an +instance of a structure type that might have subtypes.

Added in version 8.0.0.7 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/creatingunits.html b/clones/docs.racket-lang.org/reference/creatingunits.html new file mode 100644 index 00000000..37935c31 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/creatingunits.html @@ -0,0 +1,101 @@ + +7.1 Creating Units

7.1 Creating Units

syntax

(unit
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...)
  init-depends-decl
  unit-body-expr-or-defn
  ...)
 
tagged-sig-spec = sig-spec
  | (tag id sig-spec)
     
sig-spec = sig-id
  | (prefix id sig-spec)
  | (rename sig-spec (id id) ...)
  | (only sig-spec id ...)
  | (except sig-spec id ...)
     
init-depends-decl = 
  | (init-depend tagged-sig-id ...)
     
tagged-sig-id = sig-id
  | (tag id sig-id)
Produces a unit that encapsulates its +unit-body-expr-or-defns. Expressions in the unit +body can refer to identifiers bound by the sig-specs of the +import clause, and the body must include one definition for +each identifier of a sig-spec in the export clause. +An identifier that is exported cannot be set!ed in either the +defining unit or in importing units, although the implicit assignment +to initialize the variable may be visible as a mutation.

Each import or export sig-spec ultimately refers to a +sig-id, which is an identifier that is bound to a signature +by define-signature. The lexical information of each +identifier imported through a sig-id starts with the lexical +information of the sig-id; see define-signature form +more information.

In a specific import or export position, the set of identifiers bound +or required by a particular sig-id can be adjusted in a few +ways:

  • (prefix id sig-spec) as an import binds the same as +sig-spec, except that each binding is prefixed with id. +As an export, this form causes definitions using the id +prefix to satisfy the exports required by sig-spec.

  • (rename sig-spec (id id) ...) as an import binds the +same as sig-spec, except that the first id is used +for the binding instead of the second id (where +sig-spec by itself must imply a binding that is +bound-identifier=? to second id). As an export, +this form causes a definition for the first id to satisfy +the export named by the second id in sig-spec.

  • (only sig-spec id ...) as an import binds the same as +sig-spec, but restricted to just the listed ids +(where sig-spec by itself must imply a binding that is +bound-identifier=? to each id). This form is not +allowed for an export.

  • (except sig-spec id ...) as an import binds the same +as sig-spec, but excluding all listed ids (where +sig-spec by itself must imply a binding that is +bound-identifier=? to each id). This form is not +allowed for an export.

As suggested by the grammar, these adjustments to a signature can be +nested arbitrarily.

A unit’s declared imports are matched with actual supplied imports by +signature. That is, the order in which imports are supplied to a unit +when linking is irrelevant; all that matters is the signature +implemented by each supplied import. One actual import must be +provided for each declared import. Similarly, when a unit implements +multiple signatures, the order of the export signatures does not +matter.

To support multiple imports or exports for the same signature, an +import or export can be tagged using the form (tag id sig-spec). When an import declaration of a unit is +tagged, then one actual import must be given the same tag (with the +same signature) when the unit is linked. Similarly, when an export +declaration is tagged for a unit, then references to that particular +export must explicitly use the tag.

A unit is prohibited syntactically from importing two signatures that +are not distinct, unless they have different tags; two signatures are +distinct only if they share no ancestor through +extends. The same syntactic constraint applies to exported +signatures. In addition, a unit is prohibited syntactically from +importing the same identifier twice (after renaming and other +transformations on a sig-spec), exporting the same identifier +twice (again, after renaming), or exporting an identifier that is +imported.

When units are linked, the bodies of the linked units are +executed in an order that is specified at the linking site. An +optional (init-depend tagged-sig-id ...) +declaration constrains the allowed orders of linking by specifying +that the current unit must be initialized after the unit that supplies +the corresponding import. Each tagged-sig-id in an +init-depend declaration must have a corresponding import in the +import clause.

syntax

(define-signature sig-id extension-decl
  (sig-elem ...))
 
extension-decl = 
  | extends sig-id
     
sig-elem = id
  | (define-syntaxes (id ...) expr)
  | (define-values (id ...) expr)
  | (define-values-for-export (id ...) expr)
  | (contracted [id contract] ...)
  | (open sig-spec)
  | (struct id (field ...) struct-option ...)
  | (sig-form-id . datum)
     
field = id
  | [id #:mutable]
     
struct-option = #:mutable
  | #:constructor-name constructor-id
  | #:extra-constructor-name constructor-id
  | #:omit-constructor
  | #:omit-define-syntaxes
  | #:omit-define-values
Binds an identifier sig-id to a signature that specifies a group +of bindings for import or export:

  • Each id in a signature declaration means that a unit +implementing the signature must supply a variable definition for the +id. That is, id is available for use in units +importing the signature, and id must be defined by units +exporting the signature.

  • Each define-syntaxes form in a signature declaration +introduces a macro that is available for use in any unit that +imports the signature. Free variables in the definition’s +expr refer to other identifiers in the signature first, or +the context of the define-signature form if the signature +does not include the identifier.

  • Each define-values form in a signature declaration +introduces code that effectively prefixes every unit that imports the +signature. Free variables in the definition’s expr are +treated the same as for define-syntaxes.

  • Each define-values-for-export form in a signature +declaration introduces code that effectively suffixes every unit that +exports the signature. Free variables in the definition’s +expr are treated the same as for define-syntaxes.

  • Each contracted form in a signature declaration means +that a unit exporting the signature must supply a variable definition +for each id in that form. If the signature is imported, then +uses of id inside the unit are protected by the appropriate +contracts using the unit as the negative blame. If the signature is +exported, then the exported values are protected by the appropriate +contracts which use the unit as the positive blame, but internal uses +of the exported identifiers are not protected. Variables in the +contract expressions are treated the same as for +define-syntaxes.

  • Each (open sig-spec) adds to the signature everything +specified by sig-spec.

  • Each (struct id (field ...) struct-option ...) adds +all of the identifiers that would be bound by (struct id (field ...) field-option ...), where the extra option +#:omit-constructor omits the constructor identifier.

  • Each (sig-form-id . datum) extends the signature in a +way that is defined by sig-form-id, which must be bound by +define-signature-form. One such binding is for +struct/ctc.

When a define-signature form includes an extends +clause, then the define signature automatically includes everything in +the extended signature. Furthermore, any implementation of the new +signature can be used as an implementation of the extended signature.

The lexical information of each id within a signature is +compared to the lexical information of sig-id. The extra scopes +of id relative to sig-id are recorded for the +id. When the sig-id is used as a reference (e.g., in +the import clause of unit), a variant of id +is created for the referencing context by starting with the lexical +information of the referencing sig-id, and then adding the extra +scopes for id.

syntax

(open sig-spec)

Allowed only in a sig-elem; see define-signature.

syntax

(define-values-for-export (id ...) expr)

Allowed only in a sig-elem; see define-signature.

syntax

(contracted [id contract] ...)

Allowed only in a sig-elem; see define-signature.

syntax

(only sig-spec id ...)

Allowed only in a sig-spec; see unit.

syntax

(except sig-spec id ...)

Allowed only in a sig-spec; see unit.

syntax

(rename sig-spec (id id) ...)

Allowed only in a sig-spec; see unit.

syntax

(prefix id sig-spec)

Allowed only in a sig-spec; see unit.

syntax

(import tagged-sig-spec ...)

Allowed only in certain forms; see, for example, unit.

syntax

(export tagged-sig-spec ...)

Allowed only in certain forms; see, for example, unit.

syntax

(link linkage-decl ...)

Allowed only in certain forms; see, for example, compound-unit.

syntax

(tag id sig-spec)

(tag id sig-id)
Allowed only in certain forms; see, for example, unit.

syntax

(init-depend tagged-sig-id ...)

Allowed only in a init-depend-decl; see unit.

syntax

extends

Allowed only within define-signature.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/custodians.html b/clones/docs.racket-lang.org/reference/custodians.html new file mode 100644 index 00000000..93a56811 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/custodians.html @@ -0,0 +1,64 @@ + +14.7 Custodians

14.7 Custodians

See Custodians for basic information on the Racket +custodian model.

procedure

(custodian? v)  boolean?

  v : any/c
Returns #t if v is a custodian value, +#f otherwise.

procedure

(make-custodian [cust])  custodian?

  cust : (and/c custodian? (not/c custodian-shut-down?))
   = (current-custodian)
Creates a new custodian that is subordinate to cust. When +cust is directed (via custodian-shutdown-all) to +shut down all of its managed values, the new subordinate custodian is +automatically directed to shut down its managed values as well.

procedure

(custodian-shutdown-all cust)  void?

  cust : custodian?

In racket/gui/base, +eventspaces managed by cust are also +shut down.

Closes all file-stream ports, TCP ports, TCP +listeners, and UDP sockets that are managed by cust +(and its subordinates), and empties all custodian boxes +associated with cust (and its subordinates). It also removes +cust (and its subordinates) as managers of all threads; when +a thread has no managers, it is killed (or suspended; see +thread/suspend-to-kill) If the current thread is to be +killed, all other shut-down actions take place before killing the +thread.

If cust is already shut down, then +custodian-shutdown-all has no effect. When a custodian is +shut down and it has subordinate custodians, the subordinates are not +only shut down, they no longer count as subordinates.

procedure

(custodian-shut-down? cust)  boolean?

  cust : custodian?
Returns #t if cust has been shut down with +custodian-shutdown-all or if it was a subordinate of a +custodian that is shut down, #f otherwise.

Added in version 6.11.0.5 of package base.

parameter

(current-custodian)  custodian?

(current-custodian cust)  void?
  cust : custodian?

Custodians also manage eventspaces +from racket/gui/base.

A parameter that determines a custodian that assumes responsibility +for newly created threads, file-stream ports, TCP ports, +TCP listeners, UDP sockets, and byte converters.

procedure

(custodian-managed-list cust super)  list?

  cust : custodian?
  super : custodian?
Returns a list of immediately managed objects (not including +custodian boxes) and subordinate custodians for cust, +where cust is itself subordinate to super (directly +or indirectly). If cust is not strictly subordinate to +super, the exn:fail:contract exception is raised.

If cust has been shut down, the result is '(). If +cust was a subordinate of a custodian that was shut +down, then it cannot be a subordinate of super.

Memory accounting is normally available, but not in +the CGC implementation.

Returns #t if Racket is compiled with support for +per-custodian memory accounting, #f otherwise.

procedure

(custodian-require-memory limit-cust    
  need-amt    
  stop-cust)  void?
  limit-cust : custodian?
  need-amt : exact-nonnegative-integer?
  stop-cust : custodian?
Registers a required-memory check if Racket is compiled with +support for per-custodian memory accounting, otherwise the +exn:fail:unsupported exception is raised.

If a check is registered, and if Racket later reaches a state after +garbage collection (see Garbage Collection) where allocating +need-amt bytes charged to limit-cust would fail or +trigger some shutdown, then stop-cust is shut down.

The stop-cust must be a subordinate custodian of +limit-cust.

procedure

(custodian-limit-memory limit-cust    
  limit-amt    
  [stop-cust])  void?
  limit-cust : custodian?
  limit-amt : exact-nonnegative-integer?
  stop-cust : custodian? = limit-cust
Registers a limited-memory check if Racket is compiled with +support for per-custodian memory accounting, otherwise the +exn:fail:unsupported exception is raised.

If a check is registered, and if Racket later reaches a state +after garbage collection (see Garbage Collection) where +limit-cust owns more than limit-amt bytes, then +stop-cust is shut down.

A custodian’s limit is checked only after a garbage +collection, except that it may also be checked during +certain large allocations that are individually larger +than the custodian’s limit. A single garbage collection +may shut down multiple custodians, even if shutting down +only one of the custodians would have reduced memory use +for other custodians.

For reliable shutdown, limit-amt for +custodian-limit-memory must be much lower than the total +amount of memory available (minus the size of memory that is +potentially used and not charged to limit-cust). Moreover, if +individual allocations that are initially charged to +limit-cust can be arbitrarily large, then stop-cust +must be the same as limit-cust, so that excessively large +immediate allocations can be rejected with an +exn:fail:out-of-memory exception.

procedure

(make-custodian-box cust v)  custodian-box?

  cust : custodian?
  v : any/c
Returns a custodian box that contains v as long as +cust has not been shut down. If cust is already +shut down, the custodian box’s value is immediately removed.

A custodian box is a synchronizable event (see Events). +The custodian box becomes ready when its custodian is shut down; +the synchronization result of a custodian box is the custodian box itself.

procedure

(custodian-box? v)  boolean?

  v : any/c
Returns #t if v is a custodian box produced +by make-custodian-box, #f otherwise.

procedure

(custodian-box-value cb)  any

  cb : custodian-box?
Returns the value in the given custodian box, or #f if +the value has been removed.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/customport.html b/clones/docs.racket-lang.org/reference/customport.html new file mode 100644 index 00000000..5e54b44f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/customport.html @@ -0,0 +1,370 @@ + +13.1.9 Custom Ports
13.1.9 Custom Ports

The make-input-port and make-output-port procedures +create custom ports with arbitrary control procedures (much like +implementing a device driver). Custom ports are mainly useful to +obtain fine control over the action of committing bytes as read or +written.

procedure

(make-input-port name    
  read-in    
  peek    
  close    
  [get-progress-evt    
  commit    
  get-location    
  count-lines!    
  init-position    
  buffer-mode])  input-port?
  name : any/c
  read-in : 
(or/c
 (bytes?
  . -> . (or/c exact-nonnegative-integer?
               eof-object?
               procedure?
               evt?))
 input-port?)
  peek : 
(or/c
 (bytes? exact-nonnegative-integer? (or/c evt? #f)
         . -> . (or/c exact-nonnegative-integer?
                      eof-object?
                      procedure?
                      evt?
                      #f))
 input-port?
 #f)
  close : (-> any)
  get-progress-evt : (or/c (-> evt?) #f) = #f
  commit : 
(or/c (exact-positive-integer? evt? evt? . -> . any)
      #f)
   = #f
  get-location : 
(or/c
 (->
  (values (or/c exact-positive-integer? #f)
          (or/c exact-nonnegative-integer? #f)
          (or/c exact-positive-integer? #f)))
 #f)
   = #f
  count-lines! : (-> any) = void
  init-position : 
(or/c exact-positive-integer?
      port?
      #f
      (-> (or/c exact-positive-integer? #f)))
   = 1
  buffer-mode : 
(or/c (case-> ((or/c 'block 'none) . -> . any)
              (-> (or/c 'block 'none #f)))
      #f)
   = #f
Creates an input port, which is immediately open for reading. If +close procedure has no side effects, then the port need not +be explicitly closed. See also make-input-port/read-to-peek.

The arguments implement the port as follows:

  • name the name for the input port.

  • read-in either an input port, in which case reads + are redirected to the given port, or a procedure that takes a single + argument: + a mutable byte string to receive read bytes. The procedure’s + result is one of the following: +
    • the number of bytes read, as an exact, non-negative integer;

    • eof;

    • a procedure of arity four (representing a “special” +result, as discussed further below), +but a procedure result is allowed only +when peek is not #f;

    • a pipe input port that supplies bytes to be +used as long as the pipe has content (see +pipe-content-length) or until read-in or +peek is called again; or

    • a synchronizable event (see Events) other +than a pipe input port or procedure of arity four; the event +becomes ready when the read is complete (roughly): the event’s +value can be one of the above four results or another event like +itself; in the last case, a reading process loops with +sync until it gets a non-event result.

    The read-in procedure must not block indefinitely. If no + bytes are immediately available for reading, the read-in + must return 0 or an event, and preferably an event (to + avoid busy waits). The read-in should not return + 0 (or an event whose value is 0) when data is + available in the port, otherwise polling the port will behave + incorrectly. An event result from an event can also break polling.

    If the result of a read-in call is not one of the above + values, the exn:fail:contract exception is raised. If a returned integer is + larger than the supplied byte string’s length, the + exn:fail:contract exception is raised. If peek is #f and + a procedure for a special result is returned, + the exn:fail:contract exception is raised.

    The read-in procedure can report an error by raising an + exception, but only if no bytes are read. Similarly, no bytes + should be read if eof, an event, or a procedure is + returned. In other words, no bytes should be lost due to spurious + exceptions or non-byte data.

    A port’s reading procedure may be called in multiple threads + simultaneously (if the port is accessible in multiple threads), + and the port is responsible for its own internal + synchronization. Note that improper implementation of such + synchronization mechanisms might cause a non-blocking read + procedure to block indefinitely.

    If the result is a pipe input port, then previous + get-progress-evt calls whose event is not yet ready must + have been the pipe input port itself. Furthermore, + get-progress-evt must continue to return the pipe as long + as it contains data, or until the read-in or + peek-in procedure is called again (instead of using the + pipe, for whatever reason). If read-in or + peek-in is called, any previously associated pipe (as + returned by a previous call) is disassociated from the + port and is not in use by any other thread as a result of the + previous association.

    If peek, get-progress-evt, and + commit are all provided and + non-#f, then the following is an acceptable implementation + of read-in:

    (lambda (bstr)
      (let* ([progress-evt (get-progress-evt)]
             [v (peek bstr 0 progress-evt)])
        (cond
         [(sync/timeout 0 progress-evt) 0] ; try again
         [(evt? v) (wrap-evt v (lambda (x) 0))] ; sync, try again
         [(and (number? v) (zero? v)) 0] ; try again
         [else
          (if (commit (if (number? v) v 1)
                          progress-evt
                          always-evt)
              v      ; got a result
              0)]))) ; try again

    An implementor may choose not to implement the peek, + get-progress-evt, and commit + procedures, however, and even an implementor who does supply + them may provide a different read-in + that uses a fast path for non-blocking reads.

    In an input port is provided for read-in, then an input port + must also be provided for peek.

  • peek either #f, an input port (in which +case peeks are redirected to the given port), or a procedure +that takes three arguments:

    • a mutable byte string to receive peeked bytes;

    • a non-negative number of bytes (or +specials) to skip before peeking; and

    • either #f or a progress event produced by +get-progress-evt.

    The results and conventions for peek are mostly the same + as for read-in. The main difference is in the handling of + the progress event, if it is not #f. If the given + progress event becomes ready, the peek must abort any + skip attempts and not peek any values. In particular, + peek must not peek any values if the progress event is + initially ready. If the port has been closed, the progress event + should be ready, in which case peek should complete + (instead of failing because the port is closed).

    Unlike read-in, peek should produce + #f (or an event whose value is #f) if no bytes + were peeked because the progress event became ready. Like + read-in, a 0 result indicates that another + attempt is likely to succeed, so 0 is inappropriate when + the progress event is ready. Also like read-in, + peek must not block indefinitely.

    The skip count provided to peek is a number of bytes (or + specials) that must remain present in the + port—in addition to the peek results—when the peek results are + reported. If the skip count requests reading data that is past an eof, + it should not, and instead produce eof (until the eof is + consumed).

    If a progress event is supplied, then the peek is + effectively canceled when another process reads data before the + given number can be skipped. If a progress event is not supplied + and data is read, then the peek must effectively restart with the + original skip count.

    The system does not check that multiple peeks return consistent + results, or that peeking and reading produce consistent results, + although they must.

    If peek is #f, then peeking for the port is + implemented automatically in terms of reads, but with several + limitations. First, the automatic implementation is not + thread-safe. Second, the automatic implementation cannot handle + special results (non-byte and non-eof), so + read-in cannot return a procedure for a + special when peek is + #f. Finally, the automatic peek implementation is + incompatible with progress events, so if peek is + #f, then get-progress-evt and commit must + be #f. See also make-input-port/read-to-peek, + which implements peeking in terms of read-in without + these constraints.

    In an input port is provided for peek, then an input port + must also be provided for read-in.

  • close a procedure of zero arguments that is +called to close the port. The port is not considered closed until +the closing procedure returns. The port’s procedures will never be +used again via the port after it is closed. However, the closing +procedure can be called simultaneously in multiple threads (if the +port is accessible in multiple threads), and it may be called +during a call to the other procedures in another thread; in the +latter case, any outstanding reads and peeks should be terminated +with an error.

  • get-progress-evt either #f (the +default), or a procedure that takes no arguments and returns an +event. The event must become ready only after data is next read +from the port or the port is closed. If the port is already closed, +the event must be ready. After the event becomes +ready, it must remain so. See the description of read-in +for information about the allowed results of this function when +read-in returns a pipe input port. See also +semaphore-peek-evt, which is sometimes useful for +implementing get-progress-evt.

    If get-progress-evt is #f, then +port-provides-progress-evts? applied to the port will +produce #f, and the port will not be a valid argument to +port-progress-evt.

    The result event will not be exposed directly by +port-progress-evt. Instead, it will be wrapped in an +event for which progress-evt? returns true.

  • commit either #f (the +default), or a procedure that takes three arguments:

    • an exact, positive integer kr;

    • a progress event produced by get-progress-evt;

    • an event, done, that is either a channel-put +event, channel, semaphore, semaphore-peek event, always +event, or never event.

    A commit corresponds to removing data from the stream + that was previously peeked, but only if no other process removed + data first. (The removed data does not need to be reported, + because it has been peeked already.) More precisely, assuming + that kp bytes, specials, and + mid-stream eofs have been previously peeked or skipped + at the start of the port’s stream, commit must satisfy + the following constraints:

    • It must return only when the commit is complete or when the +given progress event becomes ready.

    • It must commit only if kp is positive.

    • If it commits, then it must do so with either kr items +or kp items, whichever is smaller, and only if kp is +positive.

    • It must never choose done in a synchronization +after the given progress event is ready, or after done +has been synchronized once.

    • It must not treat any data as read from the port unless +done is chosen in a synchronization.

    • It must not block indefinitely if done is ready; +it must return soon after the read completes or soon after the +given progress event is ready, whichever is first.

    • It can report an error by raising an exception, but only if +no data has been committed. In other words, no data should be lost due to +an exception, including a break exception.

    • It must return a true value if data has been committed, +#f otherwise. When it returns a value, the given +progress event must be ready (perhaps because data has just been +committed).

    • It should return a byte string as a true result when line +counting is enabled and get-location is #f (so +that line counting is implemented the default way); the result +byte string represents the data that was committed for the +purposes of character and line counting. If any other true result +is returned when a byte string is expected, it is treated like a +byte string where each byte corresponds to a non-newline +character.

    • It must raise an exception if no data (including +eof) has been peeked from the beginning of the port’s +stream, or if it would have to block indefinitely to wait for the +given progress event to become ready.

    A call to commit is parameterize-breaked to +disable breaks.

  • get-location either #f (the +default), or a procedure that takes no arguments and returns three +values: the line number for the next item in the port’s stream (a +positive number or #f), the column number for the next +item in the port’s stream (a non-negative number or #f), +and the position for the next item in the port’s stream (a +positive number or #f). See also Counting Positions, Lines, and Columns.

    This procedure is called to implement port-next-location, +but only if line counting is enabled for the port via +port-count-lines! (in which case count-lines! is +called). The read and read-syntax procedures +assume that reading a non-whitespace character increments the +column and position by one.

  • count-lines! a procedure of no arguments +that is called if and when line counting is enabled for the port. +The default procedure is void.

  • init-position normally an exact, positive integer +that determines the position of the port’s first item, which is +used by file-position or when line counting is +not enabled for the port. The default is 1. If +init-position is #f, the port is treated as +having an unknown position. If init-position is a port, +then the given port’s position is always used for the new port’s +position. If init-position is a procedure, it is called +as needed to obtain the port’s position.

  • buffer-mode either #f (the default) or a +procedure that accepts zero or one arguments. If +buffer-mode is #f, then the resulting port does +not support a buffer-mode setting. Otherwise, the procedure is +called with one symbol argument ('block or +'none) to set the buffer mode, and it is called with zero +arguments to get the current buffer mode. In the latter case, the +result must be 'block, 'none, or #f +(unknown). See Port Buffers and Positions for more information on +buffer modes.

“Special” results: When + read-in or peek (or an event produced by one of + these) returns a procedure, the procedure is used to obtain a + non-byte result. (This non-byte result is not intended to + return a character or eof; in particular, read-char + raises an exception if it encounters a special-result procedure, even + if the procedure produces a byte.) A special-result procedure must + accept four arguments that represent a source location. The first + argument is #f when the special read is triggered by read + or read/recursive.

The special-value procedure can return an arbitrary value, and it + will be called zero or one times (not necessarily before further + reads or peeks from the port). See Reader-Extension Procedures for + more details on the procedure’s result.

If read-in or peek returns a special + procedure when called by any reading procedure other than + read, read-syntax, read-char-or-special, + peek-char-or-special, read-byte-or-special, or + peek-byte-or-special, then the exn:fail:contract exception is raised.

Examples:
; A port with no input...
; Easy: (open-input-bytes #"")
; Hard:
> (define /dev/null-in
    (make-input-port 'null
                     (lambda (s) eof)
                     (lambda (skip s progress-evt) eof)
                     void
                     (lambda () never-evt)
                     (lambda (k progress-evt done-evt)
                       (error "no successful peeks!"))))
> (read-char /dev/null-in)

#<eof>

> (peek-char /dev/null-in)

#<eof>

> (read-byte-or-special /dev/null-in)

#<eof>

> (peek-byte-or-special /dev/null-in 100)

#<eof>

; A port that produces a stream of 1s:
> (define infinite-ones
    (make-input-port
     'ones
     (lambda (s)
       (bytes-set! s 0 (char->integer #\1)) 1)
     #f
     void))
> (read-string 5 infinite-ones)

"11111"

; But we can't peek ahead arbitrarily far, because the
; automatic peek must record the skipped bytes, so
; we'd run out of memory.
; An infinite stream of 1s with a specific peek procedure:
> (define infinite-ones
    (let ([one! (lambda (s)
                  (bytes-set! s 0 (char->integer #\1)) 1)])
      (make-input-port
       'ones
       one!
       (lambda (s skip progress-evt) (one! s))
       void)))
> (read-string 5 infinite-ones)

"11111"

; Now we can peek ahead arbitrarily far:
> (peek-string 5 (expt 2 5000) infinite-ones)

"11111"

; The port doesn't supply procedures to implement progress events:
> (port-provides-progress-evts? infinite-ones)

#f

> (port-progress-evt infinite-ones)

port-progress-evt: port does not provide progress evts

  port: #<input-port:ones>

; Non-byte port results:
> (define infinite-voids
    (make-input-port
     'voids
     (lambda (s) (lambda args 'void))
     (lambda (skip s evt) (lambda args 'void))
     void))
> (read-char infinite-voids)

read-char: non-character in an unsupported context

  port: #<input-port:voids>

> (read-char-or-special infinite-voids)

'void

; This port produces 0, 1, 2, 0, 1, 2, etc., but it is not
; thread-safe, because multiple threads might read and change n.
> (define mod3-cycle/one-thread
    (let* ([n 2]
           [mod! (lambda (s delta)
                   (bytes-set! s 0 (+ 48 (modulo (+ n delta) 3)))
                   1)])
      (make-input-port
       'mod3-cycle/not-thread-safe
       (lambda (s)
         (set! n (modulo (add1 n) 3))
         (mod! s 0))
       (lambda (s skip evt)
         (mod! s skip))
       void)))
> (read-string 5 mod3-cycle/one-thread)

"01201"

> (peek-string 5 (expt 2 5000) mod3-cycle/one-thread)

"20120"

; Same thing, but thread-safe and kill-safe, and with progress
; events. Only the server thread touches the stateful part
; directly. (See the output port examples for a simpler thread-safe
; example, but this one is more general.)
> (define (make-mod3-cycle)
    (define read-req-ch (make-channel))
    (define peek-req-ch (make-channel))
    (define progress-req-ch (make-channel))
    (define commit-req-ch (make-channel))
    (define close-req-ch (make-channel))
    (define closed? #f)
    (define n 0)
    (define progress-sema #f)
    (define (mod! s delta)
      (bytes-set! s 0 (+ 48 (modulo (+ n delta) 3)))
      1)
    ; -
    ; The server has a list of outstanding commit requests,
    ;  and it also must service each port operation (read,
    ;  progress-evt, etc.)
    (define (serve commit-reqs response-evts)
      (apply
       sync
       (handle-evt read-req-ch
                   (handle-read commit-reqs response-evts))
       (handle-evt progress-req-ch
                   (handle-progress commit-reqs response-evts))
       (handle-evt commit-req-ch
                   (add-commit commit-reqs response-evts))
       (handle-evt close-req-ch
                   (handle-close commit-reqs response-evts))
       (append
        (map (make-handle-response commit-reqs response-evts)
             response-evts)
        (map (make-handle-commit commit-reqs response-evts)
             commit-reqs))))
    ; Read/peek request: fill in the string and commit
    (define ((handle-read commit-reqs response-evts) r)
      (let ([s (car r)]
            [skip (cadr r)]
            [ch (caddr r)]
            [nack (cadddr r)]
            [evt (car (cddddr r))]
            [peek? (cdr (cddddr r))])
        (let ([fail? (and evt
                          (sync/timeout 0 evt))])
          (unless (or closed? fail?)
            (mod! s skip)
            (unless peek?
              (commit! 1)))
          ; Add an event to respond:
          (serve commit-reqs
                 (cons (choice-evt
                        nack
                        (channel-put-evt ch (if closed?
                                                0
                                                (if fail? #f 1))))
                       response-evts)))))
    ; Progress request: send a peek evt for the current
    ;  progress-sema
    (define ((handle-progress commit-reqs response-evts) r)
      (let ([ch (car r)]
            [nack (cdr r)])
        (unless progress-sema
          (set! progress-sema (make-semaphore (if closed? 1 0))))
        ; Add an event to respond:
        (serve commit-reqs
               (cons (choice-evt
                      nack
                      (channel-put-evt
                       ch
                       (semaphore-peek-evt progress-sema)))
                     response-evts))))
    ; Commit request: add the request to the list
    (define ((add-commit commit-reqs response-evts) r)
      (serve (cons r commit-reqs) response-evts))
    ; Commit handling: watch out for progress, in which case
    ;  the response is a commit failure; otherwise, try
    ;  to sync for a commit. In either event, remove the
    ;  request from the list
    (define ((make-handle-commit commit-reqs response-evts) r)
      (let ([k (car r)]
            [progress-evt (cadr r)]
            [done-evt (caddr r)]
            [ch (cadddr r)]
            [nack (cddddr r)])
        ; Note: we don't check that k is <= the sum of
        ;  previous peeks, because the entire stream is actually
        ;  known, but we could send an exception in that case.
        (choice-evt
         (handle-evt progress-evt
                     (lambda (x)
                       (sync nack (channel-put-evt ch #f))
                       (serve (remq r commit-reqs) response-evts)))
         ; Only create an event to satisfy done-evt if progress-evt
         ;  isn't already ready.
         ; Afterward, if progress-evt becomes ready, then this
         ;  event-making function will be called again, because
         ;  the server controls all posts to progress-evt.
         (if (sync/timeout 0 progress-evt)
             never-evt
             (handle-evt done-evt
                         (lambda (v)
                           (commit! k)
                           (sync nack (channel-put-evt ch #t))
                           (serve (remq r commit-reqs)
                                  response-evts)))))))
    ; Response handling: as soon as the respondee listens,
    ;  remove the response
    (define ((make-handle-response commit-reqs response-evts) evt)
      (handle-evt evt
                  (lambda (x)
                    (serve commit-reqs
                           (remq evt response-evts)))))
    ; Close handling: post the progress sema, if any, and set
    ;   the closed? flag
    (define ((handle-close commit-reqs response-evts) r)
      (let ([ch (car r)]
            [nack (cdr r)])
        (set! closed? #t)
        (when progress-sema
          (semaphore-post progress-sema))
        (serve commit-reqs
               (cons (choice-evt nack
                                 (channel-put-evt ch (void)))
                     response-evts))))
    ; Helper for reads and post-peek commits:
    (define (commit! k)
      (when progress-sema
        (semaphore-post progress-sema)
        (set! progress-sema #f))
      (set! n (+ n k)))
    ; Start the server thread:
    (define server-thread (thread (lambda () (serve null null))))
    ; -
    ; Client-side helpers:
    (define (req-evt f)
      (nack-guard-evt
       (lambda (nack)
         ; Be sure that the server thread is running:
         (thread-resume server-thread (current-thread))
         ; Create a channel to hold the reply:
         (let ([ch (make-channel)])
           (f ch nack)
           ch))))
    (define (read-or-peek-evt s skip evt peek?)
      (req-evt (lambda (ch nack)
                 (channel-put read-req-ch
                              (list* s skip ch nack evt peek?)))))
    ; Make the port:
    (make-input-port 'mod3-cycle
                     ; Each handler for the port just sends
                     ;  a request to the server
                     (lambda (s) (read-or-peek-evt s 0 #f #f))
                     (lambda (s skip evt)
                       (read-or-peek-evt s skip evt #t))
                     (lambda () ; close
                       (sync (req-evt
                              (lambda (ch nack)
                                (channel-put progress-req-ch
                                             (list* ch nack))))))
                     (lambda () ; progress-evt
                       (sync (req-evt
                              (lambda (ch nack)
                                (channel-put progress-req-ch
                                             (list* ch nack))))))
                     (lambda (k progress-evt done-evt)  ; commit
                       (sync (req-evt
                              (lambda (ch nack)
                                (channel-put
                                 commit-req-ch
                                 (list* k progress-evt done-evt ch
                                        nack))))))))
> (define mod3-cycle (make-mod3-cycle))
> (let ([result1 #f]
        [result2 #f])
    (let ([t1 (thread
               (lambda ()
                 (set! result1 (read-string 5 mod3-cycle))))]
          [t2 (thread
               (lambda ()
                 (set! result2 (read-string 5 mod3-cycle))))])
      (thread-wait t1)
      (thread-wait t2)
      (string-append result1 "," result2)))

"11120,02020"

> (define s (make-bytes 1))
> (define progress-evt (port-progress-evt mod3-cycle))
> (peek-bytes-avail! s 0 progress-evt mod3-cycle)

1

> s

#"1"

> (port-commit-peeked 1 progress-evt (make-semaphore 1)
                      mod3-cycle)

#t

> (sync/timeout 0 progress-evt)

#<progress-evt>

> (peek-bytes-avail! s 0 progress-evt mod3-cycle)

0

> (port-commit-peeked 1 progress-evt (make-semaphore 1)
                      mod3-cycle)

#f

> (close-input-port mod3-cycle)

procedure

(make-output-port name    
  evt    
  write-out    
  close    
  [write-out-special    
  get-write-evt    
  get-write-special-evt    
  get-location    
  count-lines!    
  init-position    
  buffer-mode])  output-port?
  name : any/c
  evt : evt?
  write-out : 
(or/c
 (bytes? exact-nonnegative-integer?
         exact-nonnegative-integer?
         boolean?
         boolean?
         . -> .
         (or/c exact-nonnegative-integer?
               #f
               evt?))
 output-port?)
  close : (-> any)
  write-out-special : 
(or/c (any/c boolean? boolean?
             . -> .
             (or/c any/c
                   #f
                   evt?))
      output-port?
      #f)
 = #f
  get-write-evt : 
(or/c
 (bytes? exact-nonnegative-integer?
         exact-nonnegative-integer?
         . -> .
         evt?)
 #f)
 = #f
  get-write-special-evt : 
(or/c
 (any/c . -> . evt?)
 #f)
 = #f
  get-location : 
(or/c
 (->
  (values (or/c exact-positive-integer? #f)
          (or/c exact-nonnegative-integer? #f)
          (or/c exact-positive-integer? #f)))
 #f)
   = #f
  count-lines! : (-> any) = void
  init-position : 
(or/c exact-positive-integer?
      port?
      #f
      (-> (or/c exact-positive-integer? #f)))
   = 1
  buffer-mode : 
(or/c (case->
       ((or/c 'block 'line 'none) . -> . any)
       (-> (or/c 'block 'line 'none #f)))
      #f)
   = #f
Creates an output port, which is immediately open for +writing. If close procedure has no side effects, then +the port need not be explicitly closed. The port can buffer data +within its write-out and write-out-special +procedures.

  • name the name for the output port.

  • evt a synchronization event (see Events; +e.g., a semaphore or another port). The event is used in place of +the output port when the port is supplied to synchronization +procedures like sync. Thus, the event should be +unblocked when the port is ready for writing at least one byte +without blocking, or ready to make progress in flushing an +internal buffer without blocking. The event must not unblock +unless the port is ready for writing; otherwise, the guarantees of +sync will be broken for the output port. Use +always-evt if writes to the port always succeed without +blocking.

  • write-out either an output port, which indicates that + writes should be redirected to the given port, or a procedure + of five arguments:

    • an immutable byte string containing bytes to write;

    • a non-negative exact integer for a starting offset +(inclusive) into the byte string;

    • a non-negative exact integer for an ending offset +(exclusive) into the byte string;

    • a boolean; #f indicates that the port is allowed +to keep the written bytes in a buffer, and that it is +allowed to block indefinitely; #t indicates that the +write should not block, and that the port should attempt to flush +its buffer and completely write new bytes instead of +buffering them;

    • a boolean; #t indicates that if the port blocks +for a write, then it should enable breaks while blocking (e.g., +using sync/enable-break); this argument is always +#f if the fourth argument is #t.

    The procedure returns one of the following:

    • a non-negative exact integer representing the number of +bytes written or buffered;

    • #f if no bytes could be written, perhaps because +the internal buffer could not be completely flushed;

    • a pipe output port (when buffering is allowed +and not when flushing) for buffering bytes as long as the pipe is +not full and until write-out or +write-out-special is called; or

    • a synchronizable event (see Events) other than a +pipe output port that acts like the result of +write-bytes-avail-evt to complete the write.

    Since write-out can produce an event, an acceptable +implementation of write-out is to pass its first three +arguments to the port’s get-write-evt. Some port +implementors, however, may choose not to provide +get-write-evt (perhaps because writes cannot be +made atomic), or may implement write-out to +enable a fast path for non-blocking writes or to +enable buffering.

    From a user’s perspective, the difference between buffered and +completely written data is (1) buffered data can be lost in the +future due to a failed write, and (2) flush-output forces +all buffered data to be completely written. Under no circumstances +is buffering required.

    If the start and end indices are the same, then the fourth +argument to write-out will be #f, and the write +request is actually a flush request for the port’s buffer (if +any), and the result should be 0 for a successful flush +(or if there is no buffer).

    The result should never be 0 if the start and end indices +are different, otherwise the exn:fail:contract exception is raised. +Similarly, the exn:fail:contract exception is raised if write-out +returns a pipe output port when buffering is disallowed or when it +is called for flushing. If a returned integer is larger than the +supplied byte-string range, the exn:fail:contract exception is raised.

    The #f result should be avoided, unless the next write +attempt is likely to work. Otherwise, if data cannot be written, +return an event instead.

    An event returned by write-out can return #f or +another event like itself, in contrast to events produced by +write-bytes-avail-evt or get-write-evt. +A writing process loops with sync until it obtains a +non-event result.

    The write-out procedure is always called with breaks +disabled, independent of whether breaks were enabled when the write +was requested by a client of the port. If breaks were enabled for +a blocking operation, then the fifth argument to write-out +will be #t, which indicates that write-out should +re-enable breaks while blocking.

    If the writing procedure raises an exception, due to write +or commit operations, it must not have committed any bytes +(though it may have committed previously buffered bytes).

    A port’s writing procedure may be called in multiple threads +simultaneously (if the port is accessible in multiple +threads). The port is responsible for its own internal +synchronization. Note that improper implementation of such +synchronization mechanisms might cause a non-blocking write +procedure to block.

  • close a procedure of zero arguments that is +called to close the port. The port is not considered closed until +the closing procedure returns. The port’s procedures will never be +used again via the port after it is closed. However, the closing +procedure can be called simultaneously in multiple threads (if the +port is accessible in multiple threads), and it may be called +during a call to the other procedures in another thread; in the +latter case, any outstanding writes or flushes should be +terminated immediately with an error.

  • write-out-special either #f (the +default), an output port (which indicates that +special writes should be redirected to the given port), +or a procedure to handle write-special calls +for the port. If #f, then the port does not support +special output, and port-writes-special? will return +#f when applied to the port.

    If a procedure is supplied, it takes three arguments: the special +value to write, a boolean that is #f if the procedure can +buffer the special value and block indefinitely, and a boolean +that is #t if the procedure should enable breaks while +blocking. The result is one of the following:

    • a non-event true value, which indicates that the special is +written;

    • #f if the special could not be written, perhaps +because an internal buffer could not be completely flushed;

    • a synchronizable event (see Events) that acts like +the result of get-write-special-evt to complete the write.

    Since write-out-special can return an event, +passing the first argument to an implementation of +get-write-special-evt is acceptable as a +write-out-special.

    As for write-out, the #f result is discouraged, +since it can lead to busy waiting. Also as for write-out, +an event produced by write-out-special is allowed +to produce #f or another event like itself. The +write-out-special procedure is always called with +breaks disabled, independent of whether breaks were enabled when +the write was requested by a client of the port.

  • get-write-evt either #f (the +default) or a procedure of three arguments:

    • an immutable byte string containing bytes to write;

    • a non-negative exact integer for a starting offset +(inclusive) into the byte string; and

    • a non-negative exact integer for an ending offset +(exclusive) into the byte string.

    The result is a synchronizable event (see Events) to act as + the result of write-bytes-avail-evt for the port (i.e., + to complete a write or flush), which becomes available only as + data is committed to the port’s underlying device, and whose + result is the number of bytes written.

    If get-write-evt is #f, then + port-writes-atomic? will produce #f when applied + to the port, and the port will not be a valid argument to + procedures such as write-bytes-avail-evt. + Otherwise, an event returned by get-write-evt must + not cause data to be written to the port unless the event is + chosen in a synchronization, and it must write to the port if the + event is chosen (i.e., the write must appear atomic with respect + to the synchronization).

    If the event’s result integer is larger than the supplied + byte-string range, the exn:fail:contract exception is raised by a wrapper + on the event. If the start and end indices are the same (i.e., no + bytes are to be written), then the event should produce 0 + when the buffer is completely flushed. (If the port has no buffer, + then it is effectively always flushed.)

    If the event raises an exception, due to write or commit + operations, it must not have committed any new bytes (though it + may have committed previously buffered bytes).

    Naturally, a port’s events may be used in multiple threads + simultaneously (if the port is accessible in multiple + threads). The port is responsible for its own internal + synchronization.

  • get-write-special-evt either #f +(the default), or a procedure to handle write-special-evt +calls for the port. This argument must be #f if either +write-out-special or get-write-evt +is #f, and it must be a procedure if both of those +arguments are procedures.

    If it is a procedure, it takes one argument: the special value to +write. The resulting event (with its constraints) is analogous to +the result of get-write-evt.

    If the event raises an exception, due to write or commit +operations, it must not have committed the special value (though +it may have committed previously buffered bytes and values).

  • get-location either #f (the +default), or a procedure that takes no arguments and returns three +values: the line number for the next item written to the port’s +stream (a positive number or #f), the column number for +the next item written to port’s stream (a non-negative number or +#f), and the position for the next item written to port’s +stream (a positive number or #f). See also +Counting Positions, Lines, and Columns.

    This procedure is called to implement port-next-location +for the port, but only if line counting is enabled for the port +via port-count-lines! (in which case +count-lines! is called).

  • count-lines! a procedure of no arguments +that is called if and when line counting is enabled for the port. +The default procedure is void.

  • init-position normally an exact, positive integer +that determines the position of the port’s first item, which is +used by file-position or when line counting is +not enabled for the port. The default is 1. If +init-position is #f, the port is treated as +having an unknown position. If init-position is a port, +then the given port’s position is always used for the new port’s +position. If init-position is a procedure, it is called +as needed to obtain the port’s position.

  • buffer-mode either #f (the +default) or a procedure that accepts zero or one arguments. If +buffer-mode is #f, then the resulting +port does not support a buffer-mode setting. Otherwise, the +procedure is called with one symbol argument ('block, +'line, or 'none) to set the buffer mode, and it is +called with zero arguments to get the current buffer mode. In the +latter case, the result must be 'block, 'line, +'none, or #f (unknown). See Port Buffers and Positions +for more information on buffer modes.

Examples:
; A port that writes anything to nowhere:
> (define /dev/null-out
    (make-output-port
     'null
     always-evt
     (lambda (s start end non-block? breakable?) (- end start))
     void
     (lambda (special non-block? breakable?) #t)
     (lambda (s start end) (wrap-evt
                            always-evt
                            (lambda (x)
                              (- end start))))
     (lambda (special) always-evt)))
> (display "hello" /dev/null-out)
> (write-bytes-avail #"hello" /dev/null-out)

5

> (write-special 'hello /dev/null-out)

#t

> (sync (write-bytes-avail-evt #"hello" /dev/null-out))

5

; A port that accumulates bytes as characters in a list,
;  but not in a thread-safe way:
> (define accum-list null)
> (define accumulator/not-thread-safe
    (make-output-port
     'accum/not-thread-safe
     always-evt
     (lambda (s start end non-block? breakable?)
       (set! accum-list
             (append accum-list
                     (map integer->char
                          (bytes->list (subbytes s start end)))))
       (- end start))
     void))
> (display "hello" accumulator/not-thread-safe)
> accum-list

'(#\h #\e #\l #\l #\o)

; Same as before, but with simple thread-safety:
> (define accum-list null)
> (define accumulator
    (let* ([lock (make-semaphore 1)]
           [lock-peek-evt (semaphore-peek-evt lock)])
      (make-output-port
       'accum
       lock-peek-evt
       (lambda (s start end non-block? breakable?)
         (if (semaphore-try-wait? lock)
             (begin
               (set! accum-list
                     (append accum-list
                             (map integer->char
                                  (bytes->list
                                   (subbytes s start end)))))
               (semaphore-post lock)
               (- end start))
             ; Cheap strategy: block until the list is unlocked,
             ;   then return 0, so we get called again
             (wrap-evt
              lock-peek-evt
              (lambda (x) 0))))
       void)))
> (display "hello" accumulator)
> accum-list

'(#\h #\e #\l #\l #\o)

; A port that transforms data before sending it on
;  to another port. Atomic writes exploit the
;  underlying port's ability for atomic writes.
> (define (make-latin-1-capitalize port)
    (define (byte-upcase s start end)
      (list->bytes
       (map (lambda (b) (char->integer
                         (char-upcase
                          (integer->char b))))
            (bytes->list (subbytes s start end)))))
    (make-output-port
     'byte-upcase
     ; This port is ready when the original is ready:
     port
     ; Writing procedure:
     (lambda (s start end non-block? breakable?)
       (let ([s (byte-upcase s start end)])
         (if non-block?
             (write-bytes-avail* s port)
             (begin
               (display s port)
               (bytes-length s)))))
     ; Close procedure close original port:
     (lambda () (close-output-port port))
     #f
     ; Write event:
     (and (port-writes-atomic? port)
          (lambda (s start end)
            (write-bytes-avail-evt
             (byte-upcase s start end)
             port)))))
> (define orig-port (open-output-string))
> (define cap-port (make-latin-1-capitalize orig-port))
> (display "Hello" cap-port)
> (get-output-string orig-port)

"HELLO"

> (sync (write-bytes-avail-evt #"Bye" cap-port))

3

> (get-output-string orig-port)

"HELLOBYE"

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/data-structure-contracts.html b/clones/docs.racket-lang.org/reference/data-structure-contracts.html new file mode 100644 index 00000000..c4c784b2 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/data-structure-contracts.html @@ -0,0 +1,281 @@ + +8.1 Data-structure Contracts

8.1 Data-structure Contracts

procedure

(flat-contract-with-explanation get-explanation 
  [#:name name]) 
  flat-contract?
  get-explanation : (-> any/c (or/c boolean? (-> blame? any)))
  name : any/c = (object-name get-explanation)
Provides a way to use flat contracts that, when a contract fails, + provide more information about the failure.

If get-explanation returns a boolean, then that boolean value is + treated as the predicate in a flat contract. If it returns + a procedure, then it is treated similarly to returning #f, + except the result procedure is called to actually signal the contract + violation.

The name argument is used as the name of the contract; it defaults + to the name of the get-explanation function.

(flat-contract-with-explanation
 (λ (val)
   (cond
     [(even? val) #t]
     [else
      (λ (blame)
        (define more-information ...do-some-complex-computation-here...)
        (raise-blame-error blame val
                           '(expected: "an even number" given: "~e"
                                       "and, here is more help: ~s")
                           val more-information))])))

procedure

(flat-named-contract name    
  flat-contract    
  [generator])  flat-contract?
  name : any/c
  flat-contract : flat-contract?
  generator : (or/c #f (-> exact-nonnegative-integer? (-> any/c)))
   = #f
Produces a flat contract like flat-contract, but with the name name.

For example, +
(define/contract i
  (flat-named-contract
   'odd-integer
   (lambda (x) (and (integer? x) (odd? x))))
  2)

The generator argument adds a generator for the flat-named-contract. See +contract-random-generate for more information.

A flat contract that accepts any value.

When using this contract as the result portion of a function contract, +consider using any instead; using any leads to +better memory performance, but it also allows multiple results.

A flat contract that accepts no values.

procedure

(or/c contract ...)  contract?

  contract : contract?
Takes any number of contracts and returns +a contract that accepts any value that any one of the contracts +accepts individually.

The or/c result tests any value by applying the contracts in +order, from left to right, with the exception that it always moves the +non-flat contracts (if any) to the end, checking them +last. Thus, a contract such as (or/c (not/c real?) positive?) is guaranteed to only invoke the positive? +predicate on real numbers.

If all of the arguments are procedures or flat contracts, the +result is a flat contract. If only one of the arguments is a +higher-order contract, the result is a contract that just checks the +flat contracts and, if they don’t pass, applies the higher-order +contract.

If there are multiple higher-order contracts, or/c uses +contract-first-order-passes? to distinguish between +them. More precisely, when an or/c is checked, it first +checks all of the flat contracts. If none of them pass, it +calls contract-first-order-passes? with each of the +higher-order contracts. If only one returns true, or/c uses +that contract. If none of them return true, it signals a contract +violation. If more than one returns true, it also signals a contract +violation. +For example, this contract +
(or/c (-> number? number?)
      (-> string? string? string?))
does not accept a function like this one: (lambda args ...) +since it cannot tell which of the two arrow contracts should be used +with the function.

If all of its arguments are list-contract?s, then or/c +returns a list-contract?.

procedure

(first-or/c contract ...)  contract?

  contract : contract?
Takes any number of contracts and returns a contract that +accepts any value that any one of the contracts accepts +individually.

The first-or/c result tests any value by applying the +contracts in order from left to right. Thus, a contract +such as (first-or/c (not/c real?) positive?) +is guaranteed to only invoke the +positive? predicate on real numbers.

If all of the arguments are procedures or flat +contracts, the result is a flat contract and +similarly if all of the arguments are chaperone +contracts the result is too. Otherwise, the result is an +impersonator contract.

If there are multiple higher-order contracts, +first-or/c uses contract-first-order-passes? +to distinguish between them. More precisely, when an +first-or/c is checked, it checks the first order passes +of the first contract against the value. If it succeeds, +then it uses only that contract. If it fails, then it moves +to the second contract, continuing until it finds one of +the contracts where the first order check succeeds. If none +of them do, a contract violation is signaled.

For example, this contract +
accepts the function (λ args 0), +applying the (-> number? number?) contract to the function +because it comes first, even though +(-> string? string? string?) also applies.

If all of its arguments are list-contract?s, then first-or/c +returns a list-contract?.

procedure

(and/c contract ...)  contract?

  contract : contract?
Takes any number of contracts and returns a contract that +accepts any value that satisfies all of the contracts simultaneously.

If all of the arguments are procedures or flat contracts, +the result is a flat contract.

The contract produced by and/c tests any value by applying +the contracts in order, from left to right.

This means that and/c can be used to guard predicates that are not +total in contracts. For example, this contract is well-behaved, correctly +blaming the definition of whoops-not-a-number for not being +a number:

Example:
> (define/contract whoops-not-a-number
    (and/c real? even?)
    "four")

whoops-not-a-number: broke its own contract

  promised: real?

  produced: "four"

  in: an and/c case of

      (and/c real? even?)

  contract from:

      (definition whoops-not-a-number)

  blaming: (definition whoops-not-a-number)

   (assuming the contract is correct)

  at: eval:2:0

but if the arguments to and/c are reversed, then the contract itself raises + an error: +

Example:
> (define/contract whoops-not-a-number
    (and/c even? real?)
    "four")

even?: contract violation

  expected: integer?

  given: "four"

If more than one of the contracts are not flat contracts, + then the order in which the higher-order parts of the contract are tested + can be counter-intuitive. As an example, consider this function that + uses and/c in a higher-order manner with contracts that + always succeed, but that print when they are called, in order for us + to see the order in which they are called.

Examples:
> (define ((show-me n) x)
    (printf "show-me ~a\n" n)
    #t)
> (define/contract identity-with-complex-printing-contract
    (and/c (-> (show-me 4) (show-me 5))
           (-> (show-me 3) (show-me 6))
           (-> (show-me 2) (show-me 7))
           (-> (show-me 1) (show-me 8)))
    (λ (x) x))
> (identity-with-complex-printing-contract 101)

show-me 1

show-me 2

show-me 3

show-me 4

show-me 5

show-me 6

show-me 7

show-me 8

101

The checking order is just like the usual ordering when a contract + is double-wrapped. The contract that is first put on has its domain checked + second but its range checked first and we see a similar pattern here in + this example, because and/c simply applies the contracts in order.

procedure

(not/c flat-contract)  flat-contract?

  flat-contract : flat-contract?
Accepts a flat contract or a predicate and returns a flat contract +that checks the inverse of the argument.

procedure

(=/c z)  flat-contract?

  z : real?
Returns a flat contract that requires the input to be a number and += to z.

procedure

(</c n)  flat-contract?

  n : real?
Returns a flat contract that requires the input to be a number and +< than n.

procedure

(>/c n)  flat-contract?

  n : real?
Like </c, but for >.

procedure

(<=/c n)  flat-contract?

  n : real?
Like </c, but for <=.

procedure

(>=/c n)  flat-contract?

  n : real?
Like </c, but for >=.

procedure

(between/c n m)  flat-contract?

  n : real?
  m : real?
Returns a flat contract that requires the +input to be a real number between n and m or equal to +one of them.

procedure

(real-in n m)  flat-contract?

  n : real?
  m : real?
An alias for between/c.

procedure

(integer-in j k)  flat-contract?

  j : (or/c exact-integer? #f)
  k : (or/c exact-integer? #f)
Returns a flat contract that requires the input to be an exact integer +between j and k, inclusive. If either j or k +is #f, then the range is unbounded on that end.

Examples:
> (define/contract two-digit-number
    (integer-in 10 99)
    23)
> (define/contract not-a-two-digit-number
    (integer-in 10 99)
    124)

not-a-two-digit-number: broke its own contract

  promised: (integer-in 10 99)

  produced: 124

  in: (integer-in 10 99)

  contract from:

      (definition not-a-two-digit-number)

  blaming: (definition not-a-two-digit-number)

   (assuming the contract is correct)

  at: eval:3:0

> (define/contract negative-number
    (integer-in #f -1)
    -4)
> (define/contract not-a-negative-number
    (integer-in #f -1)
    4)

not-a-negative-number: broke its own contract

  promised: (integer-in #f -1)

  produced: 4

  in: (integer-in #f -1)

  contract from:

      (definition not-a-negative-number)

  blaming: (definition not-a-negative-number)

   (assuming the contract is correct)

  at: eval:5:0

Changed in version 6.8.0.2 of package base: Allow j and k to be #f

procedure

(char-in a b)  flat-contract?

  a : char?
  b : char?
Returns a flat contract that requires the input to be a character whose +code point number is between the code point numbers of a and +b, inclusive.

A flat contract that requires the input to be an exact non-negative integer.

procedure

(string-len/c len)  flat-contract?

  len : real?
Returns a flat contract that recognizes strings that have fewer than +len characters.

An alias for #f for backwards compatibility.

A flat contract that recognizes values that can be written out and +read back in with write and read.

procedure

(one-of/c v ...+)  flat-contract?

  v : any/c
Accepts any number of atomic values and returns a flat contract that +recognizes those values, using eqv? as the comparison +predicate. For the purposes of one-of/c, atomic values are +defined to be: characters, symbols, booleans, +null, keywords, numbers, +#<void>, and #<undefined>.

This is a backwards compatibility contract constructor. If +neither #<void> nor #<undefined> are arguments, +it simply passes its arguments to or/c.

procedure

(symbols sym ...+)  flat-contract?

  sym : symbol?
Accepts any number of symbols and returns a flat contract that +recognizes those symbols.

This is a backwards compatibility constructor; it merely +passes its arguments to or/c.

procedure

(vectorof c    
  [#:immutable immutable    
  #:flat? flat?    
  #:eager eager])  contract?
  c : contract?
  immutable : (or/c #t #f 'dont-care) = 'dont-care
  flat? : boolean? = #f
  eager : (or/c #t #f exact-nonnegative-integer?) = #t
Returns a contract that recognizes vectors. The elements of the vector must +match c.

If the flat? argument is #t, then the resulting contract is +a flat contract, and the c argument must also be a flat contract. Such +flat contracts will be unsound if applied to mutable vectors, as they will not +check future operations on the vector.

If the immutable argument is #t and the c argument is +a flat contract and the eager argument is #t, +the result will be a flat contract. If the c argument +is a chaperone contract, then the result will be a chaperone contract.

If the eager argument is #t, then immutable vectors are +checked eagerly when c is a flat contract. If the +eager argument is a number n, then immutable vectors are checked +eagerly when c is a flat contract and the length of the vector +is less than or equal to n.

When a higher-order vectorof contract is applied to a vector, the result +is not eq? to the input. The result will be a copy for immutable vectors +and a chaperone or impersonator of the input for mutable vectors, +unless the c argument is a flat contract and the vector is immutable, +in which case the result is the original vector.

Changed in version 6.3.0.5 of package base: Changed flat vector contracts to not copy +immutable vectors.
Changed in version 6.7.0.3: Added the #:eager option.

procedure

(vector-immutableof c)  contract?

  c : contract?
Returns the same contract as (vectorof c #:immutable #t). This form exists for +backwards compatibility.

procedure

(vector/c c    
  ...    
  [#:immutable immutable    
  #:flat? flat?])  contract?
  c : contract?
  immutable : (or/c #t #f 'dont-care) = 'dont-care
  flat? : boolean? = #f
Returns a contract that recognizes vectors whose lengths match the number of +contracts given. Each element of the vector must match its corresponding contract.

If the flat? argument is #t, then the resulting contract is +a flat contract, and the c arguments must also be flat contracts. Such +flat contracts will be unsound if applied to mutable vectors, as they will not +check future operations on the vector.

If the immutable argument is #t and the c arguments are +flat contracts, the result will be a flat contract. If the c arguments +are chaperone contracts, then the result will be a chaperone contract.

When a higher-order vector/c contract is applied to a vector, the result +is not eq? to the input. The result will be a copy for immutable vectors +and a chaperone or impersonator of the input for mutable vectors.

procedure

(vector-immutable/c c ...)  contract?

  c : contract?
Returns the same contract as (vector/c c ... #:immutable #t). This form exists for +reasons of backwards compatibility.

procedure

(box/c in-c    
  [c    
  #:immutable immutable    
  #:flat? flat?])  contract?
  in-c : contract?
  c : contract? = in-c
  immutable : (or/c #t #f 'dont-care) = 'dont-care
  flat? : boolean? = #f
Returns a contract that recognizes boxes. The content of the box must match c, +and mutations on mutable boxes must match in-c.

If the flat? argument is #t, then the resulting contract is +a flat contract, and the out argument must also be a flat contract. Such +flat contracts will be unsound if applied to mutable boxes, as they will not check +future operations on the box.

If the immutable argument is #t and the c argument is +a flat contract, the result will be a flat contract. If the c argument is +a chaperone contract, then the result will be a chaperone contract.

When a higher-order box/c contract is applied to a box, the result +is not eq? to the input. The result will be a copy for immutable boxes +and either a chaperone or impersonator of the input for mutable boxes.

procedure

(box-immutable/c c)  contract?

  c : contract?
Returns the same contract as (box/c c #:immutable #t). This form exists for +reasons of backwards compatibility.

procedure

(listof c)  list-contract?

  c : contract?
Returns a contract that recognizes a list whose every element matches +the contract c. Beware that when this contract is applied to +a value, the result is not necessarily eq? to the input.

Examples:
> (define/contract some-numbers
    (listof number?)
    (list 1 2 3))
> (define/contract just-one-number
    (listof number?)
    11)

just-one-number: broke its own contract

  promised: list?

  produced: 11

  in: (listof number?)

  contract from: (definition just-one-number)

  blaming: (definition just-one-number)

   (assuming the contract is correct)

  at: eval:3:0

procedure

(non-empty-listof c)  list-contract?

  c : contract?
Returns a contract that recognizes non-empty lists whose elements match +the contract c. Beware that when this contract is applied to +a value, the result is not necessarily eq? to the input.

Examples:
> (define/contract some-numbers
    (non-empty-listof number?)
    (list 1 2 3))
> (define/contract not-enough-numbers
    (non-empty-listof number?)
    (list))

not-enough-numbers: broke its own contract

  promised: (and/c list? pair?)

  produced: '()

  in: (non-empty-listof number?)

  contract from:

      (definition not-enough-numbers)

  blaming: (definition not-enough-numbers)

   (assuming the contract is correct)

  at: eval:3:0

procedure

(list*of ele-c [last-c])  contract?

  ele-c : contract?
  last-c : contract? = ele-c
Returns a contract that recognizes improper lists whose elements match +the contract ele-c and whose last position matches last-c. +If an improper list is created with cons, +then its car position is expected to match ele-c and +its cdr position is expected to be (list*of ele-c list-c). Otherwise, +it is expected to match last-c. Beware that when this contract is applied to +a value, the result is not necessarily eq? to the input.

Examples:
> (define/contract improper-numbers
    (list*of number?)
    (cons 1 (cons 2 3)))
> (define/contract not-improper-numbers
    (list*of number?)
    (list 1 2 3))

not-improper-numbers: broke its own contract

  promised: number?

  produced: '()

  in: an element of

      (list*of number?)

  contract from:

      (definition not-improper-numbers)

  blaming: (definition not-improper-numbers)

   (assuming the contract is correct)

  at: eval:3:0

Added in version 6.1.1.1 of package base.
Changed in version 6.4.0.4: Added the last-c argument.

procedure

(cons/c car-c cdr-c)  contract?

  car-c : contract?
  cdr-c : contract?
Produces a contract that recognizes pairs whose first and second elements +match car-c and cdr-c, respectively. Beware that +when this contract is applied to a value, the result is not +necessarily eq? to the input.

If the cdr-c contract is a list-contract?, then +cons/c returns a list-contract?.

Examples:
> (define/contract a-pair-of-numbers
    (cons/c number? number?)
    (cons 1 2))
> (define/contract not-a-pair-of-numbers
    (cons/c number? number?)
    (cons #f #t))

not-a-pair-of-numbers: broke its own contract

  promised: number?

  produced: #f

  in: the car of

      (cons/c number? number?)

  contract from:

      (definition not-a-pair-of-numbers)

  blaming: (definition not-a-pair-of-numbers)

   (assuming the contract is correct)

  at: eval:3:0

Changed in version 6.0.1.13 of package base: Added the list-contract? propagating behavior.

syntax

(cons/dc [car-id contract-expr] [cdr-id (car-id) contract-expr] cons/dc-option)

(cons/dc [car-id (cdr-id) contract-expr] [cdr-id contract-expr] cons/dc-option)
 
cons/dc-option = 
  | #:flat
  | #:chaperone
  | #:impersonator
Produces a contract that recognizes pairs whose first and second elements +match the expressions after car-id and cdr-id, respectively.

In the first case, the contract on the cdr-id portion of the contract +may depend on the value in the car-id portion of the pair and in +the second case, the reverse is true.

Examples:
> (define/contract an-ordered-pair-of-reals
    (cons/dc [hd real?] [tl (hd) (>=/c hd)])
    (cons 1 2))
> (define/contract not-an-ordered-pair-of-reals
    (cons/dc [hd real?] [tl (hd) (>=/c hd)])
    (cons 2 1))

not-an-ordered-pair-of-reals: broke its own contract

  promised: (>=/c 2)

  produced: 1

  in: the cdr of

      (cons/dc (hd real?) (tl (hd) (>=/c hd)))

  contract from:

      (definition not-an-ordered-pair-of-reals)

  blaming: (definition not-an-ordered-pair-of-reals)

   (assuming the contract is correct)

  at: eval:3:0

Added in version 6.1.1.6 of package base.

procedure

(list/c c ...)  list-contract?

  c : contract?
Produces a contract for a list. The number of elements in the list +must match the number of arguments supplied to list/c, and +each element of the list must match the corresponding contract. Beware +that when this contract is applied to a value, the result is not +necessarily eq? to the input.

procedure

(*list/c prefix suffix ...)  list-contract?

  prefix : contract?
  suffix : contract?
Produces a contract for a list. The number of elements in the list +must be at least as long as the number of suffix contracts +and the tail of the list must match those contracts, one for each +element. The beginning portion of the list can be arbitrarily long, +and each element must match prefix.

Beware that when this contract is applied to a value, the result is not +necessarily eq? to the input.

Examples:
> (define/contract a-list-of-numbers-ending-with-two-integers
    (*list/c number? integer? integer?)
    (list 1/2 4/5 0+1i -11 322))
> (define/contract not-enough-integers-at-the-end
    (*list/c number? integer? integer? integer?)
    (list 1/2 4/5 1/2 321 322))

not-enough-integers-at-the-end: broke its own contract

  promised: integer?

  produced: 1/2

  in: the 3rd to the last element of

      (*list/c number? integer? integer? integer?)

  contract from:

      (definition not-enough-integers-at-the-end)

  blaming: (definition not-enough-integers-at-the-end)

   (assuming the contract is correct)

  at: eval:3:0

procedure

(syntax/c c)  flat-contract?

  c : flat-contract?
Produces a flat contract that recognizes syntax objects whose +syntax-e content matches c.

syntax

(struct/c struct-id contract-expr ...)

Produces a contract that recognizes instances of the structure +type named by struct-id, and whose field values match the +contracts produced by the contract-exprs.

Contracts for immutable fields must be either flat or chaperone contracts. +Contracts for mutable fields may be impersonator contracts. +If all fields are immutable and the contract-exprs evaluate +to flat contracts, a flat contract is produced. If all the +contract-exprs are chaperone contracts, a chaperone contract is +produced. Otherwise, an impersonator contract is produced.

syntax

(struct/dc struct-id field-spec ... maybe-inv)

 
field-spec = [field-name maybe-lazy contract-expr]
  | 
[field-name (dep-field-name ...)
            maybe-lazy
            maybe-contract-type
            maybe-dep-state
            contract-expr]
     
field-name = field-id
  | (#:selector selector-id)
  | (field-id #:parent struct-id)
     
maybe-lazy = 
  | #:lazy
     
maybe-contract-type = 
  | #:flat
  | #:chaperone
  | #:impersonator
     
maybe-dep-state = 
  | #:depends-on-state
     
maybe-inv = 
  | #:inv (dep-field-name ...) invariant-expr
Produces a contract that recognizes instances of the structure +type named by struct-id, and whose field values match the +contracts produced by the field-specs.

If the field-spec lists the names of other fields, +then the contract depends on values in those fields, and the contract-expr +expression is evaluated each time a selector is applied, building a new contract +for the fields based on the values of the dep-field-name fields (the +dep-field-name syntax is the same as the field-name syntax). +If the field is a dependent field and no contract-type annotation +appears, then it is assumed that the contract is +a chaperone, but not always a flat contract (and thus the entire struct/dc +contract is not a flat contract). +If this is not the case, and the contract is +always flat then the field must be annotated with +the #:flat, or the field must be annotated with +#:impersonator (in which case, it must be a mutable field).

A field-name is either an identifier naming a field in the first +case, an identifier naming a selector in the second case indicated +by the #:selector keyword, or +a field id for a struct that is a parent of struct-id, indicated +by the #:parent keyword.

If the #:lazy keyword appears, then the contract +on the field is checked lazily (only when a selector is applied); +#:lazy contracts cannot be put on mutable fields.

If a dependent contract depends on some mutable state, then use the +#:depends-on-state keyword argument (if a field’s dependent contract +depends on a mutable field, this keyword is automatically inferred). +The presence of this keyword means that the contract expression is evaluated +each time the corresponding field is accessed (or mutated, if it is a mutable +field). Otherwise, the contract expression for a dependent field contract +is evaluated when the contract is applied to a value.

If the #:inv clause appears, then the invariant expression is +evaluated (and must return a non-#f value) when the contract +is applied to a struct.

Contracts for immutable fields must be either flat or chaperone contracts. +Contracts for mutable fields may be impersonator contracts. +If all fields are immutable and the contract-exprs evaluate +to flat contracts, a flat contract is produced. If all the +contract-exprs are chaperone contracts, a chaperone contract is +produced. Otherwise, an impersonator contract is produced.

As an example, the function bst/c below +returns a contract for binary search trees whose values +are all between lo and hi. +The lazy annotations ensure that this contract does not +change the running time of operations that do not +inspect the entire tree.

Examples:
> (struct bt (val left right))
> (define (bst/c lo hi)
    (or/c #f
          (struct/dc bt
                     [val (between/c lo hi)]
                     [left (val) #:lazy (bst/c lo val)]
                     [right (val) #:lazy (bst/c val hi)])))
> (define/contract not-really-a-bst
    (bst/c -inf.0 +inf.0)
    (bt 5
        (bt 4
            (bt 2 #f #f)
            (bt 6 #f #f))
        #f))
> (bt-right not-really-a-bst)

#f

> (bt-val (bt-left (bt-left not-really-a-bst)))

2

> (bt-right (bt-left not-really-a-bst))

not-really-a-bst: broke its own contract

  promised: (between/c 4 5)

  produced: 6

  in: the val field of

      a part of the or/c of

      the right field of

      a part of the or/c of

      the left field of

      a part of the or/c of

      (or/c

       #f

       (struct/dc

        bt

        (val (between/c -inf.0 +inf.0))

        (left (val) #:lazy ...)

        (right (val) #:lazy ...)))

  contract from: (definition not-really-a-bst)

  blaming: (definition not-really-a-bst)

   (assuming the contract is correct)

  at: eval:4:0

Changed in version 6.0.1.6 of package base: Added #:inv.

procedure

(parameter/c in    
  [out    
  #:impersonator? impersonator?])  contract?
  in : contract?
  out : contract? = in
  impersonator? : any/c = #t
Produces a contract on parameters whose values must match +out. When the value in the contracted parameter +is set, it must match in.

If impersonator? is a true value, then + parameter/c always returns an impersonator +contract. If it is #f, then the result will be a + chaperone contract when both in and + out are chaperone contracts, and an impersonator contract otherwise.

Examples:
> (define/contract current-snack
    (parameter/c string?)
    (make-parameter "potato-chip"))
> (define baked/c
    (flat-named-contract 'baked/c (λ (s) (regexp-match #rx"baked" s))))
> (define/contract current-dinner
    (parameter/c string? baked/c)
    (make-parameter "turkey" (λ (s) (string-append "roasted " s))))
> (current-snack 'not-a-snack)

current-snack: contract violation

  expected: string?

  given: 'not-a-snack

  in: the parameter of

      (parameter/c string?)

  contract from: (definition current-snack)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

> (parameterize ([current-dinner "tofurkey"])
    (current-dinner))

current-dinner: broke its own contract

  promised: baked/c

  produced: "roasted tofurkey"

  in: the parameter of

      (parameter/c string? baked/c)

  contract from: (definition current-dinner)

  blaming: (definition current-dinner)

   (assuming the contract is correct)

  at: eval:4:0

Produces a contract for procedures that accept n argument +(i.e,. the procedure? contract is implied).

procedure

(hash/c key    
  val    
  [#:immutable immutable    
  #:flat? flat?])  contract?
  key : chaperone-contract?
  val : contract?
  immutable : (or/c #t #f 'dont-care) = 'dont-care
  flat? : boolean? = #f
Produces a contract that recognizes hash tables with keys and values +as specified by the key and val arguments.

Examples:
> (define/contract good-hash
    (hash/c integer? boolean?)
    (hash 1 #t
          2 #f
          3 #t))
> (define/contract bad-hash
    (hash/c integer? boolean?)
    (hash 1 "elephant"
          2 "monkey"
          3 "manatee"))

bad-hash: broke its own contract

  promised: boolean?

  produced: "elephant"

  in: the values of

      (hash/c integer? boolean?)

  contract from: (definition bad-hash)

  blaming: (definition bad-hash)

   (assuming the contract is correct)

  at: eval:3:0

There are a number of technicalities that control how hash/c contracts +behave. +

syntax

(hash/dc [key-id key-contract-expr] [value-id (key-id) value-contract-expr]
         hash/dc-option)
 
hash/dc-option = 
  | #:immutable immutable?-expr hash/dc-option
  | #:kind kind-expr hash/dc-option
Creates a contract for hash? tables with keys matching key-contract-expr +and where the contract on the values can depend on the key itself, since +key-id will be bound to the corresponding key before evaluating +the values-contract-expr.

If immutable?-expr is #t, then only immutable? hashes +are accepted. If it is #f then immutable? hashes are always +rejected. It defaults to 'dont-care, in which case both mutable and +immutable hashes are accepted.

If kind-expr evaluates to 'flat, then key-contract-expr +and value-contract-expr are expected to evaluate to flat-contract?s. +If it is 'chaperone, then they are expected to be chaperone-contract?s, +and it may also be 'impersonator, in which case they may be any contract?s. +The default is 'chaperone.

Examples:
> (define/contract h
    (hash/dc [k real?] [v (k) (>=/c k)])
    (hash 1 3
          2 4))
> (define/contract h
    (hash/dc [k real?] [v (k) (>=/c k)])
    (hash 3 1
          4 2))

h: broke its own contract

  promised: (>=/c 3)

  produced: 1

  in: the values of

      (hash/dc (k real?) (v (k) (>=/c k)))

  contract from: (definition h)

  blaming: (definition h)

   (assuming the contract is correct)

  at: eval:3:0

procedure

(channel/c val)  contract?

  val : contract?
Produces a contract that recognizes channels that communicate +values as specified by the val argument.

If the val argument is a chaperone contract, then the resulting contract +is a chaperone contract. Otherwise, the resulting contract is an impersonator +contract. When a channel contract is applied to a channel, the resulting channel +is not eq? to the input.

Examples:
> (define/contract chan
    (channel/c string?)
    (make-channel))
> (thread (λ () (channel-get chan)))

#<thread>

> (channel-put chan 'not-a-string)

chan: contract violation

  expected: string?

  given: 'not-a-string

  in: (channel/c string?)

  contract from: (definition chan)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

syntax

(prompt-tag/c contract ... maybe-call/cc)

 
maybe-call/cc = 
  | #:call/cc contract
  | #:call/cc (values contract ...)
 
  contract : contract?
Takes any number of contracts and returns a contract that recognizes +continuation prompt tags and will check any aborts or prompt handlers that +use the contracted prompt tag.

Each contract will check the corresponding value passed to +an abort-current-continuation and handled by the handler of a +call to call-with-continuation-prompt.

If all of the contracts are chaperone contracts, the resulting +contract will also be a chaperone contract. Otherwise, the contract is +an impersonator contract.

If maybe-call/cc is provided, then the provided contracts +are used to check the return values from a continuation captured with +call-with-current-continuation.

Examples:
> (define/contract tag
    (prompt-tag/c (-> number? string?))
    (make-continuation-prompt-tag))
> (call-with-continuation-prompt
    (lambda ()
      (number->string
        (call-with-composable-continuation
          (lambda (k)
            (abort-current-continuation tag k)))))
    tag
    (lambda (k) (k "not a number")))

tag: contract violation

  expected: number?

  given: "not a number"

  in: the 1st argument of

      (prompt-tag/c

       (-> number? string?)

       #:call/cc)

  contract from: (definition tag)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

procedure

(continuation-mark-key/c contract)  contract?

  contract : contract?
Takes a single contract and returns a contract that recognizes +continuation marks and will check any mappings of marks to values +or any accesses of the mark value.

If the argument contract is a chaperone contract, the resulting +contract will also be a chaperone contract. Otherwise, the contract is +an impersonator contract.

Examples:
> (define/contract mark-key
    (continuation-mark-key/c (-> symbol? (listof symbol?)))
    (make-continuation-mark-key))
> (with-continuation-mark
    mark-key
    (lambda (s) (append s '(truffle fudge ganache)))
    (let ([mark-value (continuation-mark-set-first
                       (current-continuation-marks) mark-key)])
      (mark-value "chocolate-bar")))

mark-key: contract violation

  expected: symbol?

  given: "chocolate-bar"

  in: the 1st argument of

      (continuation-mark-key/c

       (-> symbol? (listof symbol?)))

  contract from: (definition mark-key)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

procedure

(evt/c contract ...)  chaperone-contract?

  contract : chaperone-contract?
Returns a contract that recognizes synchronizable events whose +synchronization results are checked by the given +contracts.

The resulting contract is always a chaperone contract and its +arguments must all be chaperone contracts.

Examples:
> (define/contract my-evt
    (evt/c evt?)
    always-evt)
> (define/contract failing-evt
    (evt/c number? number?)
    (alarm-evt (+ (current-inexact-milliseconds) 50)))
> (sync my-evt)

#<always-evt>

> (sync failing-evt)

failing-evt: broke its own contract

  promised: event that produces 2 values

  produced: event that produces 1 values

  in: (evt/c number? number?)

  contract from: (definition failing-evt)

  blaming: (definition failing-evt)

   (assuming the contract is correct)

  at: eval:3:0

syntax

(flat-rec-contract id flat-contract-expr ...)

Constructs a recursive flat contract. A +flat-contract-expr can refer to id to refer +recursively to the generated contract.

For example, the contract

(flat-rec-contract sexp
  (cons/c sexp sexp)
  number?
  symbol?)

is a flat contract that checks for (a limited form of) +S-expressions. It says that a sexp is either two +sexps combined with cons, or a number, or a symbol.

Note that if the contract is applied to a circular value, contract +checking will not terminate.

syntax

(flat-murec-contract ([id flat-contract-expr ...] ...) body ...+)

A generalization of flat-rec-contract for defining several +mutually recursive flat contracts simultaneously. Each id is +visible in the entire flat-murec-contract form, and the +result of the final body is the result of the entire form.

syntax

any

Represents a contract that is always satisfied. In particular, it can accept +multiple values. It can only be used in a result position of contracts like +->. Using any elsewhere is a syntax error.

procedure

(promise/c c)  contract?

  c : contract?
Constructs a contract on a promise. The contract does not force the +promise, but when the promise is forced, the contract checks that the +result value meets the contract c.

procedure

(flat-contract predicate)  flat-contract?

  predicate : (-> any/c any/c)
Constructs a flat contract from predicate. A value +satisfies the contract if the predicate returns a true value.

This function is a holdover from before predicates could be used +directly as flat contracts. It exists today for backwards compatibility.

procedure

(flat-contract-predicate v)  (-> any/c any/c)

  v : flat-contract?
Extracts the predicate from a flat contract.

Note that most flat contracts can be used directly as predicates, but not all. +This function can be used to build predicates for ordinary Racket values that double +as contracts, such as numbers and symbols. When building a contract combinator +that needs to explicitly convert ordinary racket values to flat contracts, consider +using coerce-flat-contract instead of flat-contract-predicate so +that the combinator can raise errors that use the combinator’s name in the error +message.

procedure

(property/c accessor ctc [#:name name])  flat-contract?

  accessor : (-> any/c any/c)
  ctc : flat-contract?
  name : any/c = (object-name accessor)
Constructs a flat contract that checks that the first-order property +accessed by accessor satisfies ctc. The resulting contract +is equivalent to

(lambda (v) (ctc (accessor v)))

except that more information is included in error messages produced by +violations of the contract. The name argument is used to describe the +property being checked in error messages.

Examples:
> (define/contract (sum-triple lst)
    (-> (and/c (listof number?)
               (property/c length (=/c 3)))
        number?)
    (+ (first lst) (second lst) (third lst)))
> (sum-triple '(1 2 3))

6

> (sum-triple '(1 2))

sum-triple: contract violation

  expected: (=/c 3)

  given: 2

  in: the length of

      an and/c case of

      the 1st argument of

      (->

       (and/c

        (listof number?)

        (property/c length (=/c 3)))

       number?)

  contract from: (function sum-triple)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

Added in version 7.3.0.11 of package base.

procedure

(suggest/c c field message)  contract?

  c : contract?
  field : string?
  message : string?
Returns a contract that behaves like c, except +that it adds an extra line to the error message on a contract +violation.

The field and message strings are added +following the guidelines in +Error Message Conventions.

Examples:
> (define allow-calls? #f)
> (define/contract (f)
    (suggest/c (->* () #:pre allow-calls? any)
               "suggestion" "maybe you should set! allow-calls? to #t")
    5)
> (f)

f: contract violation

  #:pre condition

  suggestion: maybe you should set! allow-calls? to #t

  in: (->* () #:pre ... any)

  contract from: (function f)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:3:0

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/data.html b/clones/docs.racket-lang.org/reference/data.html new file mode 100644 index 00000000..e50f7aa7 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/data.html @@ -0,0 +1,3 @@ + +4 Datatypes

4 Datatypes

+Built-In Datatypes in The Racket Guide introduces Datatypes.

Each pre-defined datatype comes with a set of procedures for +manipulating instances of the datatype.

    4.1 Equality

    4.2 Booleans

    4.3 Numbers

    4.4 Strings

    4.5 Byte Strings

    4.6 Characters

    4.7 Symbols

    4.8 Regular Expressions

    4.9 Keywords

    4.10 Pairs and Lists

    4.11 Mutable Pairs and Lists

    4.12 Vectors

    4.13 Stencil Vectors

    4.14 Boxes

    4.15 Hash Tables

    4.16 Sequences and Streams

    4.17 Dictionaries

    4.18 Sets

    4.19 Procedures

    4.20 Void

    4.21 Undefined

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/debugging.html b/clones/docs.racket-lang.org/reference/debugging.html new file mode 100644 index 00000000..2511b87b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/debugging.html @@ -0,0 +1,87 @@ + +18.6 Debugging

18.6 Debugging

Racket’s built-in debugging support is limited to context (i.e., +“stack trace”) information that is printed with an exception. In +some cases, for BC implementation of Racket, disabling the +JIT compiler can affect context information. For the CS +implementation of Racket, setting the PLT_CS_DEBUG environment +variable causes compilation to record expression-level context +information, instead of just function-level information.

The errortrace library supports more consistent +(independent of the compiler) and precise context +information. The racket/trace library provides simple +tracing support. Finally, the DrRacket +programming environment provides much more debugging support.

18.6.1 Tracing

 (require racket/trace) package: base
The bindings documented in this section are provided by the racket/trace library, not racket/base or racket.

The racket/trace library mimics the tracing facility +available in Chez Scheme.

syntax

(trace id ...)

Each id must be bound to a procedure in the environment of +the trace expression, and must not be imported from another module. +Each id is set!ed to +a new procedure that traces procedure calls and returns by printing +the arguments and results of the call via +current-trace-notify. If multiple values are returned, each +value is displayed starting on a separate line.

When traced procedures invoke each other, nested invocations are shown +by printing a nesting prefix. If the nesting depth grows to ten and +beyond, a number is printed to show the actual nesting depth.

The trace form can be used on an identifier that is already +traced. In this case, assuming that the variable’s value has not been +changed, trace has no effect. If the variable has been +changed to a different procedure, then a new trace is installed.

Tracing respects tail calls to preserve loops, but its effect may be +visible through continuation marks. When a call to a traced procedure +occurs in tail position with respect to a previous traced call, then +the tailness of the call is preserved (and the result of the call is +not printed for the tail call, because the same result will be printed +for an enclosing call). Otherwise, however, the body of a traced +procedure is not evaluated in tail position with respect to a call to +the procedure.

The result of a trace expression is #<void>.

Examples:
> (define (f x) (if (zero? x) 0 (add1 (f (sub1 x)))))
> (trace f)
> (f 10)

>(f 10)

> (f 9)

> >(f 8)

> > (f 7)

> > >(f 6)

> > > (f 5)

> > > >(f 4)

> > > > (f 3)

> > > > >(f 2)

> > > > > (f 1)

> > > >[10] (f 0)

< < < <[10] 0

< < < < < 1

< < < < <2

< < < < 3

< < < <4

< < < 5

< < <6

< < 7

< <8

< 9

<10

10

trace can also be used to debug syntax transformers. +This is verbose to do directly with trace; refer to trace-define-syntax for a +simpler way to do this.

Examples:
> (require (for-syntax racket/trace))
> (begin-for-syntax
    (define let
      (syntax-rules ()
        [(_ ([x v]) e) ((lambda (x) e) v)]))
    (trace let))
> (define-syntax let let)
> (let ([x 120]) x)

>(_let #<syntax:eval:9:0 (let ((x 120)) x)>)

<#<syntax:eval:9:0 ((lambda (x) x) 120)>

120

When tracing syntax transformers, it may be helpful to modify current-trace-print-args and +current-trace-print-results to make the trace output more readable; see +current-trace-print-args for an extended example.

syntax

(trace-define id expr)

(trace-define (head args) body ...+)
The trace-define form is short-hand for first defining a +function then tracing it. This form supports all define forms.

Examples:
> (trace-define (f x) (if (zero? x) 0 (add1 (f (sub1 x)))))
> (f 5)

>(f 5)

> (f 4)

> >(f 3)

> > (f 2)

> > >(f 1)

> > > (f 0)

< < < 0

< < <1

< < 2

< <3

< 4

<5

5

Examples:
> (trace-define ((+n n) x) (+ n x))
> (map (+n 5) (list 1 3 4))

>(+n 5)

<#<procedure>

'(6 8 9)

syntax

(trace-define-syntax id expr)

(trace-define-syntax (head args) body ...+)
The trace-define-syntax form is short-hand for first defining a +syntax transformer then tracing it. This form supports all define-syntax forms.

For example:

Examples:
> (trace-define-syntax fact
    (syntax-rules ()
      [(_ x) 120]))
> (fact 5)

>(fact #<syntax:eval:15:0 (fact 5)>)

<#<syntax:eval:15:0 120>

120

By default, trace prints out syntax objects when tracing a +syntax transformer. This can result in too much output if you do not need to see, +e.g., source information. +To get more readable output by printing syntax objects as datums, we can modify the +current-trace-print-args and current-trace-print-results. +See current-trace-print-args for an example.

syntax

(trace-lambda [#:name id] args expr)

The trace-lambda form enables tracing an anonymous function. This +form will attempt to infer a name using +syntax-local-infer-name, or a name can be specified using the +optional #:name argument. A syntax error is raised if a name +is not given and a name cannot be inferred.

Example:
> ((trace-lambda (x) 120) 5)

>(eval:16:0 5)

<120

120

syntax

(trace-let id ([arg expr] ...+) body ...+)

The trace-let form enables tracing a named let.

Example:
> (trace-let f ([x 5])
    (if (zero? x)
        1
        (* x (f (sub1 x)))))

>(f 5)

> (f 4)

> >(f 3)

> > (f 2)

> > >(f 1)

> > > (f 0)

< < < 1

< < <1

< < 2

< <6

< 24

<120

120

syntax

(untrace id ...)

Undoes the effects of the trace form for each id, +set!ing each id back to the untraced procedure, but +only if the current value of id is a traced procedure. If +the current value of a id is not a procedure installed by +trace, then the variable is not changed.

The result of an untrace expression is #<void>.

parameter

(current-trace-notify)  (string? . -> . any)

(current-trace-notify proc)  void?
  proc : (string? . -> . any)
A parameter that determines the way that trace output is +displayed. The string given to proc is a trace; it does not +end with a newline, but it may contain internal newlines. Each call or +result is converted into a string using pretty-print. The +parameter’s default value prints the given string followed by a newline to +(current-output-port).

procedure

(trace-call id proc #:<kw> kw-arg ...)  any/c

  id : symbol?
  proc : procedure?
  kw-arg : any/c
Calls proc with the arguments supplied in +args, and possibly using keyword arguments. Also prints out the +trace information during the call, as described above in the docs for +trace, using id as the name of proc.

parameter

(current-trace-print-args)  
(-> symbol?
    list?
    (listof keyword?)
    list?
    number?
    void?)
(current-trace-print-args trace-print-args)  void?
  trace-print-args : 
(-> symbol?
    list?
    (listof keyword?)
    list?
    number?
    void?)
The value of this parameter is invoked to print out the arguments of a +traced call. It receives the name of the function, the function’s +ordinary arguments, its keywords, the values of the keywords, and a +number indicating the depth of the call.

Modifying this and current-trace-print-results is useful to to get more +readable or additional output when tracing syntax transformers. +For example, we can use debug-scopes to add scopes information +to the trace, (see debug-scopes for an example), +or remove source location information to just display the shape of the syntax +object

In this example, we update the printers current-trace-print-args and +current-trace-print-results +by storing the current printers (ctpa and +ctpr) to cast syntax objects to datum using syntax->datum and then +pass the transformed arguments and results to the previous printer. +When tracing, syntax arguments will be displayed without source location +information, shortening the output.

Examples:
> (require (for-syntax racket/trace))
> (begin-for-syntax
    (current-trace-print-args
      (let ([ctpa (current-trace-print-args)])
        (lambda (s l kw l2 n)
          (ctpa s (map syntax->datum l) kw l2 n))))
    (current-trace-print-results
      (let ([ctpr (current-trace-print-results)])
        (lambda (s r n)
         (ctpr s (map syntax->datum r) n)))))
> (trace-define-syntax fact
    (syntax-rules ()
      [(_ x) 120]))
> (fact 5)

>(fact '(fact 5))

<120

120

We must take care when modifying these parameters, especially when the +transformation makes assumptions about or changes the type of the +argument/result of the traced identifier. +This modification of current-trace-print-args and +current-trace-print-results is an imperative update, and will affect all traced identifiers. +This example assumes all arguments and results to all traced functions will be syntax objects, +which is the case only if you are only tracing syntax transformers. +If used as-is, the above code could result in type errors when tracing both functions and syntax transformers. +It would be better to use syntax->datum only when the argument or result is actually a syntax +object, for example, by defining maybe-syntax->datum as follows.

Examples:
> (require (for-syntax racket/trace))
> (begin-for-syntax
    (define (maybe-syntax->datum syn?)
      (if (syntax? syn?)
          (syntax->datum syn?)
          syn?))
    (current-trace-print-args
      (let ([ctpa (current-trace-print-args)])
        (lambda (s l kw l2 n)
          (ctpa s (map maybe-syntax->datum l) kw l2 n))))
    (current-trace-print-results
      (let ([ctpr (current-trace-print-results)])
        (lambda (s l n)
         (ctpr s (map maybe-syntax->datum l) n))))
  
  (trace-define (precompute-fact syn n) (datum->syntax syn (apply * (build-list n add1)))))
> (trace-define (run-time-fact n) (apply * (build-list n add1)))
> (require (for-syntax syntax/parse))
> (trace-define-syntax (fact syn)
    (syntax-parse syn
      [(_ x:nat) (precompute-fact syn (syntax->datum #'x))]
      [(_ x) #'(run-time-fact x)]))
> (fact 5)

>(fact '(fact 5))

>(precompute-fact '(fact 5) 5)

<120

120

> (fact (+ 2 3))

>(fact '(fact (+ 2 3)))

<'(run-time-fact (+ 2 3))

>(run-time-fact 5)

<120

120

parameter

(current-trace-print-results)  
(-> symbol?
    list?
    number?
    any)
(current-trace-print-results trace-print-results)  void?
  trace-print-results : 
(-> symbol?
    list?
    number?
    any)
The value of this parameter is invoked to print out the results of a +traced call. It receives the name of the function, the function’s +results, and a number indicating the depth of the call.

parameter

(current-prefix-in)  string?

(current-prefix-in prefix)  void?
  prefix : string?
This string is used by the default value of current-trace-print-args +indicating that the current line is showing the a call to a +traced function.

It defaults to ">".

parameter

(current-prefix-out)  string?

(current-prefix-out prefix)  void?
  prefix : string?
This string is used by the default value of current-trace-print-results +indicating that the current line is showing the result +of a traced call.

It defaults to "<".

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/define-sig-form.html b/clones/docs.racket-lang.org/reference/define-sig-form.html new file mode 100644 index 00000000..9a5f9cd4 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/define-sig-form.html @@ -0,0 +1,16 @@ + +7.7 Extending the Syntax of Signatures

7.7 Extending the Syntax of Signatures

syntax

(define-signature-form sig-form-id expr)

(define-signature-form (sig-form-id id) body ...+)
(define-signature-form (sig-form-id id intro-id) body ...+)
Binds sig-form-id for use within a define-signature +form.

In the first form, the result of expr must be a transformer +procedure that accepts one argument. In the second form, sig-form-id is bound to a +transformer procedure whose argument is id and whose body is +the bodys. The third form is like the second one, but +intro-id is bound to a procedure that is analogous to syntax-local-introduce +for the signature-form expansion.

The result of the transformer procedure must be a list of +syntax objects, which are substituted for a use of +sig-form-id in a define-signature expansion. (The +result is a list so that the transformer can produce multiple +declarations; define-signature has no splicing begin +form.)

Changed in version 8.1.0.7 of package base: Added support for the form with a transformer +expr.

syntax

(struct/ctc id ([field contract-expr] ...) struct-option ...)

 
field = id
  | [id #:mutable]
     
struct-option = #:mutable
  | #:omit-constructor
  | #:omit-define-syntaxes
  | #:omit-define-values
For use with define-signature. The struct/ctc form works +similarly to struct, but the constructor, predicate, field +accessors, and field mutators are contracted appropriately.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/define-struct.html b/clones/docs.racket-lang.org/reference/define-struct.html new file mode 100644 index 00000000..ecb9878e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/define-struct.html @@ -0,0 +1,146 @@ + +5.1 Defining Structure Types: struct

5.1 Defining Structure Types: struct

+Programmer-Defined Datatypes in The Racket Guide introduces struct.

syntax

(struct id maybe-super (field ...)
        struct-option ...)
 
maybe-super = 
  | super-id
     
field = field-id
  | [field-id field-option ...]
     
struct-option = #:mutable
  | #:super super-expr
  | #:inspector inspector-expr
  | #:auto-value auto-expr
  | #:guard guard-expr
  | #:property prop-expr val-expr
  | #:transparent
  | #:prefab
  | #:sealed
  | #:authentic
  | #:name name-id
  | #:extra-name name-id
  | #:constructor-name constructor-id
  | #:extra-constructor-name constructor-id
  | #:reflection-name symbol-expr
  | #:methods gen:name-id method-defs
  | #:omit-define-syntaxes
  | #:omit-define-values
     
field-option = #:mutable
  | #:auto
     
method-defs = (definition ...)
Creates a new structure type (or uses a pre-existing +structure type if #:prefab is specified), and binds +transformers and variables related to the structure type.

A struct form with n fields defines up +to 4+2n names:

  • struct:id, a structure type +descriptor value that represents the structure type.

  • constructor-id (which defaults to id), a +constructor procedure that takes m arguments +and returns a new instance of the structure type, where +m is the number of fields that do not include +an #:auto option.

  • name-id (which defaults to id), +a transformer binding that encapsulates +information about the structure type declaration. This binding +is used to define subtypes, and it also works with the +shared and match forms. For detailed +information about the binding of name-id, see +Structure Type Transformer Binding.

    The constructor-id and name-id can be the same, in +which case name-id performs both roles. In that case, the +expansion of name-id as an expression produces an otherwise +inaccessible identifier that is bound to the constructor +procedure; the expanded identifier has a +'constructor-for property whose value is an identifier +that is free-identifier=? to name-id as well as +a syntax property accessible via +syntax-procedure-alias-property with an identifier +that is free-identifier=? to name-id.

  • id?, a predicate procedure +that returns #t for instances of the structure +type (constructed by constructor-id or the +constructor for a subtype) and #f for any other +value.

  • id-field-id, for each +field; an accessor procedure that takes an +instance of the structure type and extracts the value +for the corresponding field.

  • set-id-field-id!, +for each field that includes a +#:mutable option, or when the +#:mutable option is specified as a +struct-option; a mutator procedure that +takes an instance of the structure type and a new field +value. The structure is destructively updated with the new +value, and #<void> is returned.

If super-id is provided, it must have a transformer binding +of the same sort bound to name-id (see Structure Type Transformer Binding), +and it specifies a supertype for the structure type. Alternately, +the #:super option can be used to specify an expression that +must produce a structure type descriptor. See +Structures for more information on structure subtypes +and supertypes. If both super-id and #:super are +provided, a syntax error is reported.

Examples:
> (struct document (author title content))
> (struct book document (publisher))
> (struct paper (journal) #:super struct:document)

If the #:mutable option is specified for an individual +field, then the field can be mutated in instances of the structure +type, and a mutator procedure is bound. Supplying +#:mutable as a struct-option is the same as +supplying it for all fields. If #:mutable is +specified as both a field-option and struct-option, +a syntax error is reported.

Examples:
> (struct cell ([content #:mutable]) #:transparent)
> (define a-cell (cell 0))
> (set-cell-content! a-cell 1)

The #:inspector, #:auto-value, and #:guard +options specify an inspector, value for automatic fields, and guard +procedure, respectively. See make-struct-type for more +information on these attributes of a structure type. The +#:property option, which can be supplied +multiple times, attaches a property value to the structure type; see +Structure Type Properties for more information on properties. The +#:transparent option is a shorthand for #:inspector #f.

Examples:
> (struct point (x y) #:inspector #f)
> (point 3 5)

(point 3 5)

> (struct celsius (temp)
    #:guard (λ (temp name)
              (unless (and (real? temp) (>= temp -273.15))
                (error "not a valid temperature"))
              temp))
> (celsius -275)

not a valid temperature

Use the prop:procedure property to implement an +applicable structure, use prop:evt to create a +structure type whose instances are synchronizable events, and +so on. By convention, property names start with prop:.

The #:prefab option obtains a prefab (pre-defined, +globally shared) structure type, as opposed to creating a new +structure type. Such a structure type is inherently transparent and +non-sealed, and it cannot have a guard or properties, so using #:prefab with +#:transparent, #:inspector, #:guard, +#:property, #:sealed, #:authentic, +or #:methods is a syntax error. +If a supertype is specified, it must also be a prefab structure type.

Examples:
> (struct prefab-point (x y) #:prefab)
> (prefab-point 1 2)

'#s(prefab-point 1 2)

> (prefab-point? #s(prefab-point 1 2))

#t

The #:sealed option is a shorthand for #:property prop:sealed #t, which prevents the structure type from being +used as the supertype of another structure type. See +prop:sealed for more information.

The #:authentic option is a shorthand for #:property prop:authentic #t, which prevents instances of the structure type +from being impersonated (see impersonate-struct), chaperoned +(see chaperone-struct), or acquiring a non-flat +contract (see struct/c). See prop:authentic for +more information. If a supertype is specified, it must also have the +prop:authentic property.

If name-id is supplied via #:extra-name and it is +not id, then both name-id and id are bound +to information about the structure type. Only one of +#:extra-name and #:name can be provided within a +struct form, and #:extra-name cannot be combined +with #:omit-define-syntaxes.

Examples:
> (struct ghost (color name) #:prefab #:extra-name GHOST)
> (match (ghost 'red 'blinky)
    [(GHOST c n) c])

'red

If constructor-id is supplied, then the transformer +binding of name-id records constructor-id as the +constructor binding; as a result, for example, struct-out +includes constructor-id as an export. If +constructor-id is supplied via +#:extra-constructor-name and it is not id, applying +object-name on the constructor produces the symbolic form of +id rather than constructor-id. If +constructor-id is supplied via #:constructor-name +and it is not the same as name-id, then name-id does not serve +as a constructor, and object-name on the constructor produces +the symbolic form of constructor-id. Only one of +#:extra-constructor-name and #:constructor-name +can be provided within a struct form.

Examples:
> (struct color (r g b) #:constructor-name -color)
> (struct rectangle (w h color) #:extra-constructor-name rect)
> (rectangle 13 50 (-color 192 157 235))

#<rectangle>

> (rect 50 37 (-color 35 183 252))

#<rectangle>

If #:reflection-name symbol-expr is provided, then +symbol-expr must produce a symbol that is used to identify +the structure type in reflective operations such as +struct-type-info. It corresponds to the first argument of +make-struct-type. Structure printing uses the reflective +name, as do the various procedures that are bound by struct.

Examples:
> (struct circle (radius) #:reflection-name '<circle>)
> (circle 15)

#<<circle>>

> (circle-radius "bad")

<circle>-radius: contract violation

  expected: <circle>?

  given: "bad"

If #:methods gen:name-id method-defs is provided (potentially multiple times), then +gen:name-id must be a transformer binding for the static +information about a generic interface produced by define-generics. +The method-defs define the methods of the gen:name-id +interface. A define/generic form or auxiliary definitions +and expressions may also appear in method-defs.

Examples:
> (struct constant-stream (val)
    #:methods gen:stream
    [(define (stream-empty? stream) #f)
     (define (stream-first stream)
       (constant-stream-val stream))
     (define (stream-rest stream) stream)])
> (stream-ref (constant-stream 'forever) 0)

'forever

> (stream-ref (constant-stream 'forever) 50)

'forever

If the #:omit-define-syntaxes option is supplied, then +name-id (and id, if #:extra-name is specified) +is not bound as a transformer. If the +#:omit-define-values option is supplied, then none of the +usual variables are bound, but id is bound. If both are +supplied, then the struct form is equivalent to +(begin).

Examples:
> (struct square (side) #:omit-define-syntaxes)
> (match (square 5)
    ; fails to match because syntax is omitted
    [(struct square x) x])

eval:28:0: match: square does not refer to a structure

definition

  at: square

  in: (struct square x)

> (struct ellipse (width height) #:omit-define-values)
> ellipse-width

ellipse-width: undefined;

 cannot reference an identifier before its definition

  in module: top-level

Expressions supplied to #:auto-value are evaluated once and shared +between every instance of the structure type. In particular, updates to +a mutable #:auto-value affect all current and future instances.

If #:auto is supplied as a field-option, then the +constructor procedure for the structure type does not accept an +argument corresponding to the field. Instead, the structure type’s +automatic value is used for the field, as specified by the +#:auto-value option, or as defaults to #f when +#:auto-value is not supplied. The field is mutable (e.g., +through reflective operations), but a mutator procedure is bound only +if #:mutable is specified.

If a field includes the #:auto option, then all +fields after it must also include #:auto, otherwise a syntax +error is reported. If any field-option or +struct-option keyword is repeated, other than +#:property, a syntax error is reported.

Examples:
(struct posn (x y [z #:auto #:mutable])
  #:auto-value 0
  #:transparent)

 

> (posn 1 2)

(posn 1 2 0)

> (posn? (posn 1 2))

#t

> (posn-y (posn 1 2))

2

> (posn-z (posn 1 2))

0

 

(struct color-posn posn (hue) #:mutable)
(define cp (color-posn 1 2 "blue"))

 

> (color-posn-hue cp)

"blue"

> cp

(color-posn 1 2 0 ...)

> (set-posn-z! cp 3)

For serialization, see define-serializable-struct.

Changed in version 6.9.0.4 of package base: Added #:authentic.
Changed in version 8.0.0.7: Added #:sealed.

syntax

(struct-field-index field-id)

This form can only appear as an expression within a +struct form; normally, it is used with +#:property, especially for a property like +prop:procedure. The result of a struct-field-index +expression is an exact, non-negative integer that corresponds to the +position within the structure declaration of the field named by +field-id.

Examples:
(struct mood-procedure (base rating)
  #:property prop:procedure (struct-field-index base))
(define happy+ (mood-procedure add1 10))

 

> (happy+ 2)

3

> (mood-procedure-rating happy+)

10

syntax

(define-struct id-maybe-super (field ...)
               struct-option ...)
 
id-maybe-super = id
  | (id super-id)
Like struct, except that the syntax for supplying a +super-id is different, and a constructor-id that +has a make- prefix on id is implicitly +supplied via #:extra-constructor-name if neither +#:extra-constructor-name nor #:constructor-name is +provided.

This form is provided for backwards compatibility; struct is +preferred.

Examples:
(define-struct posn (x y [z #:auto])
   #:auto-value 0
   #:transparent)

 

> (make-posn 1 2)

(posn 1 2 0)

> (posn? (make-posn 1 2))

#t

> (posn-y (make-posn 1 2))

2

syntax

(struct/derived (id . rest-form)
id (field ...) struct-option ...)
(struct/derived (id . rest-form)
id super-id (field ...) struct-option ...)
The same as struct, but with an extra (id . rest-form) sub-form that is treated as the overall form for +syntax-error reporting and otherwise ignored. The only constraint on +the sub-form for error reporting is that it starts with id. +The struct/derived form is intended for use by macros +that expand to struct.

Examples:
(define-syntax (fruit-struct stx)
  (syntax-case stx ()
   [(ds name . rest)
    (with-syntax ([orig stx])
      #'(struct/derived orig name (seeds color) . rest))]))

 

> (fruit-struct apple)
> (apple-seeds (apple 12 "red"))

12

> (fruit-struct apple #:mutable)
> (set-apple-seeds! (apple 12 "red") 8)
; this next line will cause an error due to a bad keyword
> (fruit-struct apple #:bad-option)

eval:54:0: fruit-struct: unrecognized struct-specification

keyword

  at: #:bad-option

  in: (fruit-struct apple #:bad-option)

Added in version 7.5.0.16 of package base.

syntax

(define-struct/derived (id . rest-form)
  id-maybe-super (field ...) struct-option ...)
Like struct/derived, except that the syntax for supplying a +super-id is different, and a constructor-id that +has a make- prefix on id is implicitly +supplied via #:extra-constructor-name if neither +#:extra-constructor-name nor #:constructor-name is +provided. The define-struct/derived form is intended for use by macros +that expand to define-struct.

Examples:
(define-syntax (define-xy-struct stx)
  (syntax-case stx ()
   [(ds name . rest)
    (with-syntax ([orig stx])
      #'(define-struct/derived orig name (x y) . rest))]))

 

> (define-xy-struct posn)
> (posn-x (make-posn 1 2))

1

> (define-xy-struct posn #:mutable)
> (set-posn-x! (make-posn 1 2) 0)
; this next line will cause an error due to a bad keyword
> (define-xy-struct posn #:bad-option)

eval:60:0: define-xy-struct: unrecognized

struct-specification keyword

  at: #:bad-option

  in: (define-xy-struct posn #:bad-option)

Changed in version 7.5.0.16 of package base: Moved main description to struct/derived +and replaced with differences.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/define.html b/clones/docs.racket-lang.org/reference/define.html new file mode 100644 index 00000000..5aba831e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/define.html @@ -0,0 +1,70 @@ + +3.14 Definitions: define, define-syntax, ...

3.14 Definitions: define, define-syntax, ...

+Definitions: define in The Racket Guide introduces definitions.

syntax

(define id expr)

(define (head args) body ...+)
 
head = id
  | (head args)
     
args = arg ...
  | arg ... . rest-id
     
arg = arg-id
  | [arg-id default-expr]
  | keyword arg-id
  | keyword [arg-id default-expr]
The first form binds id to the result of +expr, and the second form binds id to a +procedure. In the second case, the generated procedure is +(CVT (head args) body ...+), using the CVT meta-function +defined as follows:

(CVT (id . kw-formals) . datum)   = (lambda kw-formals . datum)
(CVT (head . kw-formals) . datum) = (lambda kw-formals expr)
                                     if (CVT head . datum) = expr

In an internal-definition context, a define form +introduces a local binding; see Internal Definitions. +At the top level, the top-level binding for id is created after +evaluating expr, if it does not exist already, and the +top-level mapping of id (in the namespace linked +with the compiled definition) is set to the binding at the same time.

In a context that allows liberal expansion of define, +id is bound as syntax if expr is an immediate +lambda form with keyword arguments or args include +keyword arguments.

Examples:
(define x 10)

 

> x

10

 

(define (f x)
  (+ x 1))

 

> (f 10)

11

 

(define ((f x) [y 20])
  (+ x y))

 

> ((f 10) 30)

40

> ((f 10))

30

syntax

(define-values (id ...) expr)

Evaluates the expr, and binds the results to the +ids, in order, if the number of results matches the number of +ids; if expr produces a different number of results, +the exn:fail:contract exception is raised.

In an internal-definition context (see Internal Definitions), +a define-values form introduces local bindings. +At the top level, the top-level binding for each id is +created after evaluating expr, if it does not exist already, +and the top-level mapping of each id (in the +namespace linked with the compiled definition) is set to +the binding at the same time.

Examples:
> (define-values () (values))
> (define-values (x y z) (values 1 2 3))
> z

3

If a define-values form for a function definition in a module +body has a 'compiler-hint:cross-module-inline +syntax property with a true value, then the Racket treats the +property as a performance hint. See +Function-Call Optimizations in The Racket Guide for more +information, and see also begin-encourage-inline.

syntax

(define-syntax id expr)

(define-syntax (head args) body ...+)
The first form creates a transformer binding (see +Transformer Bindings) of id with the value of +expr, which is an expression at phase level 1 relative +to the surrounding context. (See Identifiers, Binding, and Scopes for information +on phase levels.) Evaluation of expr side is +parameterized to set current-namespace as in +let-syntax.

The second form is a shorthand the same as for define; it +expands to a definition of the first form where the expr is a +lambda form.

In an internal-definition context (see Internal Definitions), +a define-syntax form introduces a local binding.

Examples:
> (define-syntax foo
    (syntax-rules ()
      ((_ a ...)
       (printf "~a\n" (list a ...)))))
> (foo 1 2 3 4)

(1 2 3 4)

> (define-syntax (bar syntax-object)
    (syntax-case syntax-object ()
      ((_ a ...)
       #'(printf "~a\n" (list a ...)))))
> (bar 1 2 3 4)

(1 2 3 4)

syntax

(define-syntaxes (id ...) expr)

Like define-syntax, but creates a transformer binding +for each id. The expr should produce as many values +as ids, and each value is bound to the corresponding +id.

When expr produces zero values for a top-level +define-syntaxes (i.e., not in a module or internal-definition +position), then the ids are effectively declared without +binding; see Macro-Introduced Bindings.

In an internal-definition context (see Internal Definitions), +a define-syntaxes form introduces local bindings.

Examples:
> (define-syntaxes (foo1 foo2 foo3)
    (let ([transformer1 (lambda (syntax-object)
                          (syntax-case syntax-object ()
                            [(_) #'1]))]
          [transformer2 (lambda (syntax-object)
                          (syntax-case syntax-object ()
                            [(_) #'2]))]
          [transformer3 (lambda (syntax-object)
                          (syntax-case syntax-object ()
                            [(_) #'3]))])
      (values transformer1
              transformer2
              transformer3)))
> (foo1)

1

> (foo2)

2

> (foo3)

3

syntax

(define-for-syntax id expr)

(define-for-syntax (head args) body ...+)
Like define, except that the binding is at phase level +1 instead of phase level 0 relative to its context. The +expression for the binding is also at phase level 1. (See +Identifiers, Binding, and Scopes for information on phase levels.) The form +is a shorthand for (begin-for-syntax (define id expr)) or +(begin-for-syntax (define (head args) body ...+)).

Within a module, bindings introduced by define-for-syntax +must appear before their uses or in the same +define-for-syntax form (i.e., the define-for-syntax +form must be expanded before the use is expanded). In particular, +mutually recursive functions bound by define-for-syntax must +be defined by the same define-for-syntax form.

Examples:
> (define-for-syntax helper 2)
> (define-syntax (make-two syntax-object)
    (printf "helper is ~a\n" helper)
    #'2)
> (make-two)

helper is 2

2

; helper' is not bound in the runtime phase
> helper

helper: undefined;

 cannot reference an identifier before its definition

  in module: top-level

> (define-for-syntax (filter-ids ids)
    (filter identifier? ids))
> (define-syntax (show-variables syntax-object)
    (syntax-case syntax-object ()
      [(_ expr ...)
       (with-syntax ([(only-ids ...)
                      (filter-ids (syntax->list #'(expr ...)))])
         #'(list only-ids ...))]))
> (let ([a 1] [b 2] [c 3])
    (show-variables a 5 2 b c))

'(1 2 3)

syntax

(define-values-for-syntax (id ...) expr)

Like define-for-syntax, but expr must produce as +many values as supplied ids, and all of the ids are +bound (at phase level 1).

Examples:
> (define-values-for-syntax (foo1 foo2) (values 1 2))
> (define-syntax (bar syntax-object)
    (printf "foo1 is ~a foo2 is ~a\n" foo1 foo2)
    #'2)
> (bar)

foo1 is 1 foo2 is 2

2

3.14.1 require Macros

The bindings documented in this section are provided by the racket/require-syntax library, not racket/base or racket.

syntax

(define-require-syntax id proc-expr)

(define-require-syntax (id args ...) body ...+)
The first form is like define-syntax, but for a +require sub-form. The proc-expr must produce a +procedure that accepts and returns a syntax object representing a +require sub-form.

This form expands to define-syntax with a use of +make-require-transformer (see require Transformers for +more information).

The second form is a shorthand the same as for define-syntax; it +expands to a definition of the first form where the proc-expr is a +lambda form.

procedure

(syntax-local-require-introduce stx)  syntax?

  stx : syntax?
For backward compatibility only; equivalent to syntax-local-introduce.

Changed in version 6.90.0.29 of package base: Made equivalent to syntax-local-introduce.

3.14.2 provide Macros

The bindings documented in this section are provided by the racket/provide-syntax library, not racket/base or racket.

syntax

(define-provide-syntax id proc-expr)

(define-provide-syntax (id args ...) body ...+)
The first form is like define-syntax, but for a +provide sub-form. The proc-expr must produce a +procedure that accepts and returns a syntax object representing a +provide sub-form.

This form expands to define-syntax with a use of +make-provide-transformer (see provide Transformers for +more information).

The second form is a shorthand the same as for define-syntax; it +expands to a definition of the first form where the expr is a +lambda form.

procedure

(syntax-local-provide-introduce stx)  syntax?

  stx : syntax?
For backward compatibility only; equivalent to syntax-local-introduce.

Changed in version 6.90.0.29 of package base: Made equivalent to syntax-local-introduce.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/dicts.html b/clones/docs.racket-lang.org/reference/dicts.html new file mode 100644 index 00000000..6b71b25e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/dicts.html @@ -0,0 +1,202 @@ + +4.17 Dictionaries

4.17 Dictionaries

A dictionary is an instance of a datatype that maps keys to +values. The following datatypes are all dictionaries:

When list of pairs is used as association list but does not +have distinct keys (so it’s not an association list), operations like +dict-ref and dict-remove operate on the first +instance of the key, while operations like dict-map and +dict-keys produce an element for every instance of the key.

 (require racket/dict) package: base
The bindings documented in this section are provided by the racket/dict and racket libraries, but not racket/base.

4.17.1 Dictionary Predicates and Contracts

procedure

(dict? v)  boolean?

  v : any/c
Returns #t if v is a dictionary, #f +otherwise.

Beware that dict? is not a constant-time test on pairs, since +checking that v is an association list may require +traversing the list.

Examples:
> (dict? #hash((a . "apple")))

#t

> (dict? '#("apple" "banana"))

#t

> (dict? '("apple" "banana"))

#f

> (dict? '((a . "apple") (b . "banana")))

#t

procedure

(dict-implements? d sym ...)  boolean?

  d : dict?
  sym : symbol?
Returns #t if d implements all of the methods from +gen:dict named by the syms; returns #f otherwise. +Fallback implementations do not affect the result; d may support the +given methods via fallback implementations yet produce #f.

Examples:
> (dict-implements? (hash 'a "apple") 'dict-set!)

#f

> (dict-implements? (make-hash '((a . "apple") (b . "banana"))) 'dict-set!)

#t

> (dict-implements? (make-hash '((b . "banana") (a . "apple"))) 'dict-remove!)

#t

> (dict-implements? (vector "apple" "banana") 'dict-set!)

#t

> (dict-implements? (vector 'a 'b) 'dict-remove!)

#f

> (dict-implements? (vector 'a "apple") 'dict-set! 'dict-remove!)

#f

procedure

(dict-implements/c sym ...)  flat-contract?

  sym : symbol?
Recognizes dictionaries that support all of the methods from gen:dict +named by the syms. Note that the generated contract is not similar to +hash/c, but closer to dict-implements?. +

Examples:
> (struct deformed-dict ()
    #:methods gen:dict [])
> (define/contract good-dict
    (dict-implements/c)
    (deformed-dict))
> (define/contract bad-dict
    (dict-implements/c 'dict-ref)
    (deformed-dict))

bad-dict: broke its own contract

  promised: (dict-implements/c dict-ref)

  produced: #<deformed-dict>

  in: (dict-implements/c dict-ref)

  contract from: (definition bad-dict)

  blaming: (definition bad-dict)

   (assuming the contract is correct)

  at: eval:14:0

procedure

(dict-mutable? d)  boolean?

  d : dict?
Returns #t if d is mutable via dict-set!, +#f otherwise.

Equivalent to (dict-implements? d 'dict-set!).

Examples:
> (dict-mutable? #hash((a . "apple")))

#f

> (dict-mutable? (make-hash))

#t

> (dict-mutable? '#("apple" "banana"))

#f

> (dict-mutable? (vector "apple" "banana"))

#t

> (dict-mutable? '((a . "apple") (b . "banana")))

#f

procedure

(dict-can-remove-keys? d)  boolean?

  d : dict?
Returns #t if d supports removing mappings via +dict-remove! and/or dict-remove, #f +otherwise.

Equivalent to +(or (dict-implements? d 'dict-remove!) (dict-implements? d 'dict-remove)).

Examples:
> (dict-can-remove-keys? #hash((a . "apple")))

#t

> (dict-can-remove-keys? '#("apple" "banana"))

#f

> (dict-can-remove-keys? '((a . "apple") (b . "banana")))

#t

procedure

(dict-can-functional-set? d)  boolean?

  d : dict?
Returns #t if d supports functional update via +dict-set, #f otherwise.

Equivalent to (dict-implements? d 'dict-set).

Examples:
> (dict-can-functional-set? #hash((a . "apple")))

#t

> (dict-can-functional-set? (make-hash))

#f

> (dict-can-functional-set? '#("apple" "banana"))

#f

> (dict-can-functional-set? '((a . "apple") (b . "banana")))

#t

4.17.2 Generic Dictionary Interface

syntax

gen:dict

A generic interface (see Generic Interfaces) that +supplies dictionary method implementations for a structure type via the +#:methods option of struct definitions. This interface can +be used to implement any of the methods documented as +Primitive Dictionary Methods and Derived Dictionary Methods.

Examples:
> (struct alist (v)
    #:methods gen:dict
    [(define (dict-ref dict key
                       [default (lambda () (error "key not found" key))])
       (cond [(assoc key (alist-v dict)) => cdr]
             [else (if (procedure? default) (default) default)]))
     (define (dict-set dict key val)
       (alist (cons (cons key val) (alist-v dict))))
     (define (dict-remove dict key)
       (define al (alist-v dict))
       (alist (remove* (filter (λ (p) (equal? (car p) key)) al) al)))
     (define (dict-count dict)
       (length (remove-duplicates (alist-v dict) #:key car)))])
; etc. other methods
> (define d1 (alist '((1 . a) (2 . b))))
> (dict? d1)

#t

> (dict-ref d1 1)

'a

> (dict-remove d1 1)

#<alist>

A structure type property used to define custom extensions +to the dictionary API. Using the prop:dict property is +discouraged; use the gen:dict generic interface +instead. Accepts a vector of 10 method implementations:

4.17.2.1 Primitive Dictionary Methods

These methods of gen:dict have no fallback implementations; they are +only supported for dictionary types that directly implement them.

procedure

(dict-ref dict key [failure-result])  any

  dict : dict?
  key : any/c
  failure-result : failure-result/c
   = (lambda () (raise (make-exn:fail ....)))
Returns the value for key in dict. If no value +is found for key, then failure-result determines the +result:

  • If failure-result is a procedure, it is called +(through a tail call) with no arguments to produce the result.

  • Otherwise, failure-result is returned as the result.

Examples:
> (dict-ref #hash((a . "apple") (b . "beer")) 'a)

"apple"

> (dict-ref #hash((a . "apple") (b . "beer")) 'c)

hash-ref: no value found for key

  key: 'c

> (dict-ref #hash((a . "apple") (b . "beer")) 'c #f)

#f

> (dict-ref '((a . "apple") (b . "banana")) 'b)

"banana"

> (dict-ref #("apple" "banana") 1)

"banana"

> (dict-ref #("apple" "banana") 3 #f)

#f

> (dict-ref #("apple" "banana") -3 #f)

dict-ref: contract violation

  expected: natural?

  given: -3

  in: the k argument of

      (->i

       ((d dict?) (k (d) (dict-key-contract d)))

       ((default any/c))

       any)

  contract from: <collects>/racket/dict.rkt

  blaming: top-level

   (assuming the contract is correct)

  at: <collects>/racket/dict.rkt:182:2

procedure

(dict-set! dict key v)  void?

  dict : (and/c dict? (not/c immutable?))
  key : any/c
  v : any/c
Maps key to v in dict, overwriting any +existing mapping for key. The update can fail with a +exn:fail:contract exception if dict is not mutable +or if key is not an allowed key for the dictionary (e.g., not +an exact integer in the appropriate range when dict is a +vector).

Examples:
> (define h (make-hash))
> (dict-set! h 'a "apple")
> h

'#hash((a . "apple"))

> (define v (vector #f #f #f))
> (dict-set! v 0 "apple")
> v

'#("apple" #f #f)

procedure

(dict-set dict key v)  (and/c dict? immutable?)

  dict : (and/c dict? immutable?)
  key : any/c
  v : any/c
Functionally extends dict by mapping key to +v, overwriting any existing mapping for key, and +returning an extended dictionary. The update can fail with a +exn:fail:contract exception if dict does not support +functional extension or if key is not an allowed key for the +dictionary.

Examples:
> (dict-set #hash() 'a "apple")

'#hash((a . "apple"))

> (dict-set #hash((a . "apple") (b . "beer")) 'b "banana")

'#hash((a . "apple") (b . "banana"))

> (dict-set '() 'a "apple")

'((a . "apple"))

> (dict-set '((a . "apple") (b . "beer")) 'b "banana")

'((a . "apple") (b . "banana"))

procedure

(dict-remove! dict key)  void?

  dict : (and/c dict? (not/c immutable?))
  key : any/c
Removes any existing mapping for key in dict. The +update can fail if dict is not mutable or does not support +removing keys (as is the case for vectors, for example).

Examples:
> (define h (make-hash))
> (dict-set! h 'a "apple")
> h

'#hash((a . "apple"))

> (dict-remove! h 'a)
> h

'#hash()

procedure

(dict-remove dict key)  (and/c dict? immutable?)

  dict : (and/c dict? immutable?)
  key : any/c
Functionally removes any existing mapping for key in +dict, returning the fresh dictionary. The update can fail +if dict does not support functional update or does not +support removing keys.

Examples:
> (define h #hash())
> (define h (dict-set h 'a "apple"))
> h

'#hash((a . "apple"))

> (dict-remove h 'a)

'#hash()

> h

'#hash((a . "apple"))

> (dict-remove h 'z)

'#hash((a . "apple"))

> (dict-remove '((a . "apple") (b . "banana")) 'a)

'((b . "banana"))

procedure

(dict-iterate-first dict)  any/c

  dict : dict?
Returns #f if dict contains no elements, otherwise +it returns a non-#f value that is an index to the first +element in the dict table; “first” refers to an unspecified ordering +of the dictionary elements. For a mutable dict, this index is +guaranteed to refer to the first item only as long as no mappings are +added to or removed from dict.

Examples:
> (dict-iterate-first #hash((a . "apple") (b . "banana")))

0

> (dict-iterate-first #hash())

#f

> (dict-iterate-first #("apple" "banana"))

0

> (dict-iterate-first '((a . "apple") (b . "banana")))

#<assoc-iter>

procedure

(dict-iterate-next dict pos)  any/c

  dict : dict?
  pos : any/c
Returns either a non-#f that is an index to the element in +dict after the element indexed by pos or #f +if pos refers to the last element in dict. If +pos is not a valid index, then the +exn:fail:contract exception is raised. For a mutable dict, the result +index is guaranteed to refer to its item only as long as no items are +added to or removed from dict. The dict-iterate-next +operation should take constant time.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (define i (dict-iterate-first h))
> i

0

> (dict-iterate-next h i)

1

> (dict-iterate-next h (dict-iterate-next h i))

#f

procedure

(dict-iterate-key dict pos)  any

  dict : dict?
  pos : any/c
Returns the key for the element in dict at index +pos. If pos is not a valid index for dict, +the exn:fail:contract exception is raised. The dict-iterate-key +operation should take constant time.

Examples:
> (define h '((a . "apple") (b . "banana")))
> (define i (dict-iterate-first h))
> (dict-iterate-key h i)

'a

> (dict-iterate-key h (dict-iterate-next h i))

'b

procedure

(dict-iterate-value dict pos)  any

  dict : dict?
  pos : any/c
Returns the value for the element in dict at index +pos. If pos is not a valid index for dict, +the exn:fail:contract exception is raised. The dict-iterate-key +operation should take constant time.

Examples:
> (define h '((a . "apple") (b . "banana")))
> (define i (dict-iterate-first h))
> (dict-iterate-value h i)

"apple"

> (dict-iterate-value h (dict-iterate-next h i))

"banana"

4.17.2.2 Derived Dictionary Methods

These methods of gen:dict have fallback implementations in terms of +the other methods; they may be supported even by dictionary types that do not +directly implement them.

procedure

(dict-has-key? dict key)  boolean?

  dict : dict?
  key : any/c
Returns #t if dict contains a value for the given +key, #f otherwise.

Supported for any dict that implements dict-ref.

Examples:
> (dict-has-key? #hash((a . "apple") (b . "beer")) 'a)

#t

> (dict-has-key? #hash((a . "apple") (b . "beer")) 'c)

#f

> (dict-has-key? '((a . "apple") (b . "banana")) 'b)

#t

> (dict-has-key? #("apple" "banana") 1)

#t

> (dict-has-key? #("apple" "banana") 3)

#f

> (dict-has-key? #("apple" "banana") -3)

#f

procedure

(dict-set*! dict key v ... ...)  void?

  dict : (and/c dict? (not/c immutable?))
  key : any/c
  v : any/c
Maps each key to each v in dict, overwriting any +existing mapping for each key. The update can fail with a +exn:fail:contract exception if dict is not mutable +or if any key is not an allowed key for the dictionary (e.g., not +an exact integer in the appropriate range when dict is a +vector). The update takes place from the left, so later mappings overwrite +earlier mappings.

Supported for any dict that implements dict-set!.

Examples:
> (define h (make-hash))
> (dict-set*! h 'a "apple" 'b "banana")
> h

'#hash((a . "apple") (b . "banana"))

> (define v1 (vector #f #f #f))
> (dict-set*! v1 0 "apple" 1 "banana")
> v1

'#("apple" "banana" #f)

> (define v2 (vector #f #f #f))
> (dict-set*! v2 0 "apple" 0 "banana")
> v2

'#("banana" #f #f)

procedure

(dict-set* dict key v ... ...)  (and/c dict? immutable?)

  dict : (and/c dict? immutable?)
  key : any/c
  v : any/c
Functionally extends dict by mapping each key to +each v, overwriting any existing mapping for each key, and +returning an extended dictionary. The update can fail with a +exn:fail:contract exception if dict does not support +functional extension or if any key is not an allowed key for the +dictionary. The update takes place from the left, so later mappings overwrite +earlier mappings.

Supported for any dict that implements dict-set.

Examples:
> (dict-set* #hash() 'a "apple" 'b "beer")

'#hash((a . "apple") (b . "beer"))

> (dict-set* #hash((a . "apple") (b . "beer")) 'b "banana" 'a "anchor")

'#hash((a . "anchor") (b . "banana"))

> (dict-set* '() 'a "apple" 'b "beer")

'((a . "apple") (b . "beer"))

> (dict-set* '((a . "apple") (b . "beer")) 'b "banana" 'a "anchor")

'((a . "anchor") (b . "banana"))

> (dict-set* '((a . "apple") (b . "beer")) 'b "banana" 'b "ballistic")

'((a . "apple") (b . "ballistic"))

procedure

(dict-ref! dict key to-set)  any

  dict : dict?
  key : any/c
  to-set : any/c
Returns the value for key in dict. If no value +is found for key, then to-set determines the +result as in dict-ref (i.e., it is either a thunk that computes a value +or a plain value), and this result is stored in dict for the +key. (Note that if to-set is a thunk, it is not +invoked in tail position.)

Supported for any dict that implements dict-ref and +dict-set!.

Examples:
> (dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'a #f)

"apple"

> (dict-ref! (make-hasheq '((a . "apple") (b . "beer"))) 'c 'cabbage)

'cabbage

> (define h (make-hasheq '((a . "apple") (b . "beer"))))
> (dict-ref h 'c)

hash-ref: no value found for key

  key: 'c

> (dict-ref! h 'c (λ () 'cabbage))

'cabbage

> (dict-ref h 'c)

'cabbage

procedure

(dict-update! dict    
  key    
  updater    
  [failure-result])  void?
  dict : (and/c dict? (not/c immutable?))
  key : any/c
  updater : (any/c . -> . any/c)
  failure-result : failure-result/c
   = (lambda () (raise (make-exn:fail ....)))
Composes dict-ref and dict-set! to update an +existing mapping in dict, where the optional failure-result +argument is used as in dict-ref when no mapping exists for +key already.

Supported for any dict that implements dict-ref and +dict-set!.

Examples:
> (define h (make-hash))
> (dict-update! h 'a add1)

hash-update!: no value found for key: 'a

> (dict-update! h 'a add1 0)
> h

'#hash((a . 1))

> (define v (vector #f #f #f))
> (dict-update! v 0 not)
> v

'#(#t #f #f)

procedure

(dict-update dict key updater [failure-result])

  (and/c dict? immutable?)
  dict : dict?
  key : any/c
  updater : (any/c . -> . any/c)
  failure-result : failure-result/c
   = (lambda () (raise (make-exn:fail ....)))
Composes dict-ref and dict-set to functionally +update an existing mapping in dict, where the optional failure-result +argument is used as in dict-ref when no mapping exists for +key already.

Supported for any dict that implements dict-ref and +dict-set.

Examples:
> (dict-update #hash() 'a add1)

hash-update: no value found for key: 'a

> (dict-update #hash() 'a add1 0)

'#hash((a . 1))

> (dict-update #hash((a . "apple") (b . "beer")) 'b string-length)

'#hash((a . "apple") (b . 4))

procedure

(dict-map dict proc)  (listof any/c)

  dict : dict?
  proc : (any/c any/c . -> . any/c)
Applies the procedure proc to each element in +dict in an unspecified order, accumulating the results +into a list. The procedure proc is called each time with a +key and its value.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, dict-iterate-key, and +dict-iterate-value.

Example:
> (dict-map #hash((a . "apple") (b . "banana")) vector)

'(#(b "banana") #(a "apple"))

procedure

(dict-map/copy dict proc)  dict?

  dict : dict?
  proc : (any/c any/c . -> . (values any/c any/c))
Applies the procedure proc to each element in +dict in an unspecified order, accumulating the results +into a dict of the same kind. +The procedure proc is called each time with a key +and its value, and must return a corresponding key and +value.

Supported for any dict that implements +dict-iterate-first, dict-iterate-next, +dict-iterate-key, and dict-iterate-value, +and either dict-set and dict-clear, or +dict-set!, dict-copy, and +dict-clear!.

Example:
> (dict-map/copy #hash((a . "apple") (b . "banana")) (lambda (k v) (values k (string-upcase v))))

'#hash((a . "APPLE") (b . "BANANA"))

Added in version 8.5.0.2 of package base.

procedure

(dict-for-each dict proc)  void?

  dict : dict?
  proc : (any/c any/c . -> . any)
Applies proc to each element in dict (for the +side-effects of proc) in an unspecified order. The procedure +proc is called each time with a key and its value.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, dict-iterate-key, and +dict-iterate-value.

Example:
> (dict-for-each #hash((a . "apple") (b . "banana"))
                 (lambda (k v)
                   (printf "~a = ~s\n" k v)))

b = "banana"

a = "apple"

procedure

(dict-empty? dict)  boolean?

  dict : dict?
Reports whether dict is empty.

Supported for any dict that implements dict-iterate-first.

Examples:
> (dict-empty? #hash((a . "apple") (b . "banana")))

#f

> (dict-empty? (vector))

#t

procedure

(dict-count dict)  exact-nonnegative-integer?

  dict : dict?
Returns the number of keys mapped by dict, usually in +constant time.

Supported for any dict that implements dict-iterate-first +and dict-iterate-next.

Examples:
> (dict-count #hash((a . "apple") (b . "banana")))

2

> (dict-count #("apple" "banana"))

2

procedure

(dict-copy dict)  dict?

  dict : dict?
Produces a new, mutable dictionary of the same type as dict and with +the same key/value associations.

Supported for any dict that implements dict-clear, +dict-set!, dict-iterate-first, dict-iterate-next, +dict-iterate-key, and dict-iterate-value.

Examples:
> (define original (vector "apple" "banana"))
> (define copy (dict-copy original))
> original

'#("apple" "banana")

> copy

'#("apple" "banana")

> (dict-set! copy 1 "carrot")
> original

'#("apple" "banana")

> copy

'#("apple" "carrot")

procedure

(dict-clear dict)  dict?

  dict : dict?
Produces an empty dictionary of the same type as dict. If +dict is mutable, the result must be a new dictionary.

Supported for any dict that supports dict-remove, +dict-iterate-first, dict-iterate-next, and +dict-iterate-key.

Examples:
> (dict-clear #hash((a . "apple") ("banana" . b)))

'#hash()

> (dict-clear '((1 . two) (three . "four")))

'()

procedure

(dict-clear! dict)  void?

  dict : dict?
Removes all of the key/value associations in dict.

Supported for any dict that supports dict-remove!, +dict-iterate-first, and dict-iterate-key.

Examples:
> (define table (make-hash))
> (dict-set! table 'a "apple")
> (dict-set! table "banana" 'b)
> table

'#hash((a . "apple") ("banana" . b))

> (dict-clear! table)
> table

'#hash()

procedure

(dict-keys dict)  list?

  dict : dict?
Returns a list of the keys from +dict in an unspecified order.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, and dict-iterate-key.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (dict-keys h)

'(b a)

procedure

(dict-values dict)  list?

  dict : dict?
Returns a list of the values from +dict in an unspecified order.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, and dict-iterate-value.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (dict-values h)

'("banana" "apple")

procedure

(dict->list dict)  list?

  dict : dict?
Returns a list of the associations from +dict in an unspecified order.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, dict-iterate-key, and +dict-iterate-value.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (dict->list h)

'((b . "banana") (a . "apple"))

4.17.3 Dictionary Sequences

procedure

(in-dict dict)  sequence?

  dict : dict?
Returns a sequence +whose each element is two values: a key and corresponding value from +dict.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, dict-iterate-key, and +dict-iterate-value.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (for/list ([(k v) (in-dict h)])
    (format "~a = ~s" k v))

'("b = \"banana\"" "a = \"apple\"")

procedure

(in-dict-keys dict)  sequence?

  dict : dict?
Returns a sequence whose elements are the keys of dict.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, and dict-iterate-key.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (for/list ([k (in-dict-keys h)])
    k)

'(b a)

procedure

(in-dict-values dict)  sequence?

  dict : dict?
Returns a sequence whose elements are the values of dict.

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, and dict-iterate-value.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (for/list ([v (in-dict-values h)])
    v)

'("banana" "apple")

procedure

(in-dict-pairs dict)  sequence?

  dict : dict?
Returns a sequence +whose elements are pairs, each containing a key and its value from +dict (as opposed to using in-dict, which gets the +key and value as separate values for each element).

Supported for any dict that implements dict-iterate-first, +dict-iterate-next, dict-iterate-key, and +dict-iterate-value.

Examples:
> (define h #hash((a . "apple") (b . "banana")))
> (for/list ([p (in-dict-pairs h)])
    p)

'((b . "banana") (a . "apple"))

4.17.4 Contracted Dictionaries

A structure type property for defining dictionaries with +contracts. The value associated with prop:dict/contract must +be a list of two immutable vectors:

(list dict-vector
      (vector type-key-contract
              type-value-contract
              type-iter-contract
              instance-key-contract
              instance-value-contract
              instance-iter-contract))

The first vector must be a vector of 10 procedures which match the +gen:dict generic interface (in addition, it must be an +immutable vector). The second vector must contain six elements; each +of the first three is a contract for the dictionary type’s keys, +values, and positions, respectively. Each of the second three is +either #f or a procedure used to extract the contract from +a dictionary instance.

procedure

(dict-key-contract d)  contract?

  d : dict?

procedure

(dict-value-contract d)  contract?

  d : dict?

procedure

(dict-iter-contract d)  contract?

  d : dict?
Returns the contract that d imposes on its keys, values, or +iterators, respectively, if d implements the +prop:dict/contract interface.

4.17.5 Custom Hash Tables

syntax

(define-custom-hash-types name
                          optional-predicate
                          comparison-expr
                          optional-hash-functions)
 
optional-predicate = 
  | #:key? predicate-expr
     
optional-hash-functions = 
  | hash1-expr
  | hash1-expr hash2-expr
Creates a new dictionary type based on the given comparison +comparison-expr, hash functions hash1-expr and +hash2-expr, and key predicate predicate-expr; the interfaces +for these functions are the same as in make-custom-hash-types. +The new dictionary type has three variants: immutable, mutable with +strongly-held keys, and mutable with weakly-held keys.

Defines seven names:

  • name? recognizes instances of the new type,

  • immutable-name? recognizes +immutable instances of the new type,

  • mutable-name? recognizes +mutable instances of the new type with strongly-held keys,

  • weak-name? recognizes +mutable instances of the new type with weakly-held keys,

  • make-immutable-name constructs +immutable instances of the new type,

  • make-mutable-name constructs +mutable instances of the new type with strongly-held keys, and

  • make-weak-name constructs +mutable instances of the new type with weakly-held keys.

The constructors all accept a dictionary as an optional argument, providing +initial key/value pairs.

Examples:
> (define-custom-hash-types string-hash
                            #:key? string?
                            string=?
                            string-length)
> (define imm
    (make-immutable-string-hash
     '(("apple" . a) ("banana" . b))))
> (define mut
    (make-mutable-string-hash
     '(("apple" . a) ("banana" . b))))
> (dict? imm)

#t

> (dict? mut)

#t

> (string-hash? imm)

#t

> (string-hash? mut)

#t

> (immutable-string-hash? imm)

#t

> (immutable-string-hash? mut)

#f

> (dict-ref imm "apple")

'a

> (dict-ref mut "banana")

'b

> (dict-set! mut "banana" 'berry)
> (dict-ref mut "banana")

'berry

> (equal? imm mut)

#f

> (equal? (dict-remove (dict-remove imm "apple") "banana")
          (make-immutable-string-hash))

#t

procedure

(make-custom-hash-types eql?    
  [hash1    
  hash2    
  #:key? key?    
  #:name name    
  #:for who])  
(any/c . -> . boolean?)
(any/c . -> . boolean?)
(any/c . -> . boolean?)
(any/c . -> . boolean?)
(->* [] [dict?] dict?)
(->* [] [dict?] dict?)
(->* [] [dict?] dict?)
  eql? : 
(or/c (any/c any/c . -> . any/c)
      (any/c any/c (any/c any/c . -> . any/c) . -> . any/c))
  hash1 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  hash2 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  key? : (any/c . -> . boolean?) = (const #true)
  name : symbol? = 'custom-hash
  who : symbol? = 'make-custom-hash-types
Creates a new dictionary type based on the given comparison function +eql?, hash functions hash1 and hash2, and predicate +key?. The new dictionary type has variants that are immutable, +mutable with strongly-held keys, and mutable with weakly-held keys. The given +name is used when printing instances of the new dictionary type, and +the symbol who is used for reporting errors.

The comparison function eql? may accept 2 or 3 arguments. If it +accepts 2 arguments, it given two keys to compare them. If it accepts +3 arguments and does not accept 2 arguments, it is also given a +recursive comparison function that handles data cycles when comparing sub-parts +of the keys.

The hash functions hash1 and hash2 may accept 1 or 2 +arguments. If either hash function accepts 1 argument, it is applied to a key +to compute the corresponding hash value. If either hash function accepts 2 +arguments and does not accept 1 argument, it is also given a recursive hash +function that handles data cycles when computing hash values of sub-parts of +the keys.

The predicate key? must accept 1 argument and is used to recognize +valid keys for the new dictionary type.

Produces seven values:

  • a predicate recognizing all instances of the new dictionary type,

  • a predicate recognizing immutable instances,

  • a predicate recognizing mutable instances,

  • a predicate recognizing weak instances,

  • a constructor for immutable instances,

  • a constructor for mutable instances, and

  • a constructor for weak instances.

See define-custom-hash-types for an example.

procedure

(make-custom-hash eql?    
  [hash1    
  hash2    
  #:key? key?])  dict?
  eql? : 
(or/c (any/c any/c . -> . any/c)
      (any/c any/c (any/c any/c . -> . any/c) . -> . any/c))
  hash1 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  hash2 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  key? : (any/c . -> . boolean?) = (λ (x) #true)

procedure

(make-weak-custom-hash eql?    
  [hash1    
  hash2    
  #:key? key?])  dict?
  eql? : 
(or/c (any/c any/c . -> . any/c)
      (any/c any/c (any/c any/c . -> . any/c) . -> . any/c))
  hash1 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  hash2 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  key? : (any/c . -> . boolean?) = (λ (x) #true)

procedure

(make-immutable-custom-hash eql?    
  [hash1    
  hash2    
  #:key? key?])  dict?
  eql? : 
(or/c (any/c any/c . -> . any/c)
      (any/c any/c (any/c any/c . -> . any/c) . -> . any/c))
  hash1 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  hash2 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  key? : (any/c . -> . boolean?) = (λ (x) #true)
Creates an instance of a new dictionary type, implemented + in terms of a hash table where keys are compared with + eql?, hashed with hash1 and + hash2, and where the key predicate is + key?. See gen:equal and gen:equal+hash for information + on suitable equality and hashing functions.

The make-custom-hash and make-weak-custom-hash +functions create a mutable dictionary that does not support functional +update, while make-immutable-custom-hash creates an immutable +dictionary that supports functional update. The dictionary created by +make-weak-custom-hash retains its keys weakly, like the result +of make-weak-hash.

Dictionaries created by make-custom-hash and company are +equal? when they have the same mutability and key strength, +the associated procedures are equal?, and the key–value +mappings are the same when keys and values are compared with +equal?.

See also define-custom-hash-types.

Examples:
> (define h (make-custom-hash (lambda (a b)
                                (string=? (format "~a" a)
                                          (format "~a" b)))
                              (lambda (a)
                                (equal-hash-code
                                 (format "~a" a)))))
> (dict-set! h 1 'one)
> (dict-ref h "1")

'one

4.17.6 Passing keyword arguments in dictionaries

procedure

(keyword-apply/dict proc    
  kw-dict    
  pos-arg ...    
  pos-args    
  #:<kw> kw-arg ...)  any
  proc : procedure?
  kw-dict : dict?
  pos-arg : any/c
  pos-args : (listof any/c)
  kw-arg : any/c
Applies the proc using the positional arguments +from (list* pos-arg ... pos-args), and the keyword +arguments from kw-dict in addition to the directly +supplied keyword arguments in the #:<kw> kw-arg + sequence.

All the keys in kw-dict must be keywords. +The keywords in the kw-dict do not have to be +sorted. However, the keywords in kw-dict and the +directly supplied #:<kw> keywords must not overlap. +The given proc must accept all of the keywords in +kw-dict plus the #:<kw>s.

Examples:
> (define (sundae #:ice-cream [ice-cream '("vanilla")]
                  #:toppings [toppings '("brownie-bits")]
                  #:sprinkles [sprinkles "chocolate"]
                  #:syrup [syrup "caramel"])
    (format "A sundae with ~a ice cream, ~a, ~a sprinkles, and ~a syrup."
            (string-join ice-cream #:before-last " and ")
            (string-join toppings #:before-last " and ")
            sprinkles
            syrup))
> (keyword-apply/dict sundae '((#:ice-cream    "chocolate"))  '())

"A sundae with chocolate ice cream, brownie-bits, chocolate sprinkles, and caramel syrup."

> (keyword-apply/dict sundae
                      (hash '#:toppings '("cookie-dough")
                            '#:sprinkles "rainbow"
                            '#:syrup "chocolate")
                      '())

"A sundae with vanilla ice cream, cookie-dough, rainbow sprinkles, and chocolate syrup."

> (keyword-apply/dict sundae
                      #:sprinkles "rainbow"
                      (hash '#:toppings '("cookie-dough")
                            '#:syrup "chocolate")
                      '())

"A sundae with vanilla ice cream, cookie-dough, rainbow sprinkles, and chocolate syrup."

Added in version 7.9 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/doc-bibliography.html b/clones/docs.racket-lang.org/reference/doc-bibliography.html new file mode 100644 index 00000000..cf9b204f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/doc-bibliography.html @@ -0,0 +1,2 @@ + +Bibliography

Bibliography

[C99] ISO/IEC, “ISO/IEC 9899:1999 Cor. 3:2007(E).” 2007.
[Culpepper07] Ryan Culpepper, Sam Tobin-Hochstadt, and Matthew Flatt, “Advanced Macrology and the Implementation of Typed Scheme,” Workshop on Scheme and Functional Programming, 2007. https://www2.ccs.neu.edu/racket/pubs/scheme2007-ctf.pdf
[Danvy90] Olivier Danvy and Andre Filinski, “Abstracting Control,” LISP and Functional Programming, 1990. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.6.960&rep=rep1&type=pdf
[Felleisen88a] Matthias Felleisen, “The theory and practice of first-class prompts,” Principles of Programming Languages, 1988. https://www.cs.tufts.edu/~nr/cs257/archive/matthias-felleisen/prompts.pdf
[Felleisen88] Matthias Felleisen, Mitch Wand, Dan Friedman, and Bruce Duba, “Abstract Continuations: A Mathematical Semantics for Handling Full Functional Jumps,” LISP and Functional Programming, 1988. https://help.luddy.indiana.edu/techreports/TRNNN.cgi?trnum=TR248
[Feltey18] Daniel Feltey, Ben Greenman, Christophe Scholliers, Robert Bruce Findler, and Vincent St-Amour, “Collapsible Contracts: Fixing a Pathology of Gradual Typing,” Object-Oriented Programming, Systems, and Languages (OOPSLA), 2018. https://www.ccis.northeastern.edu/~types/publications/collapsible/fgsfs-oopsla-2018.pdf
[Flatt02] Matthew Flatt, “Composable and Compilable Macros: You Want it When?,” International Conference on Functional Programming (ICFP), 2002. http://www.cs.utah.edu/plt/publications/gpce13-f-color.pdf
[Friedman95] Daniel P. Friedman, C. T. Haynes, and R. Kent Dybvig, “Exception system proposal,” web page, 1995. https://web.archive.org/web/20161012054505/http://www.cs.indiana.edu/scheme-repository/doc.proposals.exceptions.html
[Gasbichler02] Martin Gasbichler and Michael Sperber, “Processes vs. User-Level Threads in Scsh,” Workshop on Scheme and Functional Programming, 2002. http://www.ccs.neu.edu/home/shivers/papers/scheme02/article/threads.pdf
[Greenberg15] Michael Greenberg, “Space-Efficient Manifest Contracts,” Principles of Programming Languages (POPL), 2015. https://cs.pomona.edu/~michael/papers/popl2015_space.pdf
[Gunter95] Carl Gunter, Didier Remy, and Jon Rieke, “A Generalization of Exceptions and Control in ML-like Languages,” Functional Programming Languages and Computer Architecture, 1995. http://gallium.inria.fr/~remy/ftp/prompt.pdf
[Haynes84] Christopher T. Haynes and Daniel P. Friedman, “Engines Build Process Abstractions,” Symposium on LISP and Functional Programming, 1984. https://legacy.cs.indiana.edu/ftp/techreports/TR159.pdf
[Hayes97] Barry Hayes, “Ephemerons: a New Finalization Mechanism,” Object-Oriented Languages, Programming, Systems, and Applications, 1997. https://static.aminer.org/pdf/PDF/000/522/273/ephemerons_a_new_finalization_mechanism.pdf
[Hieb90] Robert Hieb and R. Kent Dybvig, “Continuations and Concurrency,” Principles and Practice of Parallel Programming, 1990. https://legacy.cs.indiana.edu/ftp/techreports/TR256.pdf
[Lamport79] Leslie Lamport, “How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Programs,” IEEE Transactions on Computers, 179. https://www.microsoft.com/en-us/research/uploads/prod/2016/12/How-to-Make-a-Multiprocessor-Computer-That-Correctly-Executes-Multiprocess-Programs.pdf
[L'Ecuyer02] Pierre L’Ecuyer, Richard Simard, E. Jack Chen, and W. David Kelton, “An Object-Oriented Random-Number Package With Many Long Streams and Substreams,” Operations Research, 50(6), 2002. https://www.iro.umontreal.ca/~lecuyer/myftp/papers/streams00.pdf
[Queinnec91] Queinnec and Serpette, “A Dynamic Extent Control Operator for Partial Continuations,” Principles of Programming Languages, 1991. https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.40.9946&rep=rep1&type=pdf
[Reppy99] John H. Reppy, Concurrent Programming in ML, Cambridge University Press, 1999. https://doi.org/10.1017/CBO9780511574962
[Roux14] Pierre Roux, “Innocuous Double Rounding of Basic Arithmetic Operations,” Journal of Formalized Reasoning, 7(1), 2014.
[Sapin18] Simon Sapin, “The WTF-8 Encoding.” 2018. http://simonsapin.github.io/wtf-8/
[Shan04] Ken Shan, “Shift to Control,” Workshop on Scheme and Functional Programming, 2004. http://homes.sice.indiana.edu/ccshan/recur/recur.pdf
[Sperber07] Michael Sperber, R. Kent Dybvig, Matthew Flatt, and Anton van Straaten (editors), “The Revised6 Report on the Algorithmic Language Scheme.” 2007. http://www.r6rs.org/
[Sitaram90] Dorai Sitaram and Matthias Felleisen, “Control Delimiters and Their Hierarchies,” Lisp and Symbolic Computation, 1990. https://www2.ccs.neu.edu/racket/pubs/lasc1990-sf.pdf
[Sitaram93] Dorai Sitaram, “Handling Control,” Programming Language Design and Implementation, 1993. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.7256
[SRFI-42] Sebastian Egner, “SRFI-42: Eager Comprehensions,” SRFI, 2003. http://srfi.schemers.org/srfi-42/
[Strickland12] T. Stephen Strickland, Sam Tobin-Hochstadt, Matthew Flatt, and Robert Bruce Findler, “Chaperones and Impersonators: Run-time Support for Reasonable Interposition,” Object-Oriented Programming, Systems, and Languages (OOPSLA), 2012. http://www.eecs.northwestern.edu/~robby/pubs/papers/oopsla2012-stff.pdf
[Torosyan21] Son Torosyan, Jon Zeppieri, and Matthew Flatt, “Runtime and Compiler Support for HAMTs,” Dynamic Languages Symposium (DLS), 2021. https://www.cs.utah.edu/plt/publications/dls21-tzf.pdf

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/doc-index.html b/clones/docs.racket-lang.org/reference/doc-index.html new file mode 100644 index 00000000..5c0e9c89 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/doc-index.html @@ -0,0 +1,35 @@ + +Index

Index

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

 

"
"longdouble.dll"
#! 
#!
#!/
#"
#%
#%app
'#%braces
'#%brackets
#%datum
#%declare
'#%dot
#%expression
'#%kernel
#%module-begin
#%plain-app
#%plain-lambda
#%plain-module-begin
#%printing-module-begin
#%provide
#%require
#%stratified-body
#%top
#%top-interaction
#%variable-reference
#&
#'
#,
#,@
#0#
#0=
#:
#:cross-phase-persistent
#:empty-namespace
#:realm
#:unsafe
#;
#<<
#\
#\backspace
#\linefeed
#\newline
#\nul
#\null
#\page
#\return
#\rubout
#\space
#\tab
#\vtab
#`
#b
#ci
#cs
#d
#e
#F
#f
#false
#hash
#hashalw
#hasheq
#hasheqv
#i
#lang
#o
#px
#reader
#rx
#T
#t
#true
#x
#|
%
'
(
)
*
*list/c
+
+inf.0
+inf.f
+inf.t
+nan.0
+nan.f
+nan.t
+rv
,
,@
-
--
--addon
--addon
--back
--binary
--collects
--compile-any
--compiled
--config
--cross
--cross
--eval
--exe
--help
--lib
--load
--main
--make
--make
--name
--no-compiled
--no-compiled
--no-delay
--no-init-file
--no-jit
--no-lib
--no-user-path
--no-yield
--repl
--require
--require-script
--script
--search
--stdout
--syslog
--text-repl
--version
--warn
--wm-class
->
->*
->*m
->d
->dm
->extfl
->fl
->i
->m
-A
-A
-b
-background
-bg
-C
-C
-c
-c
-d
-display
-E
-e
-f
-fg
-fn
-font
-foreground
-G
-geometry
-h
-I
-i
-iconic
-inf.0
-inf.f
-inf.t
-J
-j
-K
-k
-L
-l
-M
-m
-N
-n
-name
-nan.0
-nan.f
-nan.t
-O
-p
-psn_
-q
-R
-r
-reverse
-rv
-S
-selectionTimeout
-singleInstance
-synchronous
-t
-title
-U
-u
-V
-v
-W
-X
-xnllanguage
-xrm
-Y
-y
-y
-Z
-z
.
...
".racketrc"
/
'3m
3m
:do-in
;
<
</c
<=
<=/c
=
=/c
==
=>
>
>/c
>=
>=/c
?
[
\
\"
\'
\digit8{1,3}
\newline
\\
\a
\b
\e
\f
\n
\r
\t
\udigit16{1,4}
\Udigit16{1,8}
\udigit16{4,4}\udigit16{4,4}
\v
\xdigit16{1,2}
]
_
_
`
abort
abort-current-continuation
abort/cc
'aborts
abs
absent
absolute-path?
abstract
'access-time-nanoseconds
'access-time-seconds
accessor
acos
add-between
add1
Additional Byte String Functions
Additional Control Operators
Additional Custom-Output Support
Additional Exception Functions
Additional Hash Table Functions
Additional Higher-Order Functions
Additional Keyword Functions
Additional List Functions and Synonyms
Additional Logging Functions
Additional Matching Forms
Additional Operating System Functions
Additional Promise Kinds
Additional provide Forms
Additional require Forms
Additional Sequence Constructors
Additional Sequence Operations
Additional String Functions
Additional Structure Utilities
Additional Symbol Functions
Additional Syntactic Constraints
Additional Vector Functions
'addon-dir
alarm-evt
all-defined-out
all-from-out
always-evt
and
and
and/c
andmap
angle
any
'any
'any-one
any/c
app
append
'append
append*
append-map
applicable structure
apply
'arch
argmax
argmin
Arithmetic
arithmetic-shift
arity-at-least
arity-at-least-value
arity-at-least?
arity-includes?
arity=?
asin
assert-unreachable
assf
assignment transformers
Assignment: set! and set!-values
assoc
association +list
assq
assv
assw
async-channel-get
async-channel-put
async-channel-put-evt
async-channel-try-get
async-channel/c
async-channel?
asynchronous channel
atan
atexit
Attaching Contracts to Values
augment
augment*
augment-final
augment-final*
augmenting
augride
augride*
authentic
automatic fields
"AUX"
available
banner
base environment
base +phase
Basic Pretty-Print Options
BC
BC Compilation Modes
begin
begin-encourage-inline
begin-for-syntax
begin0
between/c
'binary
binding
binding space
binds
Bitwise Operations
bitwise-and
bitwise-bit-field
bitwise-bit-set?
bitwise-ior
bitwise-not
bitwise-xor
Blame Objects
blame objects
blame-add-context
blame-add-missing-party
blame-context
blame-contract
blame-missing-party?
blame-negative
blame-original?
blame-positive
blame-replace-negative
blame-replaced-negative?
blame-source
blame-swap
blame-swapped?
blame-update
blame-value
blame?
block
'block
'block-count
block-device-type-bits
'block-size
Blocks: block
Boolean Aliases
boolean=?
boolean?
Booleans
booleans
bound
bound-identifier=?
box
box
box
box-cas!
box-immutable
box-immutable/c
box/c
box?
Boxes
break
break-enabled
break-evaluator
break-parameterization?
break-thread
Breaks
Buffered Asynchronous Channels
build-chaperone-contract-property
build-collapsible-contract-property
build-compound-type-name
build-contract-property
build-flat-contract-property
build-list
build-path
build-path/convention-type
build-string
build-vector
Building New Contract Combinators
Built-in Exception Types
bulk +bindings
Byte and String Input
Byte and String Output
byte converter
byte string
Byte String Comparisons
Byte String Constructors, Selectors, and Mutators
byte strings, parsing
byte strings, immutable
byte strings, concatenate
Byte Strings
byte-pregexp
byte-pregexp?
byte-ready?
byte-regexp
byte-regexp?
byte?
bytes
bytes
Bytes to Bytes Encoding Conversion
Bytes to/from Characters, Decoding and Encoding
bytes->immutable-bytes
bytes->list
bytes->path
bytes->path-element
bytes->string/latin-1
bytes->string/locale
bytes->string/utf-8
bytes-append
bytes-append*
bytes-close-converter
bytes-convert
bytes-convert-end
bytes-converter?
bytes-copy
bytes-copy!
bytes-environment-variable-name?
bytes-fill!
bytes-join
bytes-length
bytes-no-nuls?
bytes-open-converter
bytes-ref
bytes-set!
bytes-utf-8-index
bytes-utf-8-length
bytes-utf-8-ref
bytes<?
bytes=?
bytes>?
bytes?
caaaar
caaadr
caaar
caadar
caaddr
caadr
caar
'cache-dir
cadaar
cadadr
cadar
caddar
cadddr
caddr
cadr
call-by-value
call-in-continuation
call-in-nested-thread
call-in-sandbox-context
call-with-atomic-output-file
call-with-break-parameterization
call-with-composable-continuation
call-with-continuation-barrier
call-with-continuation-prompt
call-with-current-continuation
call-with-custodian-shutdown
call-with-deep-time-limit
call-with-default-reading-parameterization
call-with-escape-continuation
call-with-exception-handler
call-with-file-lock/timeout
call-with-immediate-continuation-mark
call-with-input-bytes
call-with-input-file
call-with-input-file*
call-with-input-string
call-with-killing-threads
call-with-limits
call-with-output-bytes
call-with-output-file
call-with-output-file*
call-with-output-string
call-with-parameterization
call-with-semaphore
call-with-semaphore/enable-break
call-with-trusted-sandbox-configuration
call-with-values
call/cc
call/comp
call/ec
call/prompt
'can-update
car
cartesian-product
case
case->
case->m
case-insensitive
case-lambda
case-sensitivity
catch
'cc
cdaaar
cdaadr
cdaar
cdadar
cdaddr
cdadr
cdar
cddaar
cddadr
cddar
cdddar
cddddr
cdddr
cddr
cdr
ceiling
'certify-mode
'cf
CGC
'cgc
Chaining Reader Language
'change-time-nanoseconds
'change-time-seconds
channel
channel-get
channel-put
channel-put-evt
channel-put-evt?
channel-try-get
channel/c
channel?
Channels
chaperone
Chaperone Constructors
chaperone contract property
Chaperone contracts
chaperone-async-channel
chaperone-box
chaperone-channel
chaperone-continuation-mark-key
chaperone-contract-property?
chaperone-contract?
chaperone-evt
chaperone-generics
chaperone-hash
chaperone-hash-set
chaperone-of?
chaperone-procedure
chaperone-procedure*
chaperone-prompt-tag
chaperone-struct
chaperone-struct-type
chaperone-struct-unsafe-undefined
chaperone-vector
chaperone-vector*
chaperone?
char->integer
char-alphabetic?
char-blank?
char-ci<=?
char-ci<?
char-ci=?
char-ci>=?
char-ci>?
char-downcase
char-foldcase
char-general-category
char-graphic?
char-in
char-iso-control?
char-lower-case?
char-numeric?
char-punctuation?
char-ready?
char-symbolic?
char-title-case?
char-titlecase
char-upcase
char-upper-case?
char-utf-8-length
char-whitespace?
char<=?
char<?
char=?
char>=?
char>?
char?
Character Comparisons
Character Conversions
character-device-type-bits
Characters
Characters
Characters and Scalar Values
check-duplicate-identifier
check-duplicates
check-not-unsafe-undefined
check-not-unsafe-undefined/assign
checked-procedure-check-and-extract
checked-struct-info?
'chez-scheme
chmod
choice-evt
class
class
class*
class->interface
class-field-accessor
class-field-mutator
class-info
class-seal
class-unseal
class/c
class/derived
class?
Classes and Objects
Classifications
cleanse
cleanse-path
'client
close-input-port
close-output-port
'cn
'co
Code Inspectors
code +inspectors
code point
coerce-chaperone-contract
coerce-chaperone-contracts
coerce-contract
coerce-contract/f
coerce-contracts
coerce-flat-contract
coerce-flat-contracts
collapsible contract property
Collapsible Contracts
Collapsible contracts
collapsible-contract-continuation-mark-key
collapsible-contract-property?
collapsible-contract?
collapsible-count-property
collapsible-count-property-count
collapsible-count-property-prev
collapsible-count-property?
collapsible-guard
collapsible-ho/c
collapsible-ho/c-latest-blame
collapsible-ho/c-latest-ctc
collapsible-ho/c-missing-party
collapsible-ho/c?
collapsible-leaf/c
collapsible-leaf/c-blame-list
collapsible-leaf/c-contract-list
collapsible-leaf/c-missing-party-list
collapsible-leaf/c-proj-list
collapsible-leaf/c?
collapsible-property
collapsible-property-c-c
collapsible-property-neg-party
collapsible-property-ref
collapsible-property?
collapsible-wrapper-property
collapsible-wrapper-property-checking-wrapper
collapsible-wrapper-property?
collect-garbage
Collection Links
Collection links files
Collection Paths and Parameters
Collection Search Configuration
collection-file-path
collection-path
collections
'collects-dir
column +locations
column numbers
"COM1"
"COM2"
"COM3"
"COM4"
"COM5"
"COM6"
"COM7"
"COM8"
"COM9"
combinations
combine-in
combine-out
combine-output
Command Line
command-line
Command-Line Parsing
committed
Compilation
compilation handler
Compilation Modes
compile
compile-allow-set!-undefined
compile-context-preservation-enabled
compile-enforce-module-constants
compile-linklet
compile-syntax
compile-target-machine?
compiled
Compiled Modules and References
compiled-expression-recompile
compiled-expression?
compiled-load +handler
compiled-module-expression?
'compiler-hint:cross-module-inline
'complete
'complete
complete
complete-path?
completion value
Complex Numbers
complex numbers
complex?
composable continuation
compose
compose1
compound-unit
compound-unit/infer
"CON"
Concurrency and Parallelism
cond
Conditionals: if, cond, and, and or
'config-dir
Configuration options
'configure-runtime
Configuring Default Handling
conjoin
conjugate
cons
cons
cons/c
cons/dc
cons?
const
Constructing Graphs: shared
constructor
context
continuation
continuation barrier
continuation frames
Continuation Frames and Marks
Continuation Marks
continuation marks
Continuation Marks: with-continuation-mark
continuation-mark-key/c
continuation-mark-key?
continuation-mark-set->context
continuation-mark-set->iterator
continuation-mark-set->list
continuation-mark-set->list*
continuation-mark-set-first
continuation-mark-set?
continuation-marks
continuation-prompt-available?
continuation-prompt-tag?
continuation?
Continuations
'continues
'continues
contract
Contract combinators
contract property
Contract Utilities
contract-continuation-mark-key
contract-custom-write-property-proc
contract-equivalent?
contract-exercise
contract-first-order
contract-first-order-okay-to-give-up?
contract-first-order-passes?
contract-first-order-try-less-hard
contract-late-neg-projection
contract-name
contract-out
contract-pos/neg-doubling
contract-proc
contract-projection
contract-property?
contract-random-generate
contract-random-generate-env?
contract-random-generate-fail
contract-random-generate-fail?
contract-random-generate-get-current-environment
contract-random-generate-stash
contract-random-generate/choose
contract-stronger?
contract-struct
contract-val-first-projection
contract?
contracted
Contracted Dictionaries
Contracts
Contracts
Contracts and Impersonators on Asynchronous Channels
Contracts as structs
control
Control Flow
control-at
control0
control0-at
Controlling and Inspecting Compilation
convert-relative-module-path
convert-stream
Converting Values to Strings
copy-directory/files
copy-file
copy-port
Copying and Updating Structures
Copying Streams
core form
correlated objects
correlated->datum
correlated-column
correlated-e
correlated-line
correlated-position
correlated-property
correlated-property-symbol-keys
correlated-source
correlated-span
correlated?
cos
cosh
count
count property
Counting Positions, Lines, and Columns
Creating and Touching Futures
Creating and Using Asynchronous Channels
Creating Classes
Creating formatted identifiers
Creating Interfaces
Creating Loggers
Creating Objects
Creating Ports
Creating Structure Types
Creating Threads
Creating Units
'creation-time-nanoseconds
'creation-time-seconds
'cross
cross-phase persistent
Cross-Phase Persistent Module Declarations
Cross-Phase Persistent Modules
crypto-random-bytes
Cryptographic Hashing
CS
'cs
'cs
CS Compilation Modes
cupto
current +custodian
current logger
current namespace
current plumber
current-blame-format
current-break-parameterization
current-code-inspector
current-command-line-arguments
current-command-line-arguments
current-compile
current-compile-realm
current-compile-target-machine
current-compiled-file-roots
current-continuation-marks
current-contract-region
current-custodian
current-date
current-directory
current-directory-for-user
current-drive
current-environment-variables
current-error-message-adjuster
current-error-port
current-eval
current-evt-pseudo-random-generator
current-force-delete-permissions
current-future
current-gc-milliseconds
current-get-interaction-evt
current-get-interaction-input-port
current-inexact-milliseconds
current-inexact-monotonic-milliseconds
current-input-port
current-inspector
current-interaction-info
current-library-collection-links
current-library-collection-paths
current-load
current-load-extension
current-load-relative-directory
current-load/use-compiled
current-locale
current-logger
current-memory-use
current-milliseconds
current-module-declare-name
current-module-declare-source
current-module-name-resolver
current-module-path-for-load
current-namespace
current-output-port
current-parameterization
current-plumber
current-prefix-in
current-prefix-out
current-preserved-thread-cell-values
current-print
current-process-milliseconds
current-prompt-read
current-pseudo-random-generator
current-read-interaction
current-reader-guard
current-readtable
current-recorded-disappeared-uses
current-require-module-path
current-seconds
current-security-guard
current-subprocess-custodian-mode
current-subprocess-keep-file-descriptors
current-syntax-context
current-thread
current-thread-group
current-thread-initial-stack-size
current-trace-notify
current-trace-print-args
current-trace-print-results
current-write-relative-directory
curry
curryr
custodian
custodian box
custodian-box-value
custodian-box?
custodian-limit-memory
custodian-managed-list
custodian-memory-accounting-available?
custodian-require-memory
custodian-shut-down?
custodian-shutdown-all
custodian?
Custodians
Custodians
Custom Hash Sets
Custom Hash Tables
Custom Ports
custom ports
custom-print-quotable-accessor
custom-print-quotable?
custom-write-accessor
custom-write?
Customized Unreachable Reporting
Customizing Evaluators
Data-structure Contracts
Datatypes
date
Date Utilities
date*
date*->seconds
date*-nanosecond
date*-time-zone-name
date*?
date->julian/scaliger
date->julian/scalinger
date->seconds
date->string
date-day
date-display-format
date-dst?
date-hour
date-minute
date-month
date-second
date-time-zone-offset
date-week-day
date-year
date-year-day
date?
datum
datum->correlated
datum->syntax
datum-intern-literal
Debugging
declared
Declaring Paths Needed at Run Time
Deep time
default binding space
default method
default-continuation-prompt-tag
default-language-readers
define
define-compound-unit
define-compound-unit/infer
define-contract-struct
define-custom-hash-types
define-custom-set-types
define-for-syntax
define-generics
define-inline
define-local-member-name
define-logger
define-match-expander
define-member-name
define-module-boundary-contract
define-namespace-anchor
define-opt/c
define-provide-syntax
define-rename-transformer-parameter
define-require-syntax
define-runtime-module-path
define-runtime-module-path-index
define-runtime-path
define-runtime-path-list
define-runtime-paths
define-sequence-syntax
define-serializable-class
define-serializable-class*
define-serializable-struct
define-serializable-struct/versions
define-signature
define-signature-form
define-splicing-for-clause-syntax
define-struct
define-struct/contract
define-struct/derived
define-syntax
define-syntax-parameter
define-syntax-rule
define-syntaxes
define-unit
define-unit-binding
define-unit-from-context
define-unit/contract
define-unit/new-import-export
define-unit/s
define-values
define-values-for-export
define-values-for-syntax
define-values/invoke-unit
define-values/invoke-unit/infer
define/augment
define/augment-final
define/augride
define/contract
define/final-prop
define/generic
define/match
define/overment
define/override
define/override-final
define/private
define/public
define/public-final
define/pubment
define/subexpression-pos-prop
define/with-syntax
Defining Structure Types: struct
Definitions: define, define-syntax, ...
degrees->radians
delay
delay/idle
delay/name
delay/strict
delay/sync
delay/thread
Delayed Evaluation
'delete
delete-directory
delete-directory/files
delete-file
delimited continuation
delimiters
Delimiters and Dispatch
denominator
depth marker
derived class
Derived Dictionary Methods
Deriving New Iteration Forms
deserialize
deserialize-module-guard
'desk-dir
Detecting Filesystem Changes
'device-id
'device-id-for-special-file
dict->list
dict-can-functional-set?
dict-can-remove-keys?
dict-clear
dict-clear!
dict-copy
dict-count
dict-empty?
dict-for-each
dict-has-key?
dict-implements/c
dict-implements?
dict-iter-contract
dict-iterate-first
dict-iterate-key
dict-iterate-next
dict-iterate-value
dict-key-contract
dict-keys
dict-map
dict-map/copy
dict-mutable?
dict-ref
dict-ref!
dict-remove
dict-remove!
dict-set
dict-set!
dict-set*
dict-set*!
dict-update
dict-update!
dict-value-contract
dict-values
dict?
Dictionaries
dictionary
Dictionary Predicates and Contracts
Dictionary Sequences
Directories
directory-exists?
directory-list
directory-type-bits
'disappeared-binding
'disappeared-use
Opening a null output port
discarded
disjoin
'dispatch-macro
Dispatch: case
display
display-lines
display-lines-to-file
display-to-file
displayln
division by inexact zero
'dll
do
Do Loops
'doc-dir
double-flonum?
drop
drop-common-prefix
drop-right
dropf
dropf-right
dump-memory-stats
dup-input-port
dup-output-port
dynamic extension
dynamic extent
Dynamic Module Access
dynamic->*
dynamic-enter!
dynamic-get-field
dynamic-object/c
dynamic-place
dynamic-place*
dynamic-require
dynamic-require-for-syntax
dynamic-rerequire
dynamic-send
dynamic-set-field!
dynamic-wind
effects
eighth
else
empty
empty-sequence
empty-stream
empty?
'enclosing-module-name
Encodings and Locales
engine
engine
engine-kill
engine-result
engine-run
engine?
Engines
enter!
Entering Modules
Environment and Runtime Information
environment variable set
Environment Variables
environment-variables-copy
environment-variables-names
environment-variables-ref
environment-variables-set!
environment-variables?
eof
eof-evt
eof-object?
ephemeron
ephemeron-value
ephemeron?
Ephemerons
eprintf
eq-hash-code
eq?
equal-always-hash-code
equal-always-secondary-hash-code
equal-always?
equal-always?/recur
equal-hash-code
equal-secondary-hash-code
equal<%>
equal?
equal?/recur
Equality
Equality and Hashing
eqv-hash-code
eqv?
error
'error
'error
error display handler
error escape handler
error message convention
Error Message Conventions
Error reporting
error syntax +conversion handler
error value conversion +handler
error-contract->adjusted-string
error-display-handler
error-escape-handler
error-message->adjusted-string
error-message-adjuster-key
error-print-context-length
error-print-source-location
error-print-width
error-syntax->string-handler
error-value->string-handler
escape continuation
eval
eval-jit-enabled
eval-linklet
eval-syntax
Evaluation and Compilation
evaluation handler
Evaluation Model
evaluation order
evaluator-alive?
even?
Events
evt/c
evt?
'exact
exact number
exact->inexact
exact-ceiling
exact-floor
exact-integer?
exact-nonnegative-integer?
exact-positive-integer?
exact-round
exact-truncate
exact?
except
except-in
except-out
exception handler
Exceptions
Exceptions
Exceptions
'exec-file
executable-yield-handler
'execute
'execute
'exists
exit
exit handler
Exit Status
exit-handler
Exiting
exn
exn->string
exn-continuation-marks
exn-message
exn:break
exn:break-continuation
exn:break:hang-up
exn:break:hang-up?
exn:break:terminate
exn:break:terminate?
exn:break?
exn:fail
exn:fail:contract
exn:fail:contract:arity
exn:fail:contract:arity?
exn:fail:contract:blame
exn:fail:contract:blame-object
exn:fail:contract:blame?
exn:fail:contract:continuation
exn:fail:contract:continuation?
exn:fail:contract:divide-by-zero
exn:fail:contract:divide-by-zero?
exn:fail:contract:non-fixnum-result
exn:fail:contract:non-fixnum-result?
exn:fail:contract:variable
exn:fail:contract:variable-id
exn:fail:contract:variable?
exn:fail:contract?
exn:fail:filesystem
exn:fail:filesystem:errno
exn:fail:filesystem:errno-errno
exn:fail:filesystem:errno?
exn:fail:filesystem:exists
exn:fail:filesystem:exists?
exn:fail:filesystem:missing-module
exn:fail:filesystem:missing-module-path
exn:fail:filesystem:missing-module?
exn:fail:filesystem:version
exn:fail:filesystem:version?
exn:fail:filesystem?
exn:fail:network
exn:fail:network:errno
exn:fail:network:errno-errno
exn:fail:network:errno?
exn:fail:network?
exn:fail:object
exn:fail:object?
exn:fail:out-of-memory
exn:fail:out-of-memory?
exn:fail:read
exn:fail:read-srclocs
exn:fail:read:eof
exn:fail:read:eof?
exn:fail:read:non-char
exn:fail:read:non-char?
exn:fail:read?
exn:fail:resource-resource
exn:fail:resource?
exn:fail:sandbox-terminated-reason
exn:fail:sandbox-terminated?
exn:fail:support
exn:fail:support?
exn:fail:syntax
exn:fail:syntax-exprs
exn:fail:syntax:missing-module
exn:fail:syntax:missing-module-path
exn:fail:syntax:missing-module?
exn:fail:syntax:unbound
exn:fail:syntax:unbound?
exn:fail:syntax?
exn:fail:unsupported
exn:fail:unsupported?
exn:fail:user
exn:fail:user?
exn:fail?
exn:misc:match?
exn:missing-module-accessor
exn:missing-module?
exn:srclocs-accessor
exn:srclocs?
exn?
exp
expand
expand
expand-export
expand-import
expand-once
expand-syntax
expand-syntax-once
expand-syntax-to-top-form
expand-to-top-form
expand-user-path
Expanding Top-Level Forms
Expansion
Expansion (Parsing)
Expansion Context
Expansion Steps
explode-path
export
export
export-local-id
export-mode
export-orig-stx
export-out-sym
export-protect?
export?
expression context
Expression Wrapper: #%expression
expt
extend
Extending match
Extending the Syntax of Signatures
extends
extension-load handler
externalizable<%>
externally lifted
extfl*
extfl+
extfl-
extfl->exact
extfl->exact-integer
extfl->floating-point-bytes
extfl->fx
extfl->inexact
extfl/
extfl<
extfl<=
extfl=
extfl>
extfl>=
extflabs
extflacos
extflasin
extflatan
extflceiling
extflcos
extflexp
extflexpt
extflfloor
extfllog
extflmax
extflmin
extflonum
Extflonum Arithmetic
Extflonum Byte Strings
Extflonum Constants
Extflonum Vectors
extflonum-available?
extflonum?
Extflonums
extflround
extflsin
extflsqrt
extfltan
extfltruncate
extflvector
extflvector
extflvector-copy
extflvector-length
extflvector-ref
extflvector-set!
extflvector?
Extra Constants and Functions
extract-struct-info
failure procedure
failure-cont
failure-result/c
fallback method
false
false/c
false?
fasl->s-exp
Fast-Load Serialization
fcontrol
field
Field and Method Access
field-bound?
field-names
Fields
Fields
fifo-type-bits
fifth
file
File Inclusion
file modification date and time
File Ports
file->bytes
file->bytes-lines
file->lines
file->list
file->string
file->value
file-exists?
'file-level
file-name-from-path
file-or-directory-identity
file-or-directory-modify-seconds
file-or-directory-permissions
file-or-directory-stat
file-or-directory-type
file-position
file-position*
file-size
file-stream +port
file-stream-buffer-mode
file-stream-port?
file-truncate
file-type-bits
filename-extension
Files
Filesystem
filesystem change event
filesystem-change-evt
filesystem-change-evt-cancel
filesystem-change-evt?
filesystem-root-list
filter
filter-map
filter-not
filter-read-input-port
filtered-in
filtered-out
finalizers
find-compiled-file-roots
find-executable-path
find-files
find-library-collection-links
find-library-collection-paths
find-relative-path
find-seconds
find-system-path
findf
first
first-or/c
fixnum
Fixnum Arithmetic
Fixnum Range
Fixnum Vectors
fixnum-for-every-system?
fixnum?
Fixnums
fl*
fl+
fl-
fl->exact-integer
fl->fx
fl/
fl<
fl<=
fl=
fl>
fl>=
flabs
flacos
flasin
flat contract property
Flat contracts
flat-contract
flat-contract-predicate
flat-contract-property?
flat-contract-with-explanation
flat-contract?
flat-murec-contract
flat-named-contract
flat-rec-contract
flatan
flatten
flceiling
flcos
flexp
flexpt
flfloor
flimag-part
fllog
flmax
flmin
floating-point-bytes->extfl
floating-point-bytes->real
Flonum Arithmetic
Flonum Vectors
flonum?
Flonums
flonums
floor
flrandom
flreal-part
flround
flsin
flsingle
flsqrt
fltan
fltruncate
flush callbacks
flush handle
flush-output
flvector
flvector
flvector-copy
flvector-length
flvector-ref
flvector-set!
flvector?
fold-files
foldl
foldr
for
for*
for*/and
for*/async
for*/extflvector
for*/first
for*/flvector
for*/fold
for*/fold/derived
for*/foldr
for*/foldr/derived
for*/fxvector
for*/hash
for*/hashalw
for*/hasheq
for*/hasheqv
for*/last
for*/list
for*/lists
for*/mutable-set
for*/mutable-setalw
for*/mutable-seteq
for*/mutable-seteqv
for*/or
for*/product
for*/set
for*/setalw
for*/seteq
for*/seteqv
for*/stream
for*/sum
for*/vector
for*/weak-set
for*/weak-setalw
for*/weak-seteq
for*/weak-seteqv
for-clause-syntax-protect
for-each
for-label
for-meta
for-space
for-syntax
for-template
for/and
for/async
for/extflvector
for/first
for/flvector
for/fold
for/fold/derived
for/foldr
for/foldr/derived
for/fxvector
for/hash
for/hashalw
for/hasheq
for/hasheqv
for/last
for/list
for/lists
for/mutable-set
for/mutable-setalw
for/mutable-seteq
for/mutable-seteqv
for/or
for/product
for/set
for/setalw
for/seteq
for/seteqv
for/stream
for/sum
for/vector
for/weak-set
for/weak-setalw
for/weak-seteq
for/weak-seteqv
'for:no-implicit-optimization
force
'force
form
format
format-id
format-symbol
fourth
fprintf
'framework
free-identifier=?
free-label-identifier=?
free-template-identifier=?
free-transformer-identifier=?
'fs-change
fsemaphore-count
fsemaphore-post
fsemaphore-try-wait?
fsemaphore-wait
fsemaphore?
Fully Expanded Programs
fully-expanded
function contract
Function Contracts
future
future
Future Performance Logging
future semaphore
Future Semaphores
future?
Futures
futures-enabled?
fx*
fx*/wraparound
fx+
fx+/wraparound
fx-
fx-/wraparound
fx->extfl
fx->fl
fx<
fx<=
fx=
fx>
fx>=
fxabs
fxand
fxior
fxlshift
fxlshift/wraparound
fxmax
fxmin
fxmodulo
fxnot
fxpopcount
fxpopcount16
fxpopcount32
fxquotient
fxremainder
fxrshift
fxvector
fxvector
fxvector-copy
fxvector-length
fxvector-ref
fxvector-set!
fxvector?
fxxor
Garbage Collection
Garbage Collection
garbage +collection
'gc
gc-info
gcd
gen:custom-write
gen:dict
gen:equal+hash
gen:equal-mode+hash
gen:set
gen:stream
generate-member-key
generate-temporaries
generate-temporary
Generating A Unit from Context
generator
generator
generator-state
generator?
Generators
generic
generic
Generic Dictionary Interface
generic instance
generic interface
Generic Interfaces
generic method
Generic Numerics
Generic Set Interface
generic-instance/c
generic-set?
generic?
Generics
gensym
get-error-output
get-field
get-impersonator-prop:collapsible
get-output
get-output-bytes
get-output-string
get-preference
get-uncovered-expressions
get-user-custodian
get/build-collapsible-late-neg-projection
get/build-late-neg-projection
get/build-val-first-projection
getenv
gethostname
getpid
global port print handler
global-port-print-handler
gracket
GRacket.app
GRacket.exe
greatest common divisor
group-by
group-execute-bit
'group-id
group-permission-bits
group-read-bit
group-write-bit
guard-evt
Guarded Evaluation: when and unless
gui?
handle-evt
handle-evt?
Handling Exceptions
'hardlink-count
has-blame?
has-contract?
has-impersonator-prop:collapsible?
hash
hash
hash code
hash placeholders
hash set
Hash Sets
hash table
Hash Tables
hash->linklet-bundle
hash->linklet-directory
hash->list
hash-clear
hash-clear!
hash-copy
hash-copy-clear
hash-count
hash-empty?
hash-ephemeron?
hash-eq?
hash-equal-always?
hash-equal?
hash-eqv?
hash-for-each
hash-has-key?
hash-intersect
hash-iterate-first
hash-iterate-key
hash-iterate-key+value
hash-iterate-next
hash-iterate-pair
hash-iterate-value
hash-keys
hash-keys-subset?
hash-map
hash-map/copy
hash-placeholder?
hash-ref
hash-ref!
hash-ref-key
hash-remove
hash-remove!
hash-set
hash-set!
hash-set*
hash-set*!
hash-strong?
hash-table
hash-union
hash-union!
hash-update
hash-update!
hash-values
hash-weak?
hash/c
hash/dc
hash?
hashalw
hasheq
hasheqv
help
here strings
heredoc
HOME
'home-dir
HOMEDRIVE
HOMEPATH
Honest Custom Equality
'host-collects-dir
'host-config-dir
identifier
identifier-binding
identifier-binding-portal-syntax
identifier-binding-symbol
identifier-distinct-binding
identifier-label-binding
identifier-prune-lexical-context
identifier-prune-to-source-module
identifier-remove-from-definition-context
identifier-template-binding
identifier-transformer-binding
identifier?
Identifiers, Binding, and Scopes
identity
IEEE floating-point numbers
if
if/c
imag-part
Immutable Cyclic Data
immutable?
impersonate-async-channel
impersonate-box
impersonate-channel
impersonate-continuation-mark-key
impersonate-generics
impersonate-hash
impersonate-hash-set
impersonate-procedure
impersonate-procedure*
impersonate-prompt-tag
impersonate-struct
impersonate-vector
impersonate-vector*
impersonator
Impersonator Constructors
Impersonator contracts
Impersonator Properties
impersonator properties
impersonator property accessor
impersonator property descriptor
impersonator property predicate
impersonator-contract?
impersonator-ephemeron
impersonator-of?
impersonator-prop:application-mark
impersonator-prop:blame
impersonator-prop:collapsible
impersonator-prop:contracted
impersonator-property-accessor-procedure?
impersonator-property?
impersonator?
Impersonators and Chaperones
implementation?
implementation?/c
Implementations
implemented generic method
Implementing Equality for Custom Types
implements
implicit-made-explicit properties
implies
import
import
import-local-id
import-mode
import-orig-mode
import-orig-stx
import-req-mode
import-source
import-source-mod-path-stx
import-source-mode
import-source?
import-src-mod-path
import-src-sym
import?
Importing and Exporting: require and provide
Importing Modules Lazily: lazy-require
in-bytes
in-bytes-lines
in-combinations
in-cycle
in-dict
in-dict-keys
in-dict-pairs
in-dict-values
in-directory
in-ephemeron-hash
in-ephemeron-hash-keys
in-ephemeron-hash-pairs
in-ephemeron-hash-values
in-extflvector
in-flvector
in-fxvector
in-generator
in-hash
in-hash-keys
in-hash-pairs
in-hash-values
in-immutable-hash
in-immutable-hash-keys
in-immutable-hash-pairs
in-immutable-hash-values
in-immutable-set
in-inclusive-range
in-indexed
in-input-port-bytes
in-input-port-chars
in-lines
in-list
in-mlist
in-mutable-hash
in-mutable-hash-keys
in-mutable-hash-pairs
in-mutable-hash-values
in-mutable-set
in-naturals
in-parallel
in-permutations
in-port
in-powerset
in-producer
in-range
in-rearrangements
in-sequences
in-set
in-slice
in-stream
in-string
in-syntax
in-value
in-values*-sequence
in-values-sequence
in-vector
in-weak-hash
in-weak-hash-keys
in-weak-hash-pairs
in-weak-hash-values
in-weak-set
include
include-at/relative-to
include-at/relative-to/reader
include/reader
inclusive-range
index-of
index-where
indexes-of
indexes-where
inexact number
inexact->exact
inexact-real?
inexact?
'infer
Inferred Linking
Inferred Value Names
'inferred-name
infinite-generator
infinite?
infinity
infix
Information on Expanded Modules
inherit
inherit-field
inherit/inner
inherit/super
inheritance
Inherited and Superclass Methods
init
Init Libraries
init-depend
'init-dir
init-field
'init-file
init-rest
Initialization
Initialization Variables
initiate
inner
inode
inode
'inode
inode
Input and Output
input port
input ports, pattern matching
input-port-append
input-port?
inside-edge scope
inspect
Inspecting Compiler Passes
inspector
inspector-superior?
inspector?
instance-data
instance-describe-variable!
instance-name
instance-set-variable-value!
instance-unset-variable!
instance-variable-names
instance-variable-value
instance?
instanceof/c
instantiate
instantiate-linklet
instantiates
instantiation
integer->char
integer->integer-bytes
integer-bytes->integer
integer-in
integer-length
integer-sqrt
integer-sqrt/remainder
integer?
integers
Interacting with Evaluators
Interaction Configuration
interaction event +handler
interaction port handler
Interaction Wrapper: #%top-interaction
Interactive Help
Interactive Module Loading
interface
interface
interface*
interface->method-names
interface-extension?
interface?
Internal and External Names
Internal Definitions
internal-definition context
Internal-Definition Limiting: #%stratified-body
internal-definition-context-add-scopes
internal-definition-context-apply
internal-definition-context-binding-identifiers
internal-definition-context-introduce
internal-definition-context-seal
internal-definition-context-splice-binding-identifier
internal-definition-context?
interned
Introducing Bindings
invariant-assertion
invoke-unit
invoke-unit/infer
invoked
Invoking Units
IP_MULTICAST_LOOP
IP_MULTICAST_TTL
IP_TTL
is-a?
is-a?/c
Iteration and Comprehension Forms
iteration pattern variable
Iterations and Comprehensions: for, for/list, ...
iterator
JIT
julian/scaliger->string
julian/scalinger->string
Kernel Forms and Functions
keyword
keyword->immutable-string
keyword->string
keyword-apply
keyword-apply/dict
Keyword-Argument Conversion Introspection
keyword<?
keyword?
Keywords
Keywords and Arity
kill-evaluator
kill-thread
label phase level
lambda
LANG
Language Model
Language Run-Time Configuration
last
last-pair
late neg projection
lazy
Lazy Data-structure Contracts
lazy-require
lazy-require-syntax
LC_ALL
LC_TYPE
lcm
least common multiple
Legacy Contracts
legacy-match-expander?
length
let
let*
let*-values
let-syntax
let-syntaxes
let-values
let/cc
let/ec
letrec
letrec-syntax
letrec-syntaxes
letrec-syntaxes+values
letrec-values
'lexical
lexical information
lexical scoping
lib
liberal expansion
liberal-define-context?
Libraries and Collections
library
Library Extensions
'line
line locations
line numbers
Line-Output Hook
'linefeed
link
'link
link-exists?
linked
Linking Units and Creating Compound Units
linklet
linklet bundle
linklet directory
linklet instance
linklet-body-reserved-symbol?
linklet-bundle->hash
linklet-bundle?
linklet-directory->hash
linklet-directory?
linklet-export-variables
linklet-import-variables
linklet?
Linklets and the Core Compiler
list
list
list
List Filtering
List Iteration
List Operations
List Searching
list*
list*
list*of
list->bytes
list->mutable-set
list->mutable-setalw
list->mutable-seteq
list->mutable-seteqv
list->set
list->setalw
list->seteq
list->seteqv
list->string
list->vector
list->weak-set
list->weak-setalw
list->weak-seteq
list->weak-seteqv
list-contract?
list-no-order
list-prefix?
list-ref
list-rest
list-set
list-tail
list-update
list/c
list?
listen-port-number?
listof
Literals: quote and #%datum
'll
'lm
'lo
load
load handler
load-extension
load-on-demand-enabled
load-relative
load-relative-extension
load/cd
load/use-compiled
Loading and Reloading Modules
local
Local Binding Context
local binding context
Local Binding with Splicing Body
Local Binding: let, let*, letrec, ...
local +bindings
Local Definitions: local
local variable
local-expand
local-expand/capture-lifts
local-require
local-transformer-expand
local-transformer-expand/capture-lifts
locale
Locale-Specific String Operations
locale-string-encoding
Locating Paths
location
Locations: #%variable-reference
log
log receiver
log-all-levels
log-debug
log-error
log-fatal
log-info
log-level-evt
log-level/c
log-level?
log-max-level
log-message
log-receiver?
log-warning
logger
logger-name
logger?
Logging
Logging Events
logical operators
LOGNAME
'low-latency
Low-level Contract Boundaries
"LPT1"
"LPT2"
"LPT3"
"LPT4"
"LPT5"
"LPT6"
"LPT7"
"LPT8"
"LPT9"
'lt
'lu
'machine
Machine Memory Order
'macosx
macro
Macro-Introduced Bindings
macro-introduction scope
Macros
magnitude
make-arity-at-least
make-async-channel
make-base-empty-namespace
make-base-namespace
make-bytes
make-channel
make-chaperone-contract
make-constructor-style-printer
make-continuation-mark-key
make-continuation-prompt-tag
make-contract
make-custodian
make-custodian-box
make-custom-hash
make-custom-hash-types
make-custom-set-types
make-date
make-date*
make-derived-parameter
make-deserialize-info
make-directory
make-directory*
make-do-sequence
make-empty-namespace
make-environment-variables
make-ephemeron
make-ephemeron-hash
make-ephemeron-hashalw
make-ephemeron-hasheq
make-ephemeron-hasheqv
make-evaluator
make-exn
make-exn:break
make-exn:break:hang-up
make-exn:break:terminate
make-exn:fail
make-exn:fail:contract
make-exn:fail:contract:arity
make-exn:fail:contract:blame
make-exn:fail:contract:continuation
make-exn:fail:contract:divide-by-zero
make-exn:fail:contract:non-fixnum-result
make-exn:fail:contract:variable
make-exn:fail:filesystem
make-exn:fail:filesystem:errno
make-exn:fail:filesystem:exists
make-exn:fail:filesystem:missing-module
make-exn:fail:filesystem:version
make-exn:fail:network
make-exn:fail:network:errno
make-exn:fail:object
make-exn:fail:out-of-memory
make-exn:fail:read
make-exn:fail:read:eof
make-exn:fail:read:non-char
make-exn:fail:syntax
make-exn:fail:syntax:missing-module
make-exn:fail:syntax:unbound
make-exn:fail:unsupported
make-exn:fail:user
make-export
make-extflvector
make-file-or-directory-link
make-flat-contract
make-flrectangular
make-flvector
make-fsemaphore
make-fxvector
make-generic
make-generic-struct-type-property
make-handle-get-preference-locked
make-hash
make-hash-placeholder
make-hashalw
make-hashalw-placeholder
make-hasheq
make-hasheq-placeholder
make-hasheqv
make-hasheqv-placeholder
make-immutable-custom-hash
make-immutable-hash
make-immutable-hashalw
make-immutable-hasheq
make-immutable-hasheqv
make-impersonator-property
make-import
make-import-source
make-input-port
make-input-port/read-to-peek
make-inspector
make-instance
make-interned-syntax-introducer
make-keyword-procedure
make-known-char-range-list
make-limited-input-port
make-list
make-lock-file-name
make-log-receiver
make-logger
make-mixin-contract
make-module-evaluator
make-none/c
make-object
make-output-port
make-parameter
make-parameter-rename-transformer
make-parent-directory*
make-phantom-bytes
make-pipe
make-pipe-with-specials
make-placeholder
make-plumber
make-polar
make-portal-syntax
make-prefab-struct
make-proj-contract
make-provide-pre-transformer
make-provide-transformer
make-pseudo-random-generator
make-reader-graph
make-readtable
make-rectangular
make-rename-transformer
make-require-transformer
make-resolved-module-path
make-security-guard
make-semaphore
make-serialize-info
make-set!-transformer
make-shared-bytes
make-shared-extflvector
make-shared-flvector
make-shared-fxvector
make-sibling-inspector
make-special-comment
make-srcloc
make-string
make-struct-field-accessor
make-struct-field-mutator
make-struct-info
make-struct-type
make-struct-type-property
make-struct-type-property/generic
make-syntax-delta-introducer
make-syntax-introducer
make-temporary-directory
make-temporary-directory*
make-temporary-file
make-temporary-file*
make-tentative-pretty-print-output-port
make-thread-cell
make-thread-group
make-vector
make-weak-box
make-weak-custom-hash
make-weak-hash
make-weak-hashalw
make-weak-hasheq
make-weak-hasheqv
make-will-executor
Managing Ports
Manipulating Paths
map
match
match expander
match*
match*/derived
match-define
match-define-values
match-equality-test
match-expander?
match-lambda
match-lambda*
match-lambda**
match-let
match-let*
match-let*-values
match-let-values
match-letrec
match-letrec-values
match/derived
match/values
matching-identifiers-in
matching-identifiers-out
max
'mc
mcar
mcdr
mcons
mcons
'me
member
member-name-key
member-name-key-hash-code
member-name-key=?
member-name-key?
memf
Memory Management
memory-order-acquire
memory-order-release
memq
memv
memw
merge
merge-input
metavariables
Method Definitions
'method-arity-error
'method-arity-error
method-in-interface?
Methods
Methods
min
Miscellaneous
Miscellaneous utilities
mixin
mixin
mixin-contract
Mixins
'mn
'mode
'modify-time-nanoseconds
'modify-time-seconds
module
module binding
Module Cache
module context
Module Expansion, Phases, and Visits
module name +resolver
Module Names and Loading
module path
module path index
module path resolver
Module Redeclarations
module registry
module*
module+
module->exports
module->imports
module->indirect-exports
module->language-info
module->namespace
module->realm
module-begin context
'module-body-context
'module-body-context-simple?
'module-body-inside-context
module-cache-clear!
module-compiled-cross-phase-persistent?
module-compiled-exports
module-compiled-imports
module-compiled-indirect-exports
module-compiled-language-info
module-compiled-name
module-compiled-realm
module-compiled-submodules
module-declared?
'module-language
'module-language
module-level +variable
module-path-index-join
module-path-index-resolve
module-path-index-split
module-path-index-submodule
module-path-index?
module-path?
module-predefined?
module-provide-protected?
modules, re-define
modules, imports
modules, exports
modules
Modules and Module-Level Variables
Modules: module, module*, ...
modulo
More File and Directory Utilities
More Path Utilities
More Port Constructors, Procedures, and Events
most-negative-fixnum
most-positive-fixnum
mpair?
multi-in
Multiple Return Values
Multiple Values
multiple values
'must-truncate
mutable list
mutable pair
Mutable Pair Constructors and Selectors
Mutable Pairs and Lists
mutable-set
mutable-setalw
mutable-seteq
mutable-seteqv
mutator
nack-guard-evt
named let
namespace
namespace-anchor->empty-namespace
namespace-anchor->namespace
namespace-anchor?
namespace-attach-module
namespace-attach-module-declaration
namespace-base-phase
namespace-call-with-registry-lock
namespace-mapped-symbols
namespace-module-identifier
namespace-module-registry
namespace-require
namespace-require/constant
namespace-require/copy
namespace-require/expansion-time
namespace-set-variable-value!
namespace-symbol->identifier
namespace-syntax-introduce
namespace-undefine-variable!
namespace-unprotect-module
namespace-variable-value
namespace?
Namespaces
Namespaces
nan?
nand
natural-number/c
natural?
'nd
negate
negative-integer?
negative?
Nested Contract Boundaries
Networking
never-evt
new
new-prompt
new-∀/c
new-∃/c
newline
ninth
'nl
'no
'nominal-id
non-empty-listof
non-empty-string?
'non-terminating-macro
'non-terminating-macro
'none
none/c
nonnegative-integer?
nonpositive-integer?
nor
normal-case-path
normalize-arity
normalize-path
normalized-arity?
not
not
not-a-number
'not-free-identifier=?
'not-provide-all-defined
not/c
Notation for Documentation
Notation for Function Documentation
Notation for Module Documentation
Notation for Other Documentation
Notation for Parameter Documentation
Notation for Structure Type Documentation
Notation for Syntactic Form Documentation
"NUL"
null
null?
Number Comparison
Number Types
Number–String Conversions
number->string
number?
numbers, parsing
numbers, machine representations
numbers, little-endian
numbers, floating-point
numbers, converting
numbers, big-endian
Numbers
numbers
numerator
Object and Class Contracts
Object Equality and Hashing
Object Identity and Comparisons
Object Printing
Object Serialization
object%
Object, Class, and Interface Utilities
object->vector
object-contract
object-info
object-interface
object-method-arity-includes?
object-name
object-or-false=?
object/c
object=-hash-code
object=?
object?
objects
Objects and Imperative Update
Obligation Information in Check Syntax
odd?
one-of/c
only
only-in
only-meta-in
only-space-in
open
open-input-bytes
open-input-file
open-input-output-file
open-input-string
open-output-bytes
open-output-file
open-output-nowhere
open-output-string
Operating System
opt/c
or
or
or/c
order-of-magnitude
'orig-dir
'origin
ormap
'os
'os*
Other Randomness Utilities
other-execute-bit
other-permission-bits
other-read-bit
other-write-bit
output port
output-port?
outside-edge +scope
overment
overment*
override
override*
override-final
override-final*
overriding
packages
pair
Pair Accessor Shorthands
Pair Constructors and Selectors
pair?
Pairs and Lists
parameter procedure
parameter-procedure=?
parameter/c
parameter?
parameterization
parameterization?
parameterize
parameterize*
parameterize-break
Parameters
Parameters
Parameters
Parametric Contracts
parametric->/c
'paren-shape
parent +internal-definition context
parse
parse-command-line
parsed
Partial Expansion
partial expansion
partition
Passing keyword arguments in dictionaries
patched
PATH
path
path element
path +or string
path->bytes
path->complete-path
path->directory-path
path->string
path-add-extension
path-add-suffix
path-convention-type
path-element->bytes
path-element->string
path-element?
path-for-some-system?
path-get-extension
path-has-extension?
path-list-string->path-list
path-only
path-replace-extension
path-replace-suffix
path-string?
path-up
path<?
path?
pathlist-closure
Paths
Pattern Matching
pattern matching
pattern variable
Pattern variables
Pattern-Based Syntax Matching
'pc
'pd
'pe
peek-byte
peek-byte-or-special
peek-bytes
peek-bytes!
peek-bytes!-evt
peek-bytes-avail!
peek-bytes-avail!*
peek-bytes-avail!-evt
peek-bytes-avail!/enable-break
peek-bytes-evt
peek-char
peek-char-or-special
peek-string
peek-string!
peek-string!-evt
peek-string-evt
peeked
peeking-input-port
Per-Symbol Special Printing
Performance Hints: begin-encourage-inline
permutations
'pf
phantom byte string
Phantom Byte Strings
phantom-bytes?
Phase and Space Utilities
phase level
phase+space
phase+space+
phase+space-phase
phase+space-shift+
phase+space-shift?
phase+space-space
phase+space?
phase?
Phases
phases
pi
'pi
pi.f
pi.t
pipe
pipe-content-length
Pipes
place
place
place channels
place descriptor
place locations
place*
place-break
place-channel
place-channel-get
place-channel-put
place-channel-put/get
place-channel?
place-dead-evt
place-enabled?
place-kill
place-location?
place-message-allowed?
place-wait
place/context
place?
placeholder-get
placeholder-set!
placeholder?
placeholders
Places
Places Logging
planet
PLT_COMPILE_ANY
PLT_COMPILED_FILE_CHECK
PLT_CS_COMPILE_LIMIT
PLT_CS_DEBUG
PLT_CS_INTERP
PLT_CS_JIT
PLT_CS_MACH
PLT_DELAY_FROM_ZO
PLT_EXPANDER_TIMES
PLT_INCREMENTAL_GC
PLT_INCREMENTAL_GC
PLT_LINKLET_SHOW
PLT_LINKLET_SHOW_ASSEMBLY
PLT_LINKLET_SHOW_CP0
PLT_LINKLET_SHOW_GENSYM
PLT_LINKLET_SHOW_JIT_DEMAND
PLT_LINKLET_SHOW_KNOWN
PLT_LINKLET_SHOW_LAMBDA
PLT_LINKLET_SHOW_PASSES
PLT_LINKLET_SHOW_PATHS
PLT_LINKLET_SHOW_POST_INTERP
PLT_LINKLET_SHOW_POST_LAMBDA
PLT_LINKLET_SHOW_PRE_JIT
PLT_LINKLET_TIMES
PLT_VALIDATE_COMPILE
PLT_VALIDATE_LOAD
PLT_ZO_PATH
PLTADDONDIR
PLTCOLLECTS
PLTCOMPILEDROOTS
PLTCONFIGDIR
PLTDISABLEGC
PLTNOMZJIT
PLTSTDERR
PLTSTDOUT
PLTSYSLOG
PLTUSERHOME
plumber
plumber-add-flush!
plumber-flush-all
plumber-flush-handle-remove!
plumber-flush-handle?
plumber?
Plumbers
'po
poll
poll-guard-evt
Port Buffers and Positions
port display +handler
Port Events
port positions
port print handler
port read handler
Port String and List Conversions
port write handler
port->bytes
port->bytes-lines
port->lines
port->list
port->string
port-closed-evt
port-closed?
port-commit-peeked
port-count-lines!
port-count-lines-enabled
port-counts-lines?
port-display-handler
port-file-identity
port-file-unlock
port-next-location
port-number?
port-print-handler
port-progress-evt
port-provides-progress-evts?
port-read-handler
port-try-file-lock?
port-waiting-peer?
port-write-handler
port-writes-atomic?
port-writes-special?
port?
portal syntax
Portal Syntax Bindings
portal-syntax-content
portal-syntax?
ports, flushing
Ports
Ports
position
positive-integer?
positive?
Powers and Roots
powerset
pre-expand-export
predicate
predicate/c
'pref-dir
'pref-file
prefab
prefab-key->struct-type
prefab-key?
prefab-struct-key
prefab-struct-type-key+field-count
preferences-lock-file-mode
prefix
prefix-in
prefix-out
pregexp
pregexp
pregexp?
preserved
preserved
Pretty Printing
pretty-display
pretty-format
pretty-print
pretty-print-.-symbol-without-bars
pretty-print-abbreviate-read-macros
pretty-print-columns
pretty-print-current-style-table
pretty-print-depth
pretty-print-exact-as-decimal
pretty-print-extend-style-table
pretty-print-handler
pretty-print-newline
pretty-print-post-print-hook
pretty-print-pre-print-hook
pretty-print-print-hook
pretty-print-print-line
pretty-print-remap-stylable
pretty-print-show-inexactness
pretty-print-size-hook
pretty-print-style-table?
pretty-printing
pretty-write
Primitive Dictionary Methods
primitive procedure
primitive-closure?
primitive-result-arity
primitive?
print
print handler
print-as-expression
print-boolean-long-form
print-box
print-graph
print-hash-table
print-mpair-curly-braces
print-pair-curly-braces
print-reader-abbreviations
print-struct
print-syntax-width
print-unreadable
print-value-columns
print-vector-length
printable/c
printable<%>
Printer Extension
printf
Printing Booleans
Printing Boxes
Printing Characters
Printing Compiled Code
Printing Extflonums
Printing Hash Tables
Printing Keywords
Printing Numbers
Printing Pairs and Lists
Printing Paths
Printing Regular Expressions
Printing Strings
Printing Structures
Printing Symbols
Printing Unreadable Values
Printing Vectors
println
private
private*
"PRN"
Procedure Applications and #%app
Procedure Applications and Local Variables
Procedure Expressions: lambda and case-lambda
procedure->method
procedure-arity
procedure-arity-includes/c
procedure-arity-includes?
procedure-arity-mask
procedure-arity?
procedure-closure-contents-eq?
procedure-extract-target
procedure-impersonator*?
procedure-keywords
procedure-realm
procedure-reduce-arity
procedure-reduce-arity-mask
procedure-reduce-keyword-arity
procedure-reduce-keyword-arity-mask
procedure-rename
procedure-result-arity
procedure-specialize
procedure-struct-type?
procedure?
Procedures
process
process*
process*/ports
process/ports
Processes
processor-count
processor-count
progress-evt?
promise
promise-forced?
promise-running?
promise/c
promise/name?
promise?
prompt
prompt
prompt read handler
prompt tag
prompt-at
prompt-tag/c
prompt0
prompt0-at
Prompts, Delimited Continuations, and Barriers
prop:arity-string
prop:authentic
prop:blame
prop:chaperone-contract
prop:chaperone-unsafe-undefined
prop:checked-procedure
prop:collapsible-contract
prop:contract
prop:contracted
prop:custom-print-quotable
prop:custom-write
prop:dict
prop:dict/contract
prop:equal+hash
prop:evt
prop:exn:missing-module
prop:exn:srclocs
prop:expansion-contexts
prop:flat-contract
prop:impersonator-of
prop:input-port
prop:legacy-match-expander
prop:liberal-define-context
prop:match-expander
prop:object-name
prop:output-port
prop:place-location
prop:procedure
prop:provide-pre-transformer
prop:provide-transformer
prop:rename-transformer
prop:require-transformer
prop:sealed
prop:sequence
prop:serializable
prop:set!-transformer
prop:stream
prop:struct-auto-info
prop:struct-field-info
prop:struct-info
proper-subset?
property accessor
property predicate
property/c
protect-out
'protected
protected
provide
provide Macros
provide +pre-transformer
provide transformer
provide Transformers
provide-pre-transformer?
provide-signature-elements
provide-transformer?
provide/contract
'provide/contract-original-contract
proxy design pattern
'ps
pseudo-random-generator->vector
pseudo-random-generator-vector?
pseudo-random-generator?
public
public*
public-final
public-final*
pubment
pubment*
put-input
put-preferences
putenv
PWD
quasiquote
quasiquote
Quasiquoting: quasiquote, unquote, and unquote-splicing
quasisyntax
quasisyntax/loc
quotable
quote
quote-syntax
quote-syntax/prune
quotient
quotient/remainder
quoting +depth
racket
'racket
racket
Racket.exe
racket/async-channel
racket/base
racket/block
racket/bool
racket/bytes
racket/class
racket/cmdline
racket/contract
racket/contract/base
racket/contract/base
racket/contract/collapsible
racket/contract/combinator
racket/contract/parametric
racket/contract/region
racket/contract:contract
racket/contract:contract-on-boundary
racket/contract:internal-contract
racket/contract:negative-position
racket/contract:positive-position
racket/control
racket/date
racket/dict
racket/engine
racket/enter
racket/exn
racket/extflonum
racket/fasl
racket/file
racket/fixnum
racket/flonum
racket/format
racket/function
racket/future
racket/generator
racket/generic
racket/hash
racket/help
racket/include
racket/init
racket/interaction-info
racket/interactive
racket/kernel
racket/kernel/init
racket/keyword
racket/keyword-transform
racket/language-info
racket/lazy-require
racket/linklet
racket/list
racket/load
racket/local
racket/logging
racket/match
racket/math
racket/os
racket/path
racket/performance-hint
racket/phase+space
racket/place
racket/place/dynamic
racket/port
racket/pretty
racket/promise
racket/provide
racket/provide-syntax
racket/provide-transform
racket/random
racket/repl
racket/require
racket/require-syntax
racket/require-transform
racket/rerequire
racket/runtime-config
racket/runtime-path
racket/sandbox
racket/sequence
racket/serialize
racket/set
racket/shared
racket/signature
racket/splicing
racket/stream
racket/string
racket/struct
racket/struct-info
racket/stxparam
racket/stxparam-exptime
racket/surrogate
racket/symbol
racket/syntax
racket/syntax-srcloc
racket/system
racket/tcp
racket/trace
racket/trait
racket/udp
racket/undefined
racket/unit
racket/unit-exptime
racket/unreachable
racket/unsafe/ops
racket/unsafe/undefined
racket/vector
"racketrc.rktl"
"racketrc.rktl"
radians->degrees
raise
raise-argument-error
raise-argument-error*
raise-arguments-error
raise-arguments-error*
raise-arity-error
raise-arity-error*
raise-arity-mask-error
raise-arity-mask-error*
raise-blame-error
raise-contract-error
raise-mismatch-error
raise-range-error
raise-range-error*
raise-result-arity-error
raise-result-arity-error*
raise-result-error
raise-result-error*
raise-support-error
raise-syntax-error
raise-type-error
raise-user-error
Raising Exceptions
random
Random generation
Random Numbers
random-ref
random-sample
random-seed
range
rational numbers
rational?
rationalize
reachable
read
'read
'read
read
read interaction +handler
read-accept-bar-quote
read-accept-box
read-accept-compiled
read-accept-dot
read-accept-graph
read-accept-infix-dot
read-accept-lang
read-accept-quasiquote
read-accept-reader
read-byte
read-byte-or-special
read-bytes
read-bytes!
read-bytes!-evt
read-bytes-avail!
read-bytes-avail!*
read-bytes-avail!-evt
read-bytes-avail!/enable-break
read-bytes-evt
read-bytes-line
read-bytes-line-evt
read-case-sensitive
read-cdot
read-char
read-char-or-special
read-curly-brace-as-paren
read-curly-brace-with-tag
read-decimal-as-inexact
read-eval-print-loop
read-installation-configuration-table
read-language
read-line
read-line-evt
read-on-demand-source
read-single-flonum
read-square-bracket-as-paren
read-square-bracket-with-tag
read-string
read-string!
read-string!-evt
read-string-evt
read-syntax
read-syntax-accept-graph
read-syntax/recursive
read/recursive
reader
Reader Extension
reader +extension procedures
reader language
reader macro
Reader-Extension Procedures
Reading
Reading Booleans
Reading Boxes
Reading Characters
Reading Comments
Reading Extflonums
Reading Graph Structure
Reading Hash Tables
Reading Keywords
Reading Numbers
Reading Pairs and Lists
Reading Quotes
Reading Regular Expressions
Reading Strings
Reading Structures
Reading Symbols
Reading Vectors
Reading via an Extension
Reading with C-style Infix-Dot Notation
readtable
readtable-mapping
readtable?
Readtables
ready for +synchronization
real numbers
real->decimal-string
real->double-flonum
real->extfl
real->floating-point-bytes
real->single-flonum
real-in
real-part
real?
realm
Realms and Error Message Adjusters
rearrangements
Receiving Logged Events
recompile-linklet
recontract-out
record-disappeared-uses
Recording disappeared uses
recursive-contract
RED
redex
redirect-generics
reencode-input-port
reencode-output-port
reference
Reflecting on Primitives
Reflection and Security
regexp
regexp
Regexp Constructors
Regexp Matching
Regexp Splitting
Regexp Substitution
Regexp Syntax
regexp value
regexp-match
regexp-match*
regexp-match-evt
regexp-match-exact?
regexp-match-peek
regexp-match-peek-immediate
regexp-match-peek-positions
regexp-match-peek-positions*
regexp-match-peek-positions-immediate
regexp-match-peek-positions-immediate/end
regexp-match-peek-positions/end
regexp-match-positions
regexp-match-positions*
regexp-match-positions/end
regexp-match/end
regexp-match?
regexp-max-lookbehind
regexp-quote
regexp-replace
regexp-replace*
regexp-replace-quote
regexp-replaces
regexp-split
regexp-try-match
regexp?
regexps
Regular Expressions
Regular expressions
regular-file-type-bits
REL
'relative
relative-in
relative-path?
relocate-input-port
relocate-output-port
remainder
remf
remf*
remove
remove*
remove-duplicates
remq
remq*
remv
remv*
remw
remw*
rename
rename transformer
rename-contract
rename-file-or-directory
rename-in
rename-inner
rename-out
rename-super
rename-transformer-target
rename-transformer?
REPL
'replace
replace-evt
require
require Macros
require +transformer
require Transformers
require-transformer?
reroot-path
reset
reset-at
reset0
reset0-at
resolve-path
resolved
resolved +module path
resolved-module-path-name
resolved-module-path?
Resolving Module Names
rest
'return
'return-linefeed
reverse
root namespace
round
'run-file
'running
Running Racket
Running Racket or GRacket
runtime-paths
runtime-require
s-exp
s-exp->fasl
S-Expression Reader Language
'same
sandbox-coverage-enabled
sandbox-error-output
sandbox-eval-handlers
sandbox-eval-limits
sandbox-exit-handler
sandbox-gui-available
sandbox-init-hook
sandbox-input
sandbox-make-code-inspector
sandbox-make-environment-variables
sandbox-make-inspector
sandbox-make-logger
sandbox-make-namespace
sandbox-make-plumber
sandbox-memory-limit
sandbox-namespace-specs
sandbox-network-guard
sandbox-output
sandbox-override-collection-paths
sandbox-path-permissions
sandbox-propagate-breaks
sandbox-propagate-exceptions
sandbox-reader
sandbox-run-submodules
sandbox-security-guard
Sandboxed Evaluation
'sc
'scalable
scalar value
scope
scope set
sealed
second
seconds->date
Security Considerations
security guard
Security Guards
security-guard?
select
self
semaphore
semaphore-peek-evt
semaphore-peek-evt?
semaphore-post
semaphore-try-wait?
semaphore-wait
semaphore-wait/enable-break
semaphore?
Semaphores
send
send*
send+
send-generic
send/apply
send/keyword-apply
separate compilation guarantee
sequence
Sequence Conversion
Sequence Predicate and Constructors
sequence->generator
sequence->list
sequence->repeated-generator
sequence->stream
sequence-add-between
sequence-andmap
sequence-append
sequence-count
sequence-filter
sequence-fold
sequence-for-each
sequence-generate
sequence-generate*
sequence-length
sequence-map
sequence-ormap
sequence-ref
sequence-tail
sequence/c
sequence?
Sequences
Sequences and Streams
Sequencing: begin, begin0, and begin-for-syntax
serializable-struct
serializable-struct/versions
serializable?
Serialization
serialize
serialized=?
Serializing Syntax
'server
set
set
set
Set Methods
Set Predicates and Contracts
set!
set!-transformer-procedure
set!-transformer?
set!-values
set->list
set->stream
set-add
set-add!
set-box!
set-box*!
set-clear
set-clear!
set-copy
set-copy-clear
set-count
set-empty?
set-eq?
set-equal-always?
set-equal?
set-eqv?
set-eval-handler
set-eval-limits
set-field!
set-first
set-for-each
set-group-id-bit
set-implements/c
set-implements?
set-intersect
set-intersect!
set-map
set-mcar!
set-mcdr!
set-member?
set-mutable?
set-phantom-bytes!
set-port-next-location!
set-remove
set-remove!
set-rest
set-subset?
set-subtract
set-subtract!
set-symmetric-difference
set-symmetric-difference!
set-union
set-union!
set-user-id-bit
set-weak?
set/c
set=?
set?
setalw
seteq
seteqv
Sets
seventh
sgn
sha1-bytes
sha224-bytes
sha256-bytes
shadowing
shadows
Shallow time
shared
'shared
shared memory space
shared-bytes
shared-extflvector
shared-flvector
shared-fxvector
shell-execute
ShellExecute
shift
shift-at
shift0
shift0-at
shrink-path-wrt
shuffle
SIGHUP
SIGINT
signature
signature-members
SIGTERM
Simple Subprocesses
simple-form-path
simplify-path
sin
single-flonum-available?
single-flonum?
single-flonums
Single-Signature Modules
Single-Unit Modules
sinh
sixth
'size
'sk
skip-projection-wrapper?
sleep
'sm
'so
'so-mode
'so-suffix
socket-type-bits
some-system-path->string
sort
source location
space?
spawn
special
Special Comments
special-comment-value
special-comment?
special-filter-input-port
spliced
splicing-let
splicing-let-syntax
splicing-let-syntaxes
splicing-let-values
splicing-letrec
splicing-letrec-syntax
splicing-letrec-syntaxes
splicing-letrec-syntaxes+values
splicing-letrec-values
splicing-local
splicing-parameterize
splicing-syntax-parameterize
split-at
split-at-right
split-common-prefix
split-path
splitf-at
splitf-at-right
splitter
sqr
sqrt
square root
srcloc
srcloc->string
srcloc-column
srcloc-line
srcloc-position
srcloc-source
srcloc-span
srcloc?
stack +dump
stack trace
'static
stencil vector
Stencil Vectors
stencil-vector
stencil-vector-length
stencil-vector-mask
stencil-vector-mask-width
stencil-vector-ref
stencil-vector-set!
stencil-vector-update
stencil-vector?
sticky-bit
stop-after
stop-before
stream
stream
stream*
stream->list
stream-add-between
stream-andmap
stream-append
stream-cons
stream-count
stream-empty?
stream-filter
stream-first
stream-fold
stream-for-each
stream-force
stream-lazy
stream-length
stream-map
stream-ormap
stream-ref
stream-rest
stream-tail
stream-take
stream/c
stream?
Streams
string
string
String Comparisons
String Constructors, Selectors, and Mutators
String Conversions
string port
String Ports
string->bytes/latin-1
string->bytes/locale
string->bytes/utf-8
string->immutable-string
string->keyword
string->list
string->number
string->path
string->path-element
string->some-system-path
string->symbol
string->uninterned-symbol
string->unreadable-symbol
string-append
string-append*
string-append-immutable
string-ci<=?
string-ci<?
string-ci=?
string-ci>=?
string-ci>?
string-contains?
string-copy
string-copy!
string-downcase
string-environment-variable-name?
string-fill!
string-foldcase
string-join
string-len/c
string-length
string-locale-ci<?
string-locale-ci=?
string-locale-ci>?
string-locale-downcase
string-locale-upcase
string-locale<?
string-locale=?
string-locale>?
string-no-nuls?
string-normalize-nfc
string-normalize-nfd
string-normalize-nfkc
string-normalize-nfkd
string-normalize-spaces
string-port?
string-prefix?
string-ref
string-replace
string-set!
string-split
string-suffix?
string-titlecase
string-trim
string-upcase
string-utf-8-length
string<=?
string<?
string=?
string>=?
string>?
string?
strings, pattern matching
strings, parsing
strings, immutable
strings, concatenate
Strings
struct
struct
struct*
struct->list
struct->vector
struct-accessor-procedure?
struct-auto-info-lists
struct-auto-info?
struct-constructor-procedure?
struct-copy
struct-field-index
struct-field-info-list
struct-field-info?
struct-guard/c
struct-info
struct-info?
struct-mutator-procedure?
struct-out
struct-predicate-procedure?
struct-type-authentic?
struct-type-info
struct-type-make-constructor
struct-type-make-predicate
struct-type-property-accessor-procedure?
struct-type-property-predicate-procedure?
struct-type-property/c
struct-type-property?
struct-type-sealed?
struct-type?
struct/c
struct/contract
struct/ctc
struct/dc
struct/derived
struct:arity-at-least
struct:collapsible-count-property
struct:collapsible-ho/c
struct:collapsible-leaf/c
struct:collapsible-property
struct:collapsible-wrapper-property
struct:date
struct:date*
struct:exn
struct:exn:break
struct:exn:break:hang-up
struct:exn:break:terminate
struct:exn:fail
struct:exn:fail:contract
struct:exn:fail:contract:arity
struct:exn:fail:contract:blame
struct:exn:fail:contract:continuation
struct:exn:fail:contract:divide-by-zero
struct:exn:fail:contract:non-fixnum-result
struct:exn:fail:contract:variable
struct:exn:fail:filesystem
struct:exn:fail:filesystem:errno
struct:exn:fail:filesystem:exists
struct:exn:fail:filesystem:missing-module
struct:exn:fail:filesystem:version
struct:exn:fail:network
struct:exn:fail:network:errno
struct:exn:fail:object
struct:exn:fail:out-of-memory
struct:exn:fail:read
struct:exn:fail:read:eof
struct:exn:fail:read:non-char
struct:exn:fail:support
struct:exn:fail:syntax
struct:exn:fail:syntax:missing-module
struct:exn:fail:syntax:unbound
struct:exn:fail:unsupported
struct:exn:fail:user
struct:export
struct:import
struct:import-source
struct:srcloc
struct:struct-info
struct?
Structural Matching
structure
Structure Inspectors
structure subtype
structure type
structure type +descriptor
Structure Type Properties
structure type property
Structure Type Property Contracts
structure type property descriptor
Structure Type Transformer Binding
Structure Utilities
structures, equality
Structures
Structures as Ports
Sub-expression Evaluation and Continuations
sub1
subbytes
subclass?
subclass?/c
submod
submodule
Submodules
subprocess
subprocess
subprocess-group-enabled
subprocess-kill
subprocess-pid
subprocess-status
subprocess-wait
subprocess?
subset?
substring
subtract-in
suggest/c
super
super-instantiate
super-make-object
super-new
superclass
'supported
supported generic method
surrogate
Surrogates
Suspending, Resuming, and Killing Threads
'SW_HIDE
'sw_hide
'SW_MAXIMIZE
'sw_maximize
'SW_MINIMIZE
'sw_minimize
'SW_RESTORE
'sw_restore
'SW_SHOW
'sw_show
'SW_SHOWDEFAULT
'sw_showdefault
'SW_SHOWMAXIMIZED
'sw_showmaximized
'SW_SHOWMINIMIZED
'sw_showminimized
'SW_SHOWMINNOACTIVE
'sw_showminnoactive
'SW_SHOWNA
'sw_showna
'SW_SHOWNOACTIVATE
'sw_shownoactivate
'SW_SHOWNORMAL
'sw_shownormal
symbol
symbol->immutable-string
symbol->string
symbol-interned?
symbol-unreadable?
symbol<?
symbol=?
symbol?
symbolic-link-type-bits
symbols, unique
symbols, generating
Symbols
symbols
sync
sync/enable-break
sync/timeout
sync/timeout/enable-break
synchronizable event
Synchronization
synchronization result
Synchronizing Thread State
syntactic form
Syntactic Forms
Syntactic Support for Using Places
syntax
syntax binding set
Syntax Model
syntax object
Syntax Object Bindings
Syntax Object Content
Syntax Object Properties
Syntax Object Source Locations
Syntax Objects
syntax pair
syntax +parameter
Syntax Parameter Inspection
Syntax Parameters
syntax property
Syntax Quoting: quote-syntax
Syntax Taints
syntax transformer
Syntax Transformers
Syntax Utilities
syntax->datum
syntax->list
syntax-arm
syntax-binding-set
syntax-binding-set->syntax
syntax-binding-set-extend
syntax-binding-set?
syntax-case
syntax-case*
syntax-column
syntax-debug-info
syntax-deserialize
syntax-disarm
syntax-e
syntax-id-rules
syntax-line
syntax-local-apply-transformer
syntax-local-bind-syntaxes
syntax-local-certifier
syntax-local-context
syntax-local-eval
syntax-local-expand-expression
syntax-local-get-shadower
syntax-local-identifier-as-binding
syntax-local-introduce
syntax-local-lift-context
syntax-local-lift-expression
syntax-local-lift-module
syntax-local-lift-module-end-declaration
syntax-local-lift-provide
syntax-local-lift-require
syntax-local-lift-values-expression
syntax-local-make-definition-context
syntax-local-make-delta-introducer
syntax-local-match-introduce
syntax-local-module-defined-identifiers
syntax-local-module-exports
syntax-local-module-interned-scope-symbols
syntax-local-module-required-identifiers
syntax-local-name
syntax-local-phase-level
syntax-local-provide-certifier
syntax-local-provide-introduce
syntax-local-require-certifier
syntax-local-require-introduce
syntax-local-submodules
syntax-local-transforming-module-provides?
syntax-local-value
syntax-local-value/immediate
syntax-local-value/record
syntax-original?
syntax-parameter-value
syntax-parameterize
syntax-pattern-variable?
syntax-position
syntax-procedure-alias-property
syntax-procedure-converted-arguments-property
syntax-property
syntax-property-preserved?
syntax-property-remove
syntax-property-symbol-keys
syntax-protect
syntax-rearm
syntax-recertify
syntax-rules
syntax-serialize
syntax-shift-phase-level
syntax-source
syntax-source-module
syntax-span
syntax-srcloc
syntax-taint
syntax-tainted?
syntax-track-origin
syntax-transforming-module-expression?
syntax-transforming-with-lifts?
syntax-transforming?
syntax/c
syntax/loc
syntax?
'sys-dir
system
system*
system*/exit-code
system-big-endian?
system-idle-evt
system-language+country
system-library-subpath
system-path-convention-type
system-type
system/exit-code
tag
Tail Position
tail position
'taint-mode
tainted
take
take-common-prefix
take-right
takef
takef-right
tan
tanh
'target-machine
TCP
TCP +listener
TCP port
tcp-abandon-port
tcp-accept
tcp-accept-evt
tcp-accept-ready?
tcp-accept/enable-break
tcp-addresses
tcp-close
tcp-connect
tcp-connect/enable-break
tcp-listen
tcp-listener?
tcp-port?
TEMP
'temp-dir
template environment
tentative-pretty-print-port-cancel
tentative-pretty-print-port-transfer
tenth
terminal-port?
'terminating-macro
'text
the epoch
The Printer
The Racket Reference
The racket/load Language
The racket/repl Library
The Reader
The Separate Compilation Guarantee
the-unsupplied-arg
third
this
this%
thread
Thread Cells
thread +cells
thread +descriptor
thread group
Thread Groups
Thread Mailboxes
thread-cell-ref
thread-cell-set!
thread-cell-values?
thread-cell?
thread-dead-evt
thread-dead?
thread-group?
Thread-Local Storage
thread-receive
thread-receive-evt
thread-resume
thread-resume-evt
thread-rewind-receive
thread-running?
thread-send
thread-suspend
thread-suspend-evt
thread-try-receive
thread-wait
thread/suspend-to-kill
thread?
threads, run state
threads, breaking
threads, breaking
Threads
Threads
threads
thunk
thunk*
Time
time
time-apply
TMP
TMPDIR
top-level binding
top-level context
top-level variable
Top-Level Variables
touch
trace
trace-call
trace-define
trace-define-syntax
trace-lambda
trace-let
Tracing
trait
trait
trait->mixin
trait-alias
trait-exclude
trait-exclude-field
trait-rename
trait-rename-field
trait-sum
trait?
Traits
transformer
Transformer Bindings
transformer environment
Transformer Helpers
transplant-input-port
transplant-output-port
Trigonometric Functions
true
truncate
'truncate
'truncate/replace
UDP
UDP socket
udp-addresses
udp-bind!
udp-bound?
udp-close
udp-connect!
udp-connected?
udp-multicast-interface
udp-multicast-join-group!
udp-multicast-leave-group!
udp-multicast-loopback?
udp-multicast-set-interface!
udp-multicast-set-loopback!
udp-multicast-set-ttl!
udp-multicast-ttl
udp-open-socket
udp-receive!
udp-receive!*
udp-receive!-evt
udp-receive!/enable-break
udp-receive-ready-evt
udp-send
udp-send*
udp-send-evt
udp-send-ready-evt
udp-send-to
udp-send-to*
udp-send-to-evt
udp-send-to/enable-break
udp-send/enable-break
udp-set-receive-buffer-size!
udp-set-ttl!
udp-ttl
udp?
unbound
unbox
unbox*
uncaught-exception handler
uncaught-exception-handler
unconstrained-domain->
Undefined
undefined
'undefined-error-name
uninterned
unit
unit contract
Unit Contracts
Unit Utilities
unit-from-context
unit-static-init-dependencies
unit-static-signatures
unit/c
unit/new-import-export
unit/s
unit?
Units
Units
'unix
'unix
Unix and Mac OS Paths
Unix Path Representation
unless
unquote
unquote-splicing
unquoted-printing string
unquoted-printing-string
unquoted-printing-string-value
unquoted-printing-string?
Unreachable Expressions
unreadable symbol
unsafe
Unsafe Assertions
Unsafe Character Operations
Unsafe Compound-Data Operations
Unsafe Extflonum Operations
Unsafe Impersonators and Chaperones
unsafe mode
Unsafe Numeric Operations
Unsafe Operations
Unsafe Undefined
unsafe-assert-unreachable
unsafe-box*-cas!
unsafe-bytes->immutable-bytes!
unsafe-bytes-copy!
unsafe-bytes-length
unsafe-bytes-ref
unsafe-bytes-set!
unsafe-car
unsafe-cdr
unsafe-chaperone-procedure
unsafe-chaperone-vector
unsafe-char->integer
unsafe-char<=?
unsafe-char<?
unsafe-char=?
unsafe-char>=?
unsafe-char>?
unsafe-cons-list
unsafe-ephemeron-hash-iterate-first
unsafe-ephemeron-hash-iterate-key
unsafe-ephemeron-hash-iterate-key+value
unsafe-ephemeron-hash-iterate-next
unsafe-ephemeron-hash-iterate-pair
unsafe-ephemeron-hash-iterate-value
unsafe-extfl*
unsafe-extfl+
unsafe-extfl-
unsafe-extfl->fx
unsafe-extfl/
unsafe-extfl<
unsafe-extfl<=
unsafe-extfl=
unsafe-extfl>
unsafe-extfl>=
unsafe-extflabs
unsafe-extflacos
unsafe-extflasin
unsafe-extflatan
unsafe-extflceiling
unsafe-extflcos
unsafe-extflexp
unsafe-extflexpt
unsafe-extflfloor
unsafe-extfllog
unsafe-extflmax
unsafe-extflmin
unsafe-extflround
unsafe-extflsin
unsafe-extflsqrt
unsafe-extfltan
unsafe-extfltruncate
unsafe-extflvector-length
unsafe-extflvector-ref
unsafe-extflvector-set!
unsafe-f64vector-ref
unsafe-f64vector-set!
unsafe-fl*
unsafe-fl+
unsafe-fl-
unsafe-fl->fx
unsafe-fl/
unsafe-fl<
unsafe-fl<=
unsafe-fl=
unsafe-fl>
unsafe-fl>=
unsafe-flabs
unsafe-flacos
unsafe-flasin
unsafe-flatan
unsafe-flceiling
unsafe-flcos
unsafe-flexp
unsafe-flexpt
unsafe-flfloor
unsafe-flimag-part
unsafe-fllog
unsafe-flmax
unsafe-flmin
unsafe-flrandom
unsafe-flreal-part
unsafe-flround
unsafe-flsin
unsafe-flsingle
unsafe-flsqrt
unsafe-fltan
unsafe-fltruncate
unsafe-flvector-length
unsafe-flvector-ref
unsafe-flvector-set!
unsafe-fx*
unsafe-fx*/wraparound
unsafe-fx+
unsafe-fx+/wraparound
unsafe-fx-
unsafe-fx-/wraparound
unsafe-fx->extfl
unsafe-fx->fl
unsafe-fx<
unsafe-fx<=
unsafe-fx=
unsafe-fx>
unsafe-fx>=
unsafe-fxabs
unsafe-fxand
unsafe-fxior
unsafe-fxlshift
unsafe-fxlshift/wraparound
unsafe-fxmax
unsafe-fxmin
unsafe-fxmodulo
unsafe-fxnot
unsafe-fxpopcount
unsafe-fxpopcount16
unsafe-fxpopcount32
unsafe-fxquotient
unsafe-fxremainder
unsafe-fxrshift
unsafe-fxvector-length
unsafe-fxvector-ref
unsafe-fxvector-set!
unsafe-fxxor
unsafe-immutable-hash-iterate-first
unsafe-immutable-hash-iterate-key
unsafe-immutable-hash-iterate-key+value
unsafe-immutable-hash-iterate-next
unsafe-immutable-hash-iterate-pair
unsafe-immutable-hash-iterate-value
unsafe-impersonate-procedure
unsafe-impersonate-vector
unsafe-list-ref
unsafe-list-tail
unsafe-make-flrectangular
unsafe-make-srcloc
unsafe-mcar
unsafe-mcdr
unsafe-mutable-hash-iterate-first
unsafe-mutable-hash-iterate-key
unsafe-mutable-hash-iterate-key+value
unsafe-mutable-hash-iterate-next
unsafe-mutable-hash-iterate-pair
unsafe-mutable-hash-iterate-value
unsafe-s16vector-ref
unsafe-s16vector-set!
unsafe-set-box!
unsafe-set-box*!
unsafe-set-immutable-car!
unsafe-set-immutable-cdr!
unsafe-set-mcar!
unsafe-set-mcdr!
unsafe-stencil-vector
unsafe-stencil-vector-length
unsafe-stencil-vector-mask
unsafe-stencil-vector-ref
unsafe-stencil-vector-set!
unsafe-stencil-vector-update
unsafe-string->immutable-string!
unsafe-string-length
unsafe-string-ref
unsafe-string-set!
unsafe-struct*-cas!
unsafe-struct*-ref
unsafe-struct*-set!
unsafe-struct-ref
unsafe-struct-set!
unsafe-u16vector-ref
unsafe-u16vector-set!
unsafe-unbox
unsafe-unbox*
unsafe-undefined
unsafe-vector*->immutable-vector!
unsafe-vector*-cas!
unsafe-vector*-length
unsafe-vector*-ref
unsafe-vector*-set!
unsafe-vector-length
unsafe-vector-ref
unsafe-vector-set!
unsafe-weak-hash-iterate-first
unsafe-weak-hash-iterate-key
unsafe-weak-hash-iterate-key+value
unsafe-weak-hash-iterate-next
unsafe-weak-hash-iterate-pair
unsafe-weak-hash-iterate-value
unsupplied-arg?
unsyntax
unsyntax-splicing
untrace
'up
'update
use-collection-link-paths
use-compiled-file-check
use-compiled-file-paths
use-site scope
use-user-specific-search-paths
USER
user’s home +directory
user-execute-bit
'user-id
user-permission-bits
user-read-bit
user-read-bit
user-write-bit
USERPROFILE
Using Places
UTF-8-permissive
Utilities for Building New Combinators
valid hash index
value
Value Output Hook
value-blame
value-contract
values
variable
variable reference
Variable References and #%top
variable-reference->empty-namespace
variable-reference->instance
variable-reference->module-base-phase
variable-reference->module-declaration-inspector
variable-reference->module-path-index
variable-reference->module-source
variable-reference->namespace
variable-reference->phase
variable-reference->resolved-module-path
variable-reference-constant?
variable-reference-from-unsafe?
variable-reference?
Variables and Locations
vector
vector
vector
vector*-length
vector*-ref
vector*-set!
vector->immutable-vector
vector->list
vector->pseudo-random-generator
vector->pseudo-random-generator!
vector->values
vector-append
vector-argmax
vector-argmin
vector-cas!
vector-copy
vector-copy!
vector-count
vector-drop
vector-drop-right
vector-empty?
vector-fill!
vector-filter
vector-filter-not
vector-immutable
vector-immutable/c
vector-immutableof
vector-length
vector-map
vector-map!
vector-member
vector-memq
vector-memv
vector-ref
vector-set!
vector-set*!
vector-set-performance-stats!
vector-sort
vector-sort!
vector-split-at
vector-split-at-right
vector-take
vector-take-right
vector/c
vector?
vectorof
Vectors
version
visits
'vm
Void
void
void?
weak box
Weak Boxes
weak references
weak-box-value
weak-box?
weak-set
weak-setalw
weak-seteq
weak-seteqv
when
will
will executor
will-execute
will-executor?
will-register
will-try-execute
Wills and Executors
'windows
'windows
Windows Path Representation
Windows Paths
with-assert-unreachable
with-collapsible-contract-continuation-mark
with-continuation-mark
with-contract
with-contract-continuation-mark
with-deep-time-limit
with-disappeared-uses
with-handlers
with-handlers*
with-input-from-bytes
with-input-from-file
with-input-from-string
with-intercepted-logging
with-limits
with-logging-to-port
with-method
with-output-to-bytes
with-output-to-file
with-output-to-string
with-syntax
with-syntax*
'word
would-be-future
wrap-evt
writable<%>
write
'write
'write
write-byte
write-bytes
write-bytes-avail
write-bytes-avail*
write-bytes-avail-evt
write-bytes-avail/enable-break
write-char
write-special
write-special-avail*
write-special-evt
write-string
write-to-file
writeln
Writing
wrong-syntax
XDG_CACHE_HOME
XDG_CONFIG_HOME
XDG_DATA_HOME
xor
yield
zero?
'zl
'zp
'zs
{
|
}
~.a
~.s
~.v
~?
~@
~a
~e
~r
~s
~v
λ

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/encodings.html b/clones/docs.racket-lang.org/reference/encodings.html new file mode 100644 index 00000000..67193363 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/encodings.html @@ -0,0 +1,72 @@ + +13.1.1 Encodings and Locales
13.1.1 Encodings and Locales

When a port is provided to a character-based operation, such as +read-char or read, the port’s bytes are read and +interpreted as a UTF-8 encoding of characters. Thus, reading a single +character may require reading multiple bytes, and a procedure like +char-ready? may need to peek several bytes into the stream to +determine whether a character is available. In the case of a byte +stream that does not correspond to a valid UTF-8 encoding, functions +such as read-char may need to peek one byte ahead in the +stream to discover that the stream is not a valid encoding.

When an input port produces a sequence of bytes that is not a valid +UTF-8 encoding in a character-reading context, then bytes that +constitute an invalid sequence are converted to the character +#\uFFFD. Specifically, bytes 255 and 254 are always converted +to #\uFFFD, bytes in the range 192 to 253 produce +#\uFFFD when they are not followed by bytes that form a valid +UTF-8 encoding, and bytes in the range 128 to 191 are converted to +#\uFFFD when they are not part of a valid encoding that was +started by a preceding byte in the range 192 to 253. To put it another +way, when reading a sequence of bytes as characters, a minimal set of +bytes are changed to the encoding of #\uFFFD so that the +entire sequence of bytes is a valid UTF-8 encoding.

See Byte Strings for procedures that facilitate +conversions using UTF-8 or other encodings. See also +reencode-input-port and reencode-output-port for +obtaining a UTF-8-based port from one that uses a different encoding +of characters.

A locale captures information about a user’s +language-specific interpretation of character sequences. In particular, +a locale determines how strings are “alphabetized,” how a lowercase +character is converted to an uppercase character, and how strings are +compared without regard to case. String operations such as +string-ci=? are not sensitive to the current locale, +but operations such as string-locale-ci=? (see +Strings) produce results consistent with the current +locale.

A locale also designates a particular encoding of code-point sequences +into byte sequences. Racket generally ignores this aspect of the +locale, with a few notable exceptions: command-line arguments passed +to Racket as byte strings are converted to character strings using the +locale’s encoding; command-line strings passed as byte strings to +other processes (through subprocess) are converted to byte +strings using the locale’s encoding; environment variables are +converted to and from strings using the locale’s encoding; filesystem +paths are converted to and from strings (for display purposes) using +the locale’s encoding; and, finally, Racket provides functions such as +string->bytes/locale to specifically invoke a locale-specific +encoding.

A Unix user selects a locale by setting environment variables, such as +LC_ALL. On Windows and Mac OS, the operating system +provides other mechanisms for setting the locale. Within Racket, the +current locale can be changed by setting the current-locale +parameter. The locale name within Racket is a string, and the +available locale names depend on the platform and its configuration, +but the "" locale means the current user’s default locale; +on Windows and Mac OS, the encoding for "" is always +UTF-8, and locale-sensitive operations use the operating system’s +native interface. (In particular, setting the LC_ALL and +LC_CTYPE environment variables does not affect the locale +"" on Mac OS. Use getenv and +current-locale to explicitly install the +environment-specified locale, if desired.) Setting the current locale +to #f makes locale-sensitive operations locale-insensitive, +which means using the Unicode mapping for case operations and using +UTF-8 for encoding.

parameter

(current-locale)  (or/c string? #f)

(current-locale locale)  void?
  locale : (or/c string? #f)
A parameter that determines the current locale for +procedures such as string-locale-ci=?.

When locale sensitivity is disabled by setting the parameter to +#f, strings are compared, etc., in a fully portable manner, +which is the same as the standard procedures. Otherwise, strings are +interpreted according to a locale setting (in the sense of the C +library’s setlocale). The "" locale is always an alias +for the current machine’s default locale, and it is the default. The +"C" locale is also always available; setting the locale to +"C" is the same as disabling locale sensitivity with +#f only when string operations are restricted to the first +128 characters. Other locale names are platform-specific.

String or character printing with write is not affected by +the parameter, and neither are symbol case or regular expressions (see +Regular Expressions).

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/engine.html b/clones/docs.racket-lang.org/reference/engine.html new file mode 100644 index 00000000..0e9b4175 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/engine.html @@ -0,0 +1,39 @@ + +11.6 Engines

11.6 Engines

 (require racket/engine) package: base
The bindings documented in this section are provided by the racket/engine library, not racket/base or racket.

An engine is an abstraction that models processes that +can be preempted by a timer or other external trigger. They are +inspired by the work of Haynes and Friedman [Haynes84].

Engines log their behavior via a logger with the name +'racket/engine. The logger is created when the module +is instantiated and uses the result of (current-logger) +as its parent. The library adds logs a 'debug level +message: when engine-run +is called, when the engine timeout expires, and when the engine is +stopped (either because it terminated or it reached a safe point to +stop). Each log message holds a value of the struct: +

(struct engine-info (msec name) #:prefab)

where the msec field holds the result of +(current-inexact-milliseconds) at the moment of logging, +and the name field holds the name of the procedure +passed to engine.

procedure

(engine proc)  engine?

  proc : ((any/c . -> . void?) . -> . any/c)
Returns an engine object to encapsulate a thread that runs only when +allowed. The proc procedure should accept one argument, and +proc is run in the engine thread when +engine-run is called. If engine-run returns +due to a timeout, then the engine thread is suspended until a +future call to engine-run. Thus, proc only +executes during the dynamic extent of a engine-run call.

The argument to proc is a procedure that takes a boolean, and +it can be used to disable suspends (in case proc has critical +regions where it should not be suspended). A true value passed to the +procedure enables suspends, and #f disables +suspends. Initially, suspends are allowed.

procedure

(engine? v)  any

  v : any/c
Returns #t if v is an engine produced by +engine, #f otherwise.

procedure

(engine-run until engine)  boolean?

  until : (or/c evt? real?)
  engine : engine?
Allows the thread associated with engine to execute for up +as long as until milliseconds (if until is a real +number) or until is ready (if until is an event). If +engine’s procedure disables suspends, then the engine +can run arbitrarily long until it re-enables suspends.

The engine-run procedure returns #t if +engine’s procedure completes (or if it completed earlier), +and the result is available via engine-result. The +engine-run procedure returns #f if +engine’s procedure does not complete before it is +suspended after the until condition is met. If engine’s +procedure raises an exception, then it is re-raised by +engine-run.

procedure

(engine-result engine)  any

  engine : engine?
Returns the result for engine if it has completed with a +value (as opposed to an exception), #f otherwise.

procedure

(engine-kill engine)  void?

  engine : engine?
Forcibly terminates the thread associated with engine if +it is still running, leaving the engine result unchanged.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/envvars.html b/clones/docs.racket-lang.org/reference/envvars.html new file mode 100644 index 00000000..bf1af773 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/envvars.html @@ -0,0 +1,48 @@ + +15.7 Environment Variables

15.7 Environment Variables

An environment variable set encapsulates a partial mapping +from byte strings to byte strings. A Racket process’s initial +environment variable set is connected to the operating system’s +environment variables: accesses or changes to the set read or change +operating-system environment variables for the Racket process.

Since Windows environment variables are case-insensitive, +environment variable set’s key byte strings on Windows are +case-folded. More precisely, key byte strings are coerced to a UTF-8 +encoding of characters that are converted to lowercase via +string-locale-downcase.

The current environment variable set, which is determined by +the current-environment-variables parameter, is propagated to +a subprocess when the subprocess is created.

procedure

(environment-variables? v)  boolean?

  v : any/c
Returns #t if v is an environment variable +set, #f otherwise.

A parameter that determines the environment variable set +that is propagated to a subprocess and that is used as the +default set for getenv and putenv.

procedure

(bytes-environment-variable-name? v)  boolean?

  v : any/c
Returns #t if v is a byte string and if it is valid +for an environment variable name. An environment variable name must +contain no bytes with the value 0 or 61, where +61 is (char->integer #\=). On Windows, an +environment variable name also must have a non-zero length.

procedure

(make-environment-variables name val ... ...)

  environment-variables?
  name : bytes-environment-variable-name?
  val : bytes-no-nuls?
Creates a fresh environment variable set that is initialized +with the given name to val mappings.

Returns the mapping for name in env, returning +#f if name has no mapping.

Normally, name should be a byte-string encoding of a string +using the default encoding of the current locale. On Windows, +name is coerced to a UTF-8 encoding and case-normalized.

procedure

(environment-variables-set! env    
  name    
  maybe-bstr    
  [fail])  any
  env : environment-variables?
  name : bytes-environment-variable-name?
  maybe-bstr : (or/c bytes-no-nuls? #f)
  fail : (-> any) = 
(lambda ()
  (raise (make-exn:fail ....)))
Changes the mapping for name in env to +maybe-bstr. If maybe-bstr is #f and +env is the initial environment variable set of the +Racket process, then the operating system environment-variable mapping +for name is removed.

Normally, name and maybe-bstr should be a +byte-string encoding of a string using the default encoding of the +current locale. On Windows, name is +coerced to a UTF-8 encoding and case-normalized, and +maybe-bstr is coerced to a UTF-8 encoding if env is +the initial environment variable set of the Racket process.

On success, the result of environment-variables-set! is +#<void>. If env is the initial environment +variable set of the Racket process, then attempting to adjust the +operating system environment-variable mapping might fail for some reason, +in which case fail is called in tail position with respect to the +environment-variables-set!. The default fail raises +an exception.

Returns a list of byte strings that corresponds to names mapped by +env.

Returns an environment variable set that is initialized with +the same mappings as env.

procedure

(getenv name)  (or/c string-no-nuls? #f)

  name : string-environment-variable-name?

procedure

(putenv name value)  boolean?

  name : string-environment-variable-name?
  value : string-no-nuls?
Convenience wrappers for environment-variables-ref and +environment-variables-set! that convert between strings and +byte strings using the current locale’s default encoding (using +#\? as the replacement character for encoding errors) and +always using the current environment variable set from +current-environment-variables. The putenv function +returns #t for success and #f for failure.

procedure

(string-environment-variable-name? v)  boolean?

  v : any/c
Returns #t if v is a string and if its encoding +using the current locale’s encoding is valid for an environment +variable name according to bytes-environment-variable-name?.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/ephemerons.html b/clones/docs.racket-lang.org/reference/ephemerons.html new file mode 100644 index 00000000..f556efaf --- /dev/null +++ b/clones/docs.racket-lang.org/reference/ephemerons.html @@ -0,0 +1,40 @@ + +16.2 Ephemerons

16.2 Ephemerons

An ephemeron [Hayes97] is a generalization of a +weak box (see Weak Boxes). Instead of just containing +one value, an ephemeron holds two values: one that is considered the +value of the ephemeron and another that is the ephemeron’s key. Like +the value in a weak box, the value in an ephemeron may be replaced by +#f, but when the key is no longer reachable (except +possibly via weak references) instead of when the value is no longer +reachable.

As long as an ephemeron’s value is retained, the reference is +considered a non-weak reference. References to the key via the value +are treated specially, however, in that the reference does not +necessarily count toward the key’s reachability. A weak box can +be seen as a specialization of an ephemeron where the key and value +are the same.

One particularly common use of ephemerons is to combine them with a +weak hash table (see Hash Tables) to produce a mapping where +the memory manager can reclaim key–value pairs even when the value +refers to the key; see make-ephemeron-hash. +A related use is to retain a reference to a value +as long as any value for which it is an impersonator is +reachable; see impersonator-ephemeron.

More precisely, +
  • the value in an ephemeron is replaced +by #f when the automatic memory manager can prove that +either the ephemeron or the key is reachable only through weak +references (see Weak Boxes); and

  • nothing reachable from the value in an ephemeron counts toward +the reachability of an ephemeron key (whether for the same ephemeron +or another), unless the same value is reachable through a non-weak +reference, or unless the value’s ephemeron key is reachable through a +non-weak reference (see Weak Boxes for information on weak +references).

procedure

(make-ephemeron key v)  ephemeron?

  key : any/c
  v : any/c
Returns a new ephemeron whose key is key and whose +value is initially v.

procedure

(ephemeron-value ephemeron [gced-v retain-v])  any/c

  ephemeron : ephemeron?
  gced-v : any/c = #f
  retain-v : any/c = #f
Returns the value contained in ephemeron. If the garbage +collector has proven that the key for ephemeron is only +weakly reachable, then the result is gced-v (which defaults to #f).

The retain-v argument is retained as reachable until the +ephemeron’s value is extracted. It is useful, for example, when +ephemeron was obtained through a weak, eq?-based +mapping from key and ephemeron was created with +key as the key; in that case, supplying key as +retain-v ensures that ephemeron retains its value +long enough for it to be extracted, even if key is otherwise +unreachable.

Changed in version 7.1.0.10 of package base: Added the retain-v argument.

procedure

(ephemeron? v)  boolean?

  v : any/c
Returns #t if v is an ephemeron, #f +otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/eval-model.html b/clones/docs.racket-lang.org/reference/eval-model.html new file mode 100644 index 00000000..323e5e85 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/eval-model.html @@ -0,0 +1,515 @@ + +1.1 Evaluation Model
8.6

1.1 Evaluation Model

Racket evaluation can be viewed as the simplification of expressions +to obtain values. For example, just as an elementary-school student +simplifies

  1 + 1 = 2

Racket evaluation simplifies

(+ 1 1)  2

The arrow → replaces the more traditional = to +emphasize that evaluation proceeds in a particular direction toward +simpler expressions. In particular, a value, such as the number 2, +is an expression that evaluation simplifies no further.

1.1.1 Sub-expression Evaluation and Continuations

Some simplifications require more than one step. For example:

(- 4 (+ 1 1))  (- 4 2)  2

An expression that is not a value can always be partitioned +into two parts: a redex (“reducible expression”), +which is the part that can change in a +single-step simplification (highlighted), and the +continuation, which is the evaluation +context surrounding the redex. In (- 4 (+ 1 1)), the redex is (+ 1 1), and +the continuation is (- 4 []), where [] takes the place +of the redex as it is reduced. That is, the continuation says how to “continue” +after the redex is reduced to a value.

Before some expressions can be evaluated, some or all of their sub-expressions must be +evaluated. For example, in the application (- 4 (+ 1 1)), the +application of - cannot be reduced until the sub-expression +(+ 1 1) is reduced. +Thus, the specification of each syntactic form specifies how (some of) +its sub-expressions are evaluated and then how the results are +combined to reduce the form away.

The dynamic extent of an expression is the sequence of +evaluation steps during which the expression contains the redex.

1.1.2 Tail Position

An expression expr1 is in tail position with +respect to an enclosing expression expr2 if, whenever +expr1 becomes a redex, its continuation is the same +as was the enclosing expr2’s continuation.

For example, the (+ 1 1) expression is not in tail +position with respect to (- 4 (+ 1 1)). To illustrate, we use +the notation C[expr] to mean the expression that is produced by +substituting expr in place of [] in some continuation +C:

C[(- 4 (+ 1 1))]  C[(- 4 2)]

In this case, the continuation for reducing (+ 1 1) is +C[(- 4 [])], not just C. The requirement specified in the first paragraph above is not met.

In contrast, (+ 1 1) is in tail position with respect +to (if (zero? 0) (+ 1 1) 3) because, for any continuation +C,

C[(if (zero? 0) (+ 1 1) 3)]  C[(if #t (+ 1 1) 3)]  C[(+ 1 1)]

The requirement specified in the first paragraph is met. +The steps in this reduction sequence are driven by the definition of +if, and they do not depend on the continuation +C. The “then” branch of an if form is always in +tail position with respect to the if form. Due to a +similar reduction rule for if and #f, the “else” +branch of an if form is also in tail position.

Tail-position specifications provide a guarantee about the +asymptotic space consumption of a computation. In general, the +specification of tail positions accompanies the description of +each syntactic form, such as if.

1.1.3 Multiple Return Values

A Racket expression can evaluate to multiple values, to +provide symmetry with the fact that a procedure can accept multiple arguments.

Most continuations expect a certain number of result +values, although some continuations can accept +an arbitrary number. Indeed, most continuations, such as (+ [] 1), expect a single value. The continuation +(let-values ([(x y) []]) expr) expects two result +values; the first result replaces x in the body +expr, and the second replaces y in +expr. The continuation (begin [] (+ 1 2)) accepts any number of result values, because it ignores +the result(s).

In general, the specification of a syntactic form indicates the +number of values that it produces and the number that it +expects from each of its sub-expressions. In addition, some procedures +(notably values) produce multiple values, and some +procedures (notably call-with-values) create continuations +internally that accept a certain number of values.

1.1.4 Top-Level Variables

Given

  x = 10

then an algebra student simplifies x + 1 as follows:

  x + 1 = 10 + 1 = 11

Racket works much the same way, in that a set of top-level +variables (see also Variables and Locations) are available for substitutions on demand during +evaluation. For example, given

(define x 10)

then

(+ x 1)  (+ 10 1)  11

In Racket, the way definitions are created is just as important as the way +they are used. Racket evaluation thus keeps track of both +definitions and the current expression, and it extends the set of +definitions in response to evaluating forms such as define.

Each evaluation step, then, transforms the current set of definitions and +program into a new set of definitions and program. Before a +define can be moved into the set of definitions, its +expression (i.e., its right-hand side) must be reduced to a value. +(The left-hand side is not an expression position, and so it is not evaluated.)

defined:

evaluate:

(begin (define x (+ 9 1)) (+ x 1))

defined:

evaluate:

(begin (define x 10) (+ x 1))

defined:

(define x 10)

evaluate:

(begin (void) (+ x 1))

defined:

(define x 10)

evaluate:

(+ x 1)

defined:

(define x 10)

evaluate:

(+ 10 1)

defined:

(define x 10)

evaluate:

11

Using set!, a program can change the value associated with an +existing top-level variable:

defined:

(define x 10)

evaluate:

(begin (set! x 8) x)

defined:

(define x 8)

evaluate:

(begin (void) x)

defined:

(define x 8)

evaluate:

x

defined:

(define x 8)

evaluate:

8

1.1.5 Objects and Imperative Update

In addition to set! for imperative update of top-level +variables, various procedures enable the modification of elements +within a compound data structure. For example, vector-set! +modifies the content of a vector.

To explain such modifications to data, we must distinguish between +values, which are the results of expressions, and +objects, which actually hold data.

A few kinds of objects can serve directly as values, including +booleans, (void), and small exact integers. More generally, +however, a value is a reference to an object stored somewhere +else. For example, a value can refer to a particular vector that +currently holds the value 10 in its first slot. If an +object is modified via one value, +then the modification is visible through +all the values that reference the object.

In the evaluation model, a set of objects must be carried along +with each step in evaluation, just like the definition set. Operations +that create objects, such as vector, add to the set of +objects:

objects:

defined:

evaluate:

(begin (define x (vector 10 20))
       (define y x)
       (vector-set! x 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 10 20))

defined:

evaluate:

(begin (define x <o1>)
       (define y x)
       (vector-set! x 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 10 20))

defined:

(define x <o1>)

evaluate:

(begin (void)
       (define y x)
       (vector-set! x 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 10 20))

defined:

(define x <o1>)

evaluate:

(begin (define y x)
       (vector-set! x 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 10 20))

defined:

(define x <o1>)

evaluate:

(begin (define y <o1>)
       (vector-set! x 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 10 20))

defined:

(define x <o1>)
(define y <o1>)

evaluate:

(begin (void)
       (vector-set! x 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 10 20))

defined:

(define x <o1>)
(define y <o1>)

evaluate:

(begin (vector-set! x 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 10 20))

defined:

(define x <o1>)
(define y <o1>)

evaluate:

(begin (vector-set! <o1> 0 11)
       (vector-ref y 0))

objects:

(define <o1> (vector 11 20))

defined:

(define x <o1>)
(define y <o1>)

evaluate:

(begin (void)
       (vector-ref y 0))

objects:

(define <o1> (vector 11 20))

defined:

(define x <o1>)
(define y <o1>)

evaluate:

(vector-ref y 0)

objects:

(define <o1> (vector 11 20))

defined:

(define x <o1>)
(define y <o1>)

evaluate:

(vector-ref <o1> 0)

objects:

(define <o1> (vector 11 20))

defined:

(define x <o1>)
(define y <o1>)

evaluate:

11

The distinction between a top-level variable and an object +reference is crucial. A top-level variable is not a +value, so it must be evaluated. Each time +a variable expression is evaluated, the +value of the variable is extracted from the current set of definitions. An object +reference, in contrast, is a value and therefore needs no further +evaluation. The evaluation steps above use angle-bracketed +<o1> for an object reference to distinguish it from a +variable name.

An object reference can never appear directly in a text-based source +program. A program representation created with +datum->syntax, however, can embed direct references to +existing objects.

1.1.6 Garbage Collection

+See Memory Management for functions related to +garbage collection.

In the program state

objects:

(define <o1> (vector 10 20))
(define <o2> (vector 0))

defined:

(define x <o1>)

evaluate:

(+ 1 x)

evaluation cannot depend on <o2>, because it is not part of +the program to evaluate, and it is not referenced by any definition +that is accessible by the program. The object is said to not +be reachable. The object <o2> may +therefore be removed from the program state by garbage +collection.

A few special compound datatypes hold weak references to +objects. Such weak references are treated specially by the garbage +collector in determining which objects are reachable for the +remainder of the computation. If an object is reachable only +via a weak reference, then the object can be reclaimed, and the +weak reference is replaced by a different value +(typically #f).

As a special case, a fixnum is always considered reachable by +the garbage collector. Many other values are always reachable due to +the way they are implemented and used: A character in the +Latin-1 range is always reachable, because equal? Latin-1 +characters are always eq?, and all of the Latin-1 characters +are referenced by an internal module. Similarly, null, +#t, #f, eof, and #<void> are +always reachable. Values produced by quote remain reachable +when the quote expression itself is reachable.

1.1.7 Procedure Applications and Local Variables

Given

  f(x) = x + 10

an algebra student simplifies f(7) as follows:

  f(7) = 7 + 10 = 17

The key step in this simplification is to take the body of the defined +function f and replace each x with the actual +value 7.

Racket procedure application works much the same way. A procedure is +an object, so evaluating (f 7) starts with a +variable lookup:

objects:

(define <p1> (lambda (x) (+ x 10)))

defined:

(define f <p1>)

evaluate:

(f 7)

objects:

(define <p1> (lambda (x) (+ x 10)))

defined:

(define f <p1>)

evaluate:

(<p1> 7)

Unlike in algebra, however, the value associated with a procedure +argument variable can be changed in the body of a procedure by using +set!, as in the example (lambda (x) (begin (set! x 3) x)). Since the value associated with argument variable x should be +able to change, we cannot just substitute the value in for x when +we first apply the procedure.

We do not use the term “parameter variable” to refer to +the argument variable names declared with a function. This choice avoids +confusion with parameters.

Instead, a new location is created for each variable +on each application. The argument value is placed in the +location, and each instance of the variable in the +procedure body is replaced with the new location:

objects:

(define <p1> (lambda (x) (+ x 10)))

defined:

(define f <p1>)

evaluate:

(<p1> 7)

objects:

(define <p1> (lambda (x) (+ x 10)))

defined:

(define f <p1>)
(define xloc 7)

evaluate:

(+ xloc 10)

objects:

(define <p1> (lambda (x) (+ x 10)))

defined:

(define f <p1>)
(define xloc 7)

evaluate:

(+ 7 10)

objects:

(define <p1> (lambda (x) (+ x 10)))

defined:

(define f <p1>)
(define xloc 7)

evaluate:

17

A location is the same as a top-level variable, but when +a location is generated, it (conceptually) uses a name that has +not been used before and that cannot be generated again or +accessed directly.

Generating a location in this way means that set! +evaluates for local variables, including argument +variables, in the same way as for +top-level variables, because the local variable is +always replaced with a location by the time the set! +form is evaluated:

objects:

(define <p1> (lambda (x) (begin (set! x 3) x)))

defined:

(define f <p1>)

evaluate:

(f 7)

objects:

(define <p1> (lambda (x) (begin (set! x 3) x)))

defined:

(define f <p1>)

evaluate:

(<p1> 7)

objects:

(define <p1> (lambda (x) (begin (set! x 3) x)))

defined:

(define f <p1>)
(define xloc 7)

evaluate:

(begin (set! xloc 3) xloc)

objects:

(define <p1> (lambda (x) (begin (set! x 3) x)))

defined:

(define f <p1>)
(define xloc 3)

evaluate:

(begin (void) xloc)

objects:

(define <p1> (lambda (x) (begin (set! x 3) x)))

defined:

(define f <p1>)
(define xloc 3)

evaluate:

xloc

objects:

(define <p1> (lambda (x) (begin (set! x 3) x)))

defined:

(define f <p1>)
(define xloc 3)

evaluate:

3

The location-generation and substitution step of procedure +application requires that the argument is a value. Therefore, +in ((lambda (x) (+ x 10)) (+ 1 2)), the (+ 1 2) +sub-expression must be simplified to the value 3, and +then 3 can be placed into a location for +x. In other words, Racket is a call-by-value +language.

Evaluation of a local-variable form, such as (let ([x (+ 1 2)]) expr), is the same as for a procedure call. After (+ 1 2) produces a value, it is stored in a fresh location +that replaces every instance of x in expr.

1.1.8 Variables and Locations

A variable is a placeholder for a value, and +expressions in an initial program refer to variables. A +top-level variable is both a variable and a +location. Any other variable is always replaced by a +location at run-time; thus, evaluation of expressions +involves only locations. A single local variable +(i.e., a non-top-level, non-module-level variable), such as an +argument variable, can correspond to different locations +during different applications.

For example, in the program

(define y (+ (let ([x 5]) x) 6))

both y and x are variables. The y +variable is a top-level variable, and the x is +a local variable. When this code is evaluated, a +location is created for x to hold the value +5, and a location is also created for y to +hold the value 11.

The replacement of a variable with a location during +evaluation implements Racket’s lexical scoping. +For the purposes of substituting xloc for x, +all variable bindings must use distinct names, so no x that +is really a different variable will get replaced. Ensuring that +distinction is one of the jobs of the macro expander; see Syntax Model. +For example, when an argument variable x is replaced by +the location xloc, it is replaced throughout the +body of the procedure, including any nested lambda +forms. As a result, future references to the variable always +access the same location.

1.1.9 Modules and Module-Level Variables

+See Modules: module, module*, ... for the syntax of modules.

Most definitions in Racket are in modules. In terms of evaluation, +a module is essentially a prefix on a defined name, so that different +modules can define the same name. That is, a module-level +variable is like a top-level variable from the perspective of +evaluation.

One difference between a module and a top-level definition +is that a module can be declared +without instantiating its module-level definitions. +Evaluation of a require instantiates +(i.e., triggers the instantiation of) the declared +module, which creates variables that correspond to its +module-level definitions.

For example, given the module declaration

(module m racket
  (define x 10))

the evaluation of (require 'm) creates the variable x +and installs 10 as its value. This x is unrelated to +any top-level definition of x (as if it were given a unique, +module-specific prefix).

1.1.9.1 Phases

+See also General Phase Levels in The Racket Guide.

The purpose of phases is to +address the necessary separation of names defined at execution time versus +names defined at expansion time.

A module can be instantiated in multiple phases. A +phase is an integer that, like a module name, is effectively a prefix on the names +of module-level definitions. Phase 0 is the execution-time phase.

A top-level require +instantiates a module at phase 0, if the module is not +already instantiated at phase 0. A top-level +(require (for-syntax ....)) instantiates a module at +phase 1 (if it is not already instantiated at that +phase); for-syntax also has a different binding +effect on further program parsing, as described in +Introducing Bindings.

Within a module, some definitions are already shifted by a phase: the +begin-for-syntax form is similar to begin, but it +shifts expressions and definitions by a relative phase +1. +Likewise, the define-for-syntax form is similar to define, +but shifts the definition by +1. +Thus, if the module is instantiated at phase 1, +the variables defined with begin-for-syntax are created at phase 2, +and so on. Moreover, this relative phase acts as another layer of +prefixing, so that x defined with define and +x defined with define-for-syntax can co-exist in a module +without colliding. A begin-for-syntax form can be nested +within a begin-for-syntax form, in which case the inner definitions and +expressions are in relative phase +2, and so on. Higher phases are +mainly related to program parsing instead of normal evaluation.

If a module instantiated at phase n +requires another module, then the required module is +first instantiated at phase n, and so on +transitively. (Module requires cannot form cycles.) If a +module instantiated at phase n requires +another module M for-syntax, then M becomes +available at phase n+1, and it later may be +instantiated at phase n+1. If a module that is +available at phase n (for n>0) requires +another module M for-template, then M becomes +available at phase n-1, and so +on. Instantiations of available modules above +phase 0 are triggered on demand as described in +Module Expansion, Phases, and Visits.

A final distinction among module instantiations is that +multiple instantiations may exist at phase 1 and +higher. These instantiations are created by the parsing of +module forms (see Module Expansion, Phases, and Visits), and are, again, conceptually +distinguished by prefixes.

Top-level variables can exist in multiple phases in the same way as +within modules. For example, define within begin-for-syntax creates a +phase 1 variable. Furthermore, reflective operations like +make-base-namespace and eval provide access to +top-level variables in higher phases, while module +instantiations (triggered by require) relative to such +top-levels are in correspondingly higher phases.

1.1.9.2 The Separate Compilation Guarantee

When a module is compiled, its phase 1 is instantiated. This +can, in turn, trigger the transitive instantiation of many other +modules at other phases, including phase 1. Racket provides a very +strong guarantee about this instantiation called +“The Separate +Compilation Guarantee”:

Any effects of the instantiation of the module’s phase 1 due +to compilation on the Racket runtime system are discarded.

The guarantee concerns effects. There are two different +kinds of effects: internal and external.

Internal effects are exemplified by mutation. Mutation is the action +of a function such as set-box!, which changes the value +contained in the box. The modified box is not observable outside +Racket, so the effect is said to be “internal.” By definition, +internal effects are not detectable outside the Racket program.

External effects are exemplified by input/output (I/O). I/O is the +action of a function such as tcp-connect, which communicates +with the operating system to send network packets outside the +machine running Racket. The transmission of these packets is +observable outside Racket, in particular by the receiving computer +or any routers in between. External effects exist to be detectable +outside the Racket program and are often detectable using physical +processes.

An effect is discarded when it is no longer detectable. For +instance, the mutation of a box from 3 to 4 is +discarded when it ceases to be detectable that it was ever changed and +thus would still contain 3. Because external effects are +intrinsically observable outside Racket, they are irreversible and +cannot be discarded.

Thus, The Separate Compilation Guarantee only concerns effects like +mutation, because they are exclusively effects “on the Racket runtime +system” and not “on the physical universe.”

There are many things a Racket program can do that appear to be +internal effects but are actually external effects. For instance, +bytes-set! is typically an internal effect, except when the +bytes are created by make-shared-bytes, which allocates in +space observable by other processes. Thus, effects which modify those +bytes are not discardable, so bytes-set!, in this case, has an +external effect.

The opposite is also true: some things which appear to be external are +actually internal. For instance, if a Racket program starts multiple +threads and uses mutation to communicate between them, that mutation +is purely internal, because Racket’s threads are defined entirely +internally (they are not related to operating system threads).

Furthermore, whenever a Racket program calls an unsafe +function, the Racket runtime system makes no promises about its +effects. For instance, all foreign calls use +ffi/unsafe, so all foreign calls are unsafe and their +effects cannot be discarded by Racket.

Finally, The Separate Compilation Guarantee only concerns +instantiations at phase 1 during compilation and not all phase 1 +instantiations generally, such as when its phase 1 is required and +used for effects via reflective mechanisms.

The practical consequence of this guarantee is that because effects +are never visible, no module can detect whether a module it +requires is already compiled. Thus, it can never change the +compilation of one module to have already compiled a different module. +In particular, if module A is shared by the phase 1 portion of modules +X and Y, then any internal effects while X is compiled are not visible +during the compilation of Y, regardless of whether X and Y are +compiled during the same execution of Racket’s runtime system and +regardless of the order of compilation.

The following set of modules demonstrate this guarantee. First, we +define a module with the ability to observe effects via a +box:

(module box racket/base
  (provide (all-defined-out))
  (define b (box 0)))

Next, we define two syntax transformers that use and mutate this box:

(module transformers racket/base
  (provide (all-defined-out))
  (require (for-syntax racket/base 'box))
  (define-syntax (sett stx)
    (set-box! b 2)
    #'(void))
  (define-syntax (gett stx)
    #`#,(unbox b)))

Next, we define a module that uses these transformers:

(module user racket/base
  (provide (all-defined-out))
  (require 'transformers)
  (sett)
  (define gott (gett)))

Finally, we define a second module that uses these +transformers and the user module:

(module test racket/base
  (require 'box 'transformers 'user)
  (displayln gott)
  (displayln (gett))
 
  (sett)
  (displayln (gett))
 
  (displayln (unbox b)))

This module displays: +
  • 2, because the (gett) in module user expanded to 2.

  • 0, because the effects of compiling user were discarded.

  • 2, because the effect of (sett) inside test has +not yet been discarded.

  • 0, because the effects of sett at +phase 1 are irrelevant to the phase 0 use of b in (unbox b).

Furthermore, this display will never change, regardless of which order +these modules are compiled in or whether they are compiled at the same +time or separately.

In contrast, if these modules were changed to store the value of +b in a file on the filesystem, then the program would only +display 2.

The Separate Compilation Guarantee is described in more detail +in the paper “Composable and Compilable Macros” [Flatt02], including +informative examples. The paper “Advanced Macrology and the +implementation of Typed Scheme” [Culpepper07] also contains an +extended example of why it is important and how to design effectful +syntactic extensions in its presence.

1.1.9.3 Cross-Phase Persistent Modules

Module declarations that fit a highly constrained +form—including a +(#%declare #:cross-phase-persistent) form in the +module body—create cross-phase persistent +modules. A cross-phase persistent module’s +instantiations across all phases share the variables +produced by the first instantiation of the module. +Additionally, cross-phase persistent module +instantiations persist across module registries when +they share a common module declaration.

Examples:
> (module cross '#%kernel
    (#%declare #:cross-phase-persistent)
    (#%provide x)
    (define-values (x) (gensym)))
> (module noncross '#%kernel
    (#%provide x)
    (define-values (x) (gensym)))
> (define ns (current-namespace))
> (define (same-instance? mod)
    (namespace-require mod)
    (define a
      (parameterize ([current-namespace (make-base-namespace)])
        (namespace-attach-module-declaration ns mod)
        (namespace-require mod)
        (namespace-variable-value 'x)))
    (define b
      (parameterize ([current-namespace (make-base-namespace)])
        (namespace-attach-module-declaration ns mod)
        (namespace-require mod)
        (namespace-variable-value 'x)))
    (eq? a b))
> (same-instance? ''noncross)

#f

> (same-instance? ''cross)

#t

The intent of a cross-phase persistent module is to support values that are +recognizable after phase crossings. For example, when a macro +transformer running in phase 1 raises a syntax error as represented by +an exn:fail:syntax instance, the instance is recognizable by a +phase-0 exception handler wrapping a call to eval or +expand that triggered the syntax error, because the +exn:fail:syntax structure type is defined by a +cross-phase persistent module.

A cross-phase persistent module imports only other cross-phase persistent modules, +and it contains only definitions that bind variables to functions, +structure types and related functions, or structure-type properties +and related functions. A cross-phase persistent module never includes syntax +literals (via quote-syntax) or variable references (via +#%variable-reference). See Cross-Phase Persistent Module Declarations for +the syntactic specification of a cross-phase persistent module +declaration.

A documented module should be assumed non–cross-phase persistent unless it +is specified as cross-phase persistent (such as +racket/kernel).

1.1.9.4 Module Redeclarations

When a module is declared using a name with which a module is already +declared, the new declaration’s definitions replace and extend the old +declarations. If a variable in the old declaration has no counterpart +in the new declaration, the old variable continues to exist, but its +binding is not included in the lexical information for the +module body. If a new variable definition has a counterpart in the old +declaration, it effectively assigns to the old variable.

If a module is instantiated in the current namespace’s +base phase before the module is redeclared, the redeclaration +of the module is immediately instantiated in that +phase.

If the current inspector does not manage a module’s declaration +inspector (see Code Inspectors), then the module cannot be +redeclared. Similarly, a cross-phase persistent module cannot be redeclared. +Even if redeclaration succeeds, instantiation of a module that is +previously instantiated may fail if instantiation for the +redeclaration attempts to modify variables that are constant (see +compile-enforce-module-constants).

1.1.9.5 Submodules

A module or module* form within a top-level +module form declares a submodule. A submodule is +accessed relative to its enclosing module, usually with a +submod path. Submodules can be nested to any depth.

Although a submodule is lexically nested within a module, it cannot +necessarily access the bindings of its enclosing module directly. +More specifically, a submodule declared with module cannot +require from its enclosing module, but the enclosing module +can require the submodule. In contrast, a submodule declared +with module* conceptually follows its enclosing module, so +can require from its enclosing module, but the enclosing +module cannot require the submodule. Unless a submodule +imports from its enclosing module or vice versa, then visits or +instantiations of the two modules are independent, and their +implementations may even be loaded from bytecode sources at different times.

A submodule declared with module can import any preceding +submodule declared with module. A submodule declared with +module* can import any preceding module declared with +module* and any submodule declared with module.

When a submodule declaration has the form (module* name #f ....), then all of the bindings of the enclosing module’s bodies are +visible in the submodule’s body, and the submodule implicitly imports +the enclosing module. The submodule can provide any bindings +that it inherits from its enclosing module.

1.1.10 Continuation Frames and Marks

+See Continuation Marks for continuation-mark forms and functions.

Every continuation C can be partitioned into +continuation frames C1, C2, ..., Cn +such that C = C1[C2[...[Cn]]], and no frame Ci can be itself partitioned +into smaller continuations. Evaluation steps add frames to and remove frames from +the current continuation, typically one at a time.

Each frame is conceptually annotated with a set of +continuation marks. A mark consists of a key and its value. +The key is an arbitrary value, and each frame includes at most one +mark for any given key. Various operations set and extract marks from +continuations, so that marks can be used to attach information to a +dynamic extent. For example, marks can be used to record information +for a “stack trace” to be presented when an exception is raised, or +to implement dynamic scope.

1.1.11 Prompts, Delimited Continuations, and Barriers

+See Continuations for continuation and prompt functions.

A prompt is a special kind of continuation frame that is +annotated with a specific prompt tag (essentially a +continuation mark). Various operations allow the capture of frames in +the continuation from the redex position out to the nearest enclosing +prompt with a particular prompt tag; such a continuation is sometimes +called a delimited continuation. Other operations allow the +current continuation to be extended with a captured continuation +(specifically, a composable continuation). Yet other +operations abort the computation to the nearest enclosing prompt with +a particular tag, or replace the continuation to the nearest enclosing +prompt with another one. When a delimited continuation is captured, +the marks associated with the relevant frames are also captured.

A continuation barrier is another kind of continuation frame +that prohibits certain replacements of the current continuation with +another. Specifically, a continuation can be replaced by another only +when the replacement does not introduce any continuation barriers. +A continuation barrier +thus prevents “downward jumps” into a continuation that is protected +by a barrier. Certain operations install barriers automatically; in +particular, when an exception handler is called, a continuation +barrier prohibits the continuation of the handler from capturing the +continuation past the exception point.

An escape continuation is essentially a derived concept. It +combines a prompt for escape purposes with a continuation for +mark-gathering purposes. As the name implies, escape continuations are +used only to abort to the point of capture.

1.1.12 Threads

+See Concurrency and Parallelism for thread and synchronization functions.

Racket supports multiple threads of evaluation. Threads run +concurrently, in the sense that one thread can preempt another without +its cooperation, but threads currently all run on the same processor +(i.e., the same underlying operating system process and thread).

Threads are created explicitly by functions such as thread. +In terms of the evaluation model, each step in evaluation +actually deals with multiple concurrent +expressions, up to one per thread, rather than a single expression. The expressions all +share the same objects and top-level variables, so that they can +communicate through shared state, and sequential consistency [Lamport79] is +guaranteed (i.e., the result is consistent with some global sequence +imposed on all evaluation steps across threads). Most evaluation steps involve a +single step in a single thread, but certain synchronization +primitives require multiple threads to progress together in one step; for example, +an exchange of a value through a channel progresses in two +threads simultaneously.

Unless otherwise noted, all constant-time procedures and operations +provided by Racket are thread-safe in the sense that they are +atomic: they happen as a single evaluation step. +For example, set! assigns to a variable as an atomic action +with respect to all threads, so that no thread can see a +“half-assigned” variable. Similarly, vector-set! assigns to +a vector atomically. Note that the evaluation of a set! +expression with its subexpression is not necessarily atomic, because +evaluating the subexpression involves a separate step of evaluation. +Only the assignment action itself (which takes after the subexpression +is evaluated to obtain a value) is atomic. Similarly, a procedure +application can involve multiple steps that are not atomic, even if +the procedure itself performs an atomic action.

The hash-set! procedure is not atomic, but the table is +protected by a lock; see Hash Tables for more information. +Port operations are generally not atomic, but they are thread-safe in +the sense that a byte consumed by one thread from an input port will +not be returned also to another thread, and procedures like +port-commit-peeked and write-bytes-avail offer +specific concurrency guarantees.

In addition to the state that is shared among all threads, each thread +has its own private state that is accessed through thread +cells. A thread cell is similar to a normal mutable object, but a +change to the value inside a thread cell is seen only when extracting +a value from that cell in the same thread. A thread cell can be +preserved; when a new thread is created, the creating +thread’s value for a preserved thread cell serves as the initial value +for the cell in the created thread. For a non-preserved thread cell, a +new thread sees the same initial value (specified when the thread cell +is created) as all other threads.

Futures and places offer different kinds of concurrency +and parallelism, and they have weaker guarantees about shared state. +(Places can share state through functions like +make-shared-bytes.) Each thread of evaluation in a future or +place is constrained to behave consistent with the possibility of some +other thread that might inspect any shared data starting at any point +that a future or place starts. In the case that two futures or two +places share state, each read or write operation to shared state +corresponds to a read or write operation at the virtual-memory level, +and the operations are constrained to the order they could be observed +or affected by a thread. However, Racket does not enforce additional +guarantees about reordering that might be performed at the +virtual-memory level or below, except in the case of operations that +specify such guarantees explicitly (e.g., box-cas!).

1.1.13 Parameters

+See Parameters for parameter forms and functions.

Parameters are essentially a derived concept in Racket; they +are defined in terms of continuation marks and thread +cells. However, parameters are also “built in,” due to the fact that some +primitive procedures consult parameter values. For example, the +default output stream for primitive output operations is specified by +a parameter.

A parameter is a setting that is both thread-specific and +continuation-specific. In the empty continuation, each parameter +corresponds to a preserved thread cell; a corresponding +parameter procedure accesses and sets the thread cell’s +value for the current thread.

In a non-empty continuation, a parameter’s value is determined through +a parameterization that is associated with the nearest +enclosing continuation frame via a continuation mark (whose key is +not directly accessible). A parameterization maps each parameter to a +preserved thread cell, and the combination of the thread cell and the current +thread yields the parameter’s value. A parameter procedure sets or +accesses the relevant thread cell for its parameter.

Various operations, such as parameterize or +call-with-parameterization, install a parameterization into +the current continuation’s frame.

1.1.14 Exceptions

+See Exceptions for exception forms, functions, and types.

Exceptions are essentially a derived concept in Racket; they +are defined in terms of continuations, prompts, and continuation +marks. However, exceptions are also “built in,” due to the fact that +primitive forms and procedures may raise exceptions.

An exception handler to catch exceptions can be associated +with a continuation frame though a continuation mark (whose key +is not directly accessible). When an exception is raised, the current +continuation’s marks determine a chain of exception handler +procedures that are consulted to handle the exception. +A handler for uncaught exceptions is designated through a built-in parameter.

One potential action of an exception handler is to abort the +current continuation up to an enclosing prompt with a +particular prompt tag. The default handler for uncaught +exceptions, in particular, aborts to a particular tag for which a +prompt is always present, because the prompt is installed in the +outermost frame of the continuation for any new thread.

1.1.15 Custodians

+See Custodians for custodian functions.

A custodian manages a collection of threads, +file-stream ports, TCP ports, TCP listeners, UDP +sockets, byte converters, and places. Whenever a thread, etc., is +created, it is placed under the management of the current +custodian as determined by the current-custodian +parameter.

Custodians also manage eventspaces from +racket/gui/base.

Except for the root custodian, every custodian itself is +managed by a custodian, so that custodians form a hierarchy. +Every object managed by a subordinate custodian is also managed by the +custodian’s owner.

When a custodian is shut down via +custodian-shutdown-all, it forcibly and immediately closes +the ports, TCP connections, etc., that it manages, as well as +terminating (or suspending) its threads. A custodian that has been +shut down cannot manage new objects. After the current custodian is shut +down, if a procedure is called that attempts to create a managed resource (e.g., +open-input-file, thread), then the +exn:fail:contract exception is raised.

A thread can have multiple managing custodians, and a suspended thread +created with thread/suspend-to-kill can have zero +custodians. Extra custodians become associated with a thread through +thread-resume (see Suspending, Resuming, and Killing Threads). When a thread +has multiple custodians, it is not necessarily killed by a +custodian-shutdown-all. Instead, shut-down custodians are removed +from the thread’s managing custodian set, and the thread is killed when its +managing set becomes empty.

The values managed by a custodian are semi-weakly held by the +custodian: a will can be executed for a value that is +managed by a custodian; in addition, weak references via weak +hash tables, ephemerons, or weak boxes can be +dropped on the BC implementation of Racket, but not on the CS +implementation. For all variants, a custodian only weakly +references its subordinate custodians; if a subordinate custodian is +unreferenced but has its own subordinates, then the custodian may be +garbage collected, at which point its subordinates become immediately +subordinate to the collected custodian’s superordinate (owner) custodian.

In addition to the other entities managed by a custodian, a +custodian box created with make-custodian-box +strongly holds onto a value placed in the box until the box’s +custodian is shut down. However, the custodian only weakly retains the box +itself, so the box and its content can be collected if there +are no other references to them.

When Racket is compiled with support for per-custodian memory +accounting (see custodian-memory-accounting-available?), the +current-memory-use procedure can report a custodian-specific +result. This result determines how much memory is occupied by objects +that are reachable from the custodian’s managed values, especially its +threads, and including its sub-custodians’ managed values. If an +object is reachable from two custodians where neither is an ancestor +of the other, an object is arbitrarily charged to one or the other, +and the choice can change after each collection; objects reachable +from both a custodian and its descendant, however, are reliably +charged to the custodian and not to the descendants, unless the +custodian can reach the objects only through a descendant custodian or +a descendant’s thread. Reachability for per-custodian accounting does +not include weak references, references to threads managed by other +custodians, references to other custodians, or references to custodian +boxes for other custodians.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/eval.html b/clones/docs.racket-lang.org/reference/eval.html new file mode 100644 index 00000000..d08369d8 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/eval.html @@ -0,0 +1,347 @@ + +14.2 Evaluation and Compilation

14.2 Evaluation and Compilation

+Reflection and Dynamic Evaluation in The Racket Guide introduces dynamic evaluation.

Racket provides programmatic control over evaluation through +eval and related functions. See Controlling and Inspecting Compilation for +information about extra-linguistic facilities related to the Racket +compiler.

parameter

(current-eval)  (any/c . -> . any)

(current-eval proc)  void?
  proc : (any/c . -> . any)
A parameter that determines the current evaluation handler. +The evaluation handler is a procedure that takes a top-level form and +evaluates it, returning the resulting values. The evaluation +handler is called by eval, eval-syntax, the default +load handler, and read-eval-print-loop to evaluate a +top-level form. The handler should evaluate its argument in tail +position.

The top-level-form provided to the handler can be a +syntax object, a compiled form, a compiled form wrapped as a +syntax object, or an arbitrary datum.

The default handler converts an arbitrary datum to a syntax object +using datum->syntax, and then enriches its lexical +information in the same way as eval. (If +top-level-form is a syntax object, then its lexical +information is not enriched.) The default evaluation handler +partially expands the form to splice the body of top-level +begin forms into the top level (see +expand-to-top-form), and then individually compiles and +evaluates each spliced form before continuing to expand, compile, and +evaluate later forms.

procedure

(eval top-level-form [namespace])  any

  top-level-form : any/c
  namespace : namespace? = (current-namespace)

Calls the current evaluation handler to evaluate +top-level-form. The evaluation handler is called in +tail position with respect to the eval call, and +parameterized to set current-namespace to +namespace.

If top-level-form is a syntax object whose datum is not a +compiled form, then its lexical information is enriched before +it is sent to the evaluation handler:

For interactive evaluation in the style of +read-eval-print-loop and load, wrap each expression +with #%top-interaction, which is normally bound to +#%top-interaction, before passing it to eval.

procedure

(eval-syntax stx [namespace])  any

  stx : syntax?
  namespace : namespace? = (current-namespace)
Like eval, except that stx must be a syntax object, +and its lexical context is not enriched before it is passed to the +evaluation handler.

parameter

(current-load)

  
(path? (or/c #f
             symbol?
             (cons/c (or/c #f symbol?)
                     (non-empty-listof symbol?)))
       . -> .
       any)
(current-load proc)  void?
  proc : 
(path? (or/c #f
             symbol?
             (cons/c (or/c #f symbol?)
                     (non-empty-listof symbol?)))
       . -> .
       any)
A parameter that determines the current load handler to load +top-level forms from a file. The load handler is called by +load, load-relative, load/cd, and the +default compiled-load handler.

A load handler takes two arguments: a path (see Paths) +and an expected module name. The expected module name is a symbol or a +list when the call is to load a module declaration in response to a +require (in which case the file should contain a module +declaration), or #f for any other load.

When loading a module from a stream that starts with a compiled module +that contains submodules, the load handler should load only the +requested module, where a symbol as the load handler’s indicates the +root module and a list indicates a submodule whose path relative to +the root module is given by the cdr of the list. The list +starts with #f when a submodule should be loaded only +if it can be loaded independently (i.e., from compiled form—never +from source); if the submodule cannot be loaded independently, the +load handler should return without loading from a file. When the +expected module name is a list that starts with a symbol, the root +module and any other submodules can be loaded from the given file, +which might be from source, and the load handler still should not +complain if the expected submodule is not found. +When loading modules from a nonexistent source file, the load handler +may raise an exception regardless of whether submodules are +requested or not.

The default load handler reads forms from the file in +read-syntax mode with line-counting enabled for the file +port, unless the path has a ".zo" suffix. It also +parameterizes each read to set read-accept-compiled, +read-accept-reader, and read-accept-lang to +#t. In addition, if load-on-demand-enabled is +#t, then read-on-demand-source is set to +the cleansed, absolute form of path during the +read-syntax call. After reading a single form, the form is +passed to the current evaluation handler, wrapping the +evaluation in a continuation prompt (see +call-with-continuation-prompt) for the default continuation +prompt tag with handler that propagates the abort to the continuation +of the load call.

If the second argument to the load handler is a symbol, then:

If the second argument to the load handler is #f, then each +expression read from the file is wrapped with +#%top-interaction, which is normally bound to +#%top-interaction, before passing it to the evaluation +handler.

The return value from the default load handler is the value of +the last form from the loaded file, or #<void> if the file +contains no forms. If the given path is a relative path, then it is +resolved using the value of current-directory.

procedure

(load file)  any

  file : path-string?

Calls the current load handler in tail position. The call is +parameterized to set current-load-relative-directory +to the directory of file, which is resolved relative to +the value of current-directory.

procedure

(load-relative file)  any

  file : path-string?
Like load/use-compiled, but when file is a relative +path, it is resolved using the value of +current-load-relative-directory instead of the value of +current-directory if the former is not #f, otherwise +current-directory is used.

procedure

(load/cd file)  any

  file : path-string?
Like load, but load/cd sets both +current-directory and +current-load-relative-directory before calling the load +handler.

parameter

(current-load-extension)

  
(path? (or/c #f
             symbol?
             (cons/c (or/c #f symbol?)
                     (non-empty-listof symbol?)))
 . -> .
 any)
(current-load-extension proc)  void?
  proc : 
(path? (or/c #f
             symbol?
             (cons/c (or/c #f symbol?)
                     (non-empty-listof symbol?)))
 . -> .
 any)
A parameter that determines a extension-load handler, which is +called by load-extension and the default compiled-load +handler.

An extension-load handler takes the same arguments as a +load handler, but the file should be a platform-specific +dynamic extension, typically with the file suffix +".so" (Unix), ".dll" (Windows), or ".dylib" +(Mac OS). The file is loaded using internal, OS-specific +primitives. See Inside: Racket C API for more information on +dynamic extensions.

Extensions are supported only when (system-type 'vm) returns +'racket.

procedure

(load-extension file)  any

  file : path-string?
Sets current-load-relative-directory like load, and +calls the extension-load handler in tail position.

Extensions are supported only when (system-type 'vm) returns +'racket.

procedure

(load-relative-extension file)  any

  file : path-string?
Like load-extension, but resolves file using +current-load-relative-directory like load-relative.

Extensions are supported only when (system-type 'vm) returns +'racket.

parameter

(current-load/use-compiled)

  
(path? (or/c #f
             symbol?
             (cons/c (or/c #f symbol?)
                     (non-empty-listof symbol?)))
       . -> . any)
(current-load/use-compiled proc)  void?
  proc : 
(path? (or/c #f
             symbol?
             (cons/c (or/c #f symbol?)
                     (non-empty-listof symbol?)))
       . -> . any)
A parameter that determines the current compiled-load +handler to load from a file that may have a compiled form. The +compiled-load handler is called by load/use-compiled.

The protocol for a compiled-load handler is the same as for the +load handler (see current-load), except that a +compiled-load handler is expected to set +current-load-relative-directory itself. Additionally, the default +compiled-load handler does the following:

  • When the given path ends with ".rkt", no ".rkt" +file exists, and when the handler’s second argument is not #f, +the default compiled-load handler checks for a ".ss" file.

  • The default compiled-load handler checks for the opportunity +to load from ".zo" (bytecode) files and, when (system-type 'vm) +returns 'racket, for ".so" (native Unix), ".dll" (native Windows), +or ".dylib" (native Mac OS) files.

  • When the default compiled-load handler needs to load from +the given path, the given path does not exist, and when the handler’s +second argument is not #f, +the default compiled-load handler returns without +raising an exception.

The check for a compiled file occurs whenever the given path +file ends with any extension (e.g., ".rkt" or +".scrbl"), and the check consults the subdirectories +indicated by the current-compiled-file-roots and +use-compiled-file-paths parameters relative to +file, where the former supplies “roots” for compiled files +and the latter provides subdirectories. +See also compiler/compilation-path. +A “root” can be an absolute +path, in which case file’s directory is combined with +reroot-path and the root as the second argument; if the +“root” is a relative path, then the relative path is instead +suffixed onto the directory of file. The roots are tried in +order, and the subdirectories are checked in order within each root. A +".zo" version of the file (whose name is formed by passing +file and #".zo" to path-add-extension) is +loaded if it exists directly in one of the indicated subdirectories, +or when (system-type 'vm) returns +'racket, then a ".so"/".dll"/".dylib" version of the +file is loaded if it exists within a "native" subdirectory of +a use-compiled-file-paths directory, in an even deeper +subdirectory as named by system-library-subpath. A compiled +file is loaded only if it checks out according to +(use-compiled-file-check); with the default parameter value +of 'modify-seconds, a compiled file is used only if its +modification date is not older than the +date for file. If both ".zo" and +".so"/".dll"/".dylib" files are available +when (system-type 'vm) returns 'racket, +the ".so"/".dll"/".dylib" file is used. If +file ends with ".rkt", no such file exists, the +handler’s second argument is a symbol, and a ".ss" file +exists, then ".zo" and +".so"/".dll"/".dylib" files are used only +with names based on file with its suffixed replaced by +".ss".

While a ".zo", ".so", ".dll", or +".dylib" file is loaded, the current load-relative +directory is set to the directory of the original file. If +the file to be loaded has the suffix ".ss" while the +requested file has the suffix ".rkt", then the +current-module-declare-source parameter is set to the full +path of the loaded file, otherwise the +current-module-declare-source parameter is set to +#f.

If the original file is loaded or a ".zo" variant is +loaded, the load handler is called to load the file. If any +other kind of file is loaded, the extension-load handler is +called.

When the default compiled-load handler loads a module from a +bytecode (i.e., ".zo") file, the handler records the bytecode +file path in the current namespace’s module registry. More +specifically, the handler records the path for the top-level module of +the loaded module, which is an enclosing module if the loaded module +is a submodule. Thereafter, loads via the default compiled-load +handler for modules within the same top-level module use the recorded +file, independent of the file that otherwise would be selected by the +compiled-load handler (e.g., even if the +use-compiled-file-paths parameter value changes). The default +module name resolver transfers bytecode-file information when a +module declaration is attached to a new namespace. This protocol supports +independent but consistent loading of submodules from bytecode files.

procedure

(load/use-compiled file)  any

  file : path-string?
Calls the current compiled-load handler in tail position.

When a new path or string is provided as the parameter’s value, it is +immediately expanded (see Paths) and converted to a +path. (The directory need not exist.)

A list of relative paths, which defaults to (list (string->path "compiled")). It is used by the compiled-load +handler (see current-load/use-compiled).

If the PLT_ZO_PATH environment variable is set on +startup, it supplies a path instead of "compiled" to +use for the initial parameter value.

Changed in version 7.7.0.9 of package base: Added PLT_ZO_PATH.

parameter

(current-compiled-file-roots)  (listof (or/c path? 'same))

(current-compiled-file-roots paths)  void?
  paths : (listof (or/c path-string? 'same))
A list of paths and 'sames that is is used by the default +compiled-load handler (see current-load/use-compiled).

The parameter is normally initialized to (list 'same), but +the parameter’s initial value can be adjusted by the installation +configuration as reported by (find-compiled-file-roots), +and it can be further adjusted by the +PLTCOMPILEDROOTS environment variable or the +--compiled or -R command-line flag for racket. If +the environment variable is defined and not overridden by a +command-line flag, it is parsed by first replacing any +@(version) with the result of (version), then using +path-list-string->path-list with a path list produced by +(find-compiled-file-roots) to arrive at the parameter’s +initial value.

procedure

(find-compiled-file-roots)  (listof (or/c path? 'same))

Produces a list of paths and 'same, which is normally used to +initialize current-compiled-file-roots. The list is +determined by consulting the "config.rtkd" file in the +directory reported by (find-config-dir), and it defaults to +(list 'same) if not configured there.

See also 'compiled-file-roots in Installation Configuration and Search Paths.

Added in version 8.0.0.9 of package base.

parameter

(use-compiled-file-check)  (or/c 'modify-seconds 'exists)

(use-compiled-file-check check)  void?
  check : (or/c 'modify-seconds 'exists)
A parameter that determines how a compiled file is checked +against its source to enable use of the compiled file. By default, the +file-check mode is 'modify-seconds, which uses a compiled +file when its filesystem modification date is at least as new as the +source file’s. The 'exists mode causes a compiled file to be +used in place of its source as long as the compiled file exists.

If the PLT_COMPILED_FILE_CHECK environment variable is +set to modify-seconds or exists, then the +environment variable’s value configures the parameter when Racket +starts.

Added in version 6.6.0.3 of package base.

procedure

(read-eval-print-loop)  any

Starts a new REPL using the current input, output, and error +ports. The REPL wraps each expression to evaluate with +#%top-interaction, which is normally bound to +#%top-interaction, and it wraps each evaluation with a +continuation prompt using the default continuation prompt tag and +prompt handler (see call-with-continuation-prompt). The REPL +also wraps the read and print operations with a prompt for the default +tag whose handler ignores abort arguments and continues the loop. The +read-eval-print-loop procedure does not return until +eof is read, at which point it returns #<void>.

The read-eval-print-loop procedure can be configured through +the current-prompt-read, current-eval, and +current-print parameters.

parameter

(current-prompt-read)  (-> any)

(current-prompt-read proc)  void?
  proc : (-> any)
A parameter that determines a prompt read handler, which is +a procedure that takes no arguments, displays a prompt string, and +returns a top-level form to evaluate. The prompt read handler is +called by read-eval-print-loop, and after printing a prompt, +the handler typically should call the read interaction handler +(as determined by the current-read-interaction parameter) +with the port produced by the interaction port handler +(as determined by the current-get-interaction-input-port parameter).

The default prompt read handler prints >  and returns the +result of

(let ([in ((current-get-interaction-input-port))])
  ((current-read-interaction) (object-name in) in))

If the input and output ports are both terminals (in the sense of +terminal-port?) and if the output port appears to be counting +lines (because port-next-location returns a non-#f +line and column), then the output port’s line is incremented and its +column is reset to 0 via set-port-next-location! +before returning the read result.

A parameter that determines the interaction port handler, +which returns a port to use for read-eval-print-loop inputs.

The default interaction port handler returns the current input port. +In addition, if that port is the initial current input port, +the initial current output and error ports are flushed.

The racket/gui/base library adjusts this parameter’s +value by extending the current value. The extension wraps the result +port so that GUI events can be handled when reading from the port +blocks.

parameter

(current-get-interaction-evt)  (-> evt?)

(current-get-interaction-evt proc)  void?
  proc : (-> evt?)
A parameter that determines the interaction event +handler, which returns an synchronizable event that should be +used in combination with blocking that is similar to +read-eval-print-loop waiting for input—but where an input +port is not read directly, so +current-get-interaction-input-port does not apply.

When the interaction event handler returns an event that becomes +ready, and when the event’s ready value is a procedure, then the +procedure is meant to be called with zero arguments blocking resumes. +The default interaction event handler returns never-evt.

The racket/gui/base library adjusts this parameter’s +value by extending the current value. The extension combines the +current value’s result with choice-evt and an event that +becomes ready when a GUI event is available, and the event’s value is +a procedure that yields to one or more available GUI events.

Added in version 8.3.0.3 of package base.

A parameter that determines the current read interaction +handler, which is procedure that takes an arbitrary value and an +input port and returns an expression read from the input port.

The default read interaction handler accepts src and +in and returns

(parameterize ([read-accept-reader #t]
               [read-accept-lang #f])
  (read-syntax src in))

parameter

(current-print)  (any/c -> any)

(current-print proc)  void?
  proc : (any/c -> any)
A parameter that determines the print handler that is called + by read-eval-print-loop to print the result of an evaluation + (and the result is ignored).

The default print handler prints the value to the + current output port (as determined by the + current-output-port parameter) and then outputs a newline, + except that it prints nothing when the value is #<void>.

parameter

(current-compile)

  (any/c boolean? . -> . compiled-expression?)
(current-compile proc)  void?
  proc : (any/c boolean? . -> . compiled-expression?)
A parameter that determines the current compilation handler. +The compilation handler is a procedure that takes a top-level form and +returns a compiled form; see Compilation for +more information on compilation.

The compilation handler is called by compile, and +indirectly by the default evaluation handler and the default +load handler.

The handler’s second argument is #t if the compiled form will +be used only for immediate evaluation, or #f if the compiled +form may be saved for later use; the default compilation handler is +optimized for the special case of immediate evaluation.

When a compiled form is written to an output port, the written form +starts with #~. See Printing Compiled Code for more +information.

For internal testing purposes, when the +PLT_VALIDATE_COMPILE environment variable is set, +the default compilation handler runs a bytecode validator immediately +on its own compilation results (instead of relying only on validation +when compiled bytecode is loaded).

The current-compile binding is provided as protected +in the sense of protect-out.

Changed in version 8.2.0.4 of package base: Changed binding to protected.

procedure

(compile top-level-form)  compiled-expression?

  top-level-form : any/c
Like eval, but calls the current compilation handler in +tail position with top-level-form.

procedure

(compile-syntax stx)  compiled-expression?

  stx : syntax?
Like eval-syntax, but calls the current compilation +handler in tail position with stx.

Recompiles ce. If ce was compiled as +machine-independent and current-compile-target-machine is +not set to #f, then recompiling effectively converts to the current +machine format. Otherwise, recompiling effectively re-runs +optimization passes to produce an equivalent compiled form with +potentially different performance characteristics.

Added in version 6.3 of package base.

procedure

(compiled-expression? v)  boolean?

  v : any/c
Returns #t if v is a compiled form, #f +otherwise.

A parameter that determines how a module declaration is compiled.

When constants are enforced, and when the macro-expanded body of a +module contains no set! assignment to a particular variable +defined within the module, then the variable is marked as constant +when the definition is evaluated. Afterward, the variable’s value +cannot be assigned or undefined through module->namespace, +and it cannot be defined by redeclaring the module.

Enforcing constants allows the compiler to inline some variable +values, and it allows the native-code just-in-time compiler to +generate code that skips certain run-time checks.

parameter

(compile-allow-set!-undefined)  boolean?

(compile-allow-set!-undefined allow?)  void?
  allow? : any/c
A parameter that determines how a set! expression is compiled +when it mutates a global variable. If the value of this parameter is a +true value, set! expressions for global variables are +compiled so that the global variable is set even if it was not +previously defined. Otherwise, set! expressions for global +variables are compiled to raise the +exn:fail:contract:variable exception if the global variable +is not defined at the time the set! is performed. Note that +this parameter is used when an expression is compiled, not +when it is evaluated.

A parameter that determines whether compilation should avoid +function-call inlining and other optimizations that may cause +information to be lost from stack traces (as reported by +continuation-mark-set->context). The default is #f, +which allows such optimizations.

A parameter that determines the platform and/or virtual machine +target for a newly compiled expression.

If the target is #f, the the compiled expression writes in a +machine-independent format (usually in ".zo" files). +Machine-independent compiled code works for any platform and any +Racket virtual machine. When the machine-independent compiled +expression is read back in, it is subject to further compilation for +the current platform and virtual machine, which can be considerably +slower than reading a format that is fully compiled for a platform and +virtual machine.

The default is something other than #f, unless +machine-independent mode is enabled through the +-M/--compile-any command-line flag to stand-alone Racket +(or GRacket) or through the PLT_COMPILE_ANY +environment variable (set to any value).

Added in version 7.1.0.6 of package base.

procedure

(compile-target-machine? sym)  boolean?

  sym : symbol?
Reports whether sym is a supported compilation target for the +currently running Racket.

When (system-type 'vm) reports 'racket, then the +only target symbol is 'racket. When (system-type 'vm) reports 'chez-scheme, then a symbol corresponding to +the current platform is a target, and other targets may also be +supported. The 'target-machine mode of system-type +reports the running Racket’s native target machine.

Added in version 7.1.0.6 of package base.

parameter

(current-compile-realm)  symbol?

(current-compile-realm realm)  void?
  realm : symbol?
Determines the realm that is assigned to modules and procedures +when they are compiled.

Added in version 8.4.0.2 of package base.

parameter

(eval-jit-enabled)  boolean?

(eval-jit-enabled on?)  void?
  on? : any/c

A parameter that determines whether the native-code just-in-time +compiler (JIT) is enabled for code (compiled or not) that is passed to +the default evaluation handler. A true parameter value is effective +only on platforms for which the JIT is supported and for Racket virtual machines +that rely on a JIT.

The default is #t, unless the JIT is not supported by the +current platform but is supported on the same virtual machine for other +platforms, unless it is disabled through the +-j/--no-jit command-line flag to stand-alone Racket (or +GRacket), and unless it is disabled through the +PLTNOMZJIT environment variable (set to any +value).

parameter

(load-on-demand-enabled)  boolean?

(load-on-demand-enabled on?)  void?
  on? : any/c
A parameter that determines whether the default load handler +sets read-on-demand-source. See current-load for +more information. The default is #t, unless it is disabled +through the -d/--no-delay command-line flag.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/exns.html b/clones/docs.racket-lang.org/reference/exns.html new file mode 100644 index 00000000..f955a218 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/exns.html @@ -0,0 +1,507 @@ + +10.2 Exceptions
On this page:
10.2.1 Error Message Conventions
10.2.2 Raising Exceptions
raise
error
raise-user-error
raise-argument-error
raise-argument-error*
raise-result-error
raise-result-error*
raise-arguments-error
raise-arguments-error*
raise-range-error
raise-range-error*
raise-type-error
raise-mismatch-error
raise-arity-error
raise-arity-error*
raise-arity-mask-error
raise-arity-mask-error*
raise-result-arity-error
raise-result-arity-error*
raise-syntax-error
unquoted-printing-string?
unquoted-printing-string
unquoted-printing-string-value
10.2.3 Handling Exceptions
call-with-exception-handler
uncaught-exception-handler
with-handlers
with-handlers*
10.2.4 Configuring Default Handling
error-escape-handler
error-display-handler
error-print-width
error-print-context-length
error-print-source-location
error-value->string-handler
error-syntax->string-handler
10.2.5 Built-in Exception Types
exn
exn:  fail
exn:  fail:  contract
exn:  fail:  contract:  arity
exn:  fail:  contract:  divide-by-zero
exn:  fail:  contract:  non-fixnum-result
exn:  fail:  contract:  continuation
exn:  fail:  contract:  variable
exn:  fail:  syntax
exn:  fail:  syntax:  unbound
exn:  fail:  syntax:  missing-module
exn:  fail:  read
exn:  fail:  read:  eof
exn:  fail:  read:  non-char
exn:  fail:  filesystem
exn:  fail:  filesystem:  exists
exn:  fail:  filesystem:  version
exn:  fail:  filesystem:  errno
exn:  fail:  filesystem:  missing-module
exn:  fail:  network
exn:  fail:  network:  errno
exn:  fail:  out-of-memory
exn:  fail:  unsupported
exn:  fail:  user
exn:  break
exn:  break:  hang-up
exn:  break:  terminate
prop:  exn:  srclocs
exn:  srclocs?
exn:  srclocs-accessor
srcloc
srcloc->string
prop:  exn:  missing-module
exn:  missing-module?
exn:  missing-module-accessor
10.2.6 Additional Exception Functions
exn->string
10.2.7 Realms and Error Message Adjusters
error-message->adjusted-string
error-contract->adjusted-string
current-error-message-adjuster
error-message-adjuster-key

10.2 Exceptions

+Exceptions in The Racket Guide introduces exceptions.

See Exceptions for information on the Racket exception +model. It is based on a proposal by Friedman, Haynes, and Dybvig +[Friedman95].

Whenever a primitive error occurs in Racket, an exception is +raised. The value that is passed to the current exception +handler for a primitive error is always an instance of the +exn structure type. Every exn structure value has a +message field that is a string, the primitive error message. +The default exception handler recognizes exception values with the +exn? predicate and passes the error message to the current +error display handler (see error-display-handler).

Primitive procedures that accept a procedure argument with a +particular required arity (e.g., call-with-input-file, +call/cc) check the argument’s arity immediately, raising +exn:fail:contract if the arity is incorrect.

10.2.1 Error Message Conventions

Racket’s error message convention is to produce error +messages with the following shape:

srcloc: name: message;
 continued-message ...
  field: detail
  ...

The message starts with an optional source location, srcloc, +which is followed by a colon and space when present. The message +continues with an optional name that usually identifies the +complaining function, syntactic form, or other entity, but may also +refer to an entity being complained about; the name is also +followed by a colon and space when present.

The message should be relatively short, and it should be +largely independent of specific values that triggered the error. More +detailed explanation that requires multiple lines should continue with +each line indented by a single space, in which case message +should end in a semi-colon (but the semi-colon should be omitted if +continued-message is not present). Message text should be +lowercase—using semi-colons to separate sentences if needed, +although long explanations may be better deferred to extra fields.

Specific values that triggered the error or other helpful information +should appear in separate field lines, each of which is +indented by two spaces. If a detail is especially long or +takes multiple lines, it should start on its own line after the +field label, and each of its lines should be indented by +three spaces. Field names should be all lowercase.

A field name should end with ... if the field +provides relatively detailed information that might be distracting in +common cases but useful in others. For example, when a contract +failure is reported for a particular argument of a function, other +arguments to the function might be shown in an “other arguments...” +field. The intent is that fields whose names end in ... +might be hidden by default in an environment such as DrRacket.

Make field names as short as possible, relying on +message or continued message text to clarify the +meaning for a field. For example, prefer “given” to “given turtle” +as a field name, where message is something like “given +turtle is too sleepy” to clarify that “given” refers to a turtle.

10.2.2 Raising Exceptions

procedure

(raise v [barrier?])  any

  v : any/c
  barrier? : any/c = #t
Raises an exception, where v represents the exception being +raised. The v argument can be anything; it is passed to the +current exception handler.

If barrier? is true, then the call to the exception +handler is protected by a continuation barrier, so that +multiple returns/escapes are impossible. All exceptions raised by +racket functions effectively use raise with a +#t value for barrier?.

Breaks are disabled from the time the exception is raised until the +exception handler obtains control, and the handler itself is +parameterize-breaked to disable breaks initially; see +Breaks for more information on breaks.

Examples:
> (with-handlers ([number? (lambda (n)
                             (+ n 5))])
    (raise 18 #t))

23

> (struct my-exception exn:fail:user ())
> (with-handlers ([my-exception? (lambda (e)
                                   #f)])
    (+ 5 (raise (my-exception
                 "failed"
                 (current-continuation-marks)))))

#f

> (raise 'failed #t)

uncaught exception: failed

procedure

(error message-sym)  any

  message-sym : symbol?
(error message-str v ...)  any
  message-str : string?
  v : any/c
(error who-sym format-str v ...)  any
  who-sym : symbol?
  format-str : string?
  v : any/c
Raises the exception exn:fail, which contains an error +string. The different forms produce the error string in different +ways:

  • (error message-sym) creates a message string by concatenating +"error: " with the string form of message-sym. Use this +form sparingly.

  • (error message-str v ...) creates a message string by +concatenating message-str with string versions of the vs +(as produced by the current error value conversion handler; see +error-value->string-handler). A space is inserted before +each v. Use this form sparingly, because it does not conform +well to Racket’s error message conventions; consider +raise-arguments-error, instead.

  • (error who-sym format-str v ...) creates a +message string equivalent to the string created by

    (format (string-append "~s: " format-str) who-sym v ...)

    When possible, use functions such as raise-argument-error, +instead, which construct messages that follow Racket’s error message +conventions.

In all cases, the constructed message string is passed to +make-exn:fail, and the resulting exception is raised.

Examples:
> (error 'failed)

error: failed

> (error "failed" 23 'pizza (list 1 2 3))

failed 23 'pizza '(1 2 3)

> (error 'method-a "failed because ~a" "no argument supplied")

method-a: failed because no argument supplied

procedure

(raise-user-error message-sym)  any

  message-sym : symbol?
(raise-user-error message-str v ...)  any
  message-str : string?
  v : any/c
(raise-user-error who-sym format-str v ...)  any
  who-sym : symbol?
  format-str : string?
  v : any/c
Like error, but constructs an exception with +make-exn:fail:user instead of make-exn:fail. The +default error display handler does not show a “stack trace” for +exn:fail:user exceptions (see Continuation Marks), so +raise-user-error should be used for errors that are intended +for end users.

procedure

(raise-argument-error name expected v)  any

  name : symbol?
  expected : string?
  v : any/c
(raise-argument-error name    
  expected    
  bad-pos    
  v ...)  any
  name : symbol?
  expected : string?
  bad-pos : exact-nonnegative-integer?
  v : any/c
Creates an exn:fail:contract value and raises it as +an exception. The name argument is used as the source +procedure’s name in the error message. The expected argument +is used as a description of the expected contract (i.e., as a string, +but the string is intended to contain a contract expression).

In the first form, v is the value received by the procedure +that does not have the expected type.

In the second form, the bad argument is indicated by an index +bad-pos (counting from 0), and all of the original +arguments v are provided (in order). The resulting error +message names the bad argument and also lists the other arguments. If +bad-pos is not less than the number of vs, the +exn:fail:contract exception is raised.

The error message generated by raise-argument-error is +adjusted via error-contract->adjusted-string and then +error-message->adjusted-string using the default +'racket realm.

Examples:
> (define (feed-machine bits)
    (if (not (integer? bits))
      (raise-argument-error 'feed-machine "integer?" bits)
      "fed the machine"))
> (feed-machine 'turkey)

feed-machine: contract violation

  expected: integer?

  given: 'turkey

> (define (feed-cow animal)
    (if (not (eq? animal 'cow))
      (raise-argument-error 'feed-cow "'cow" animal)
      "fed the cow"))
> (feed-cow 'turkey)

feed-cow: contract violation

  expected: 'cow

  given: 'turkey

> (define (feed-animals cow sheep goose cat)
    (if (not (eq? goose 'goose))
      (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
      "fed the animals"))
> (feed-animals 'cow 'sheep 'dog 'cat)

feed-animals: contract violation

  expected: 'goose

  given: 'dog

  argument position: 3rd

  other arguments...:

   'cow

   'sheep

   'cat

procedure

(raise-argument-error* name realm expected v)  any

  name : symbol?
  realm : symbol?
  expected : string?
  v : any/c
(raise-argument-error* name    
  realm    
  expected    
  bad-pos    
  v ...)  any
  name : symbol?
  realm : symbol?
  expected : string?
  bad-pos : exact-nonnegative-integer?
  v : any/c
Like raise-argument-error, but using the given realm +for error-message adjustments.

Added in version 8.4.0.2 of package base.

procedure

(raise-result-error name expected v)  any

  name : symbol?
  expected : string?
  v : any/c
(raise-result-error name    
  expected    
  bad-pos    
  v ...)  any
  name : symbol?
  expected : string?
  bad-pos : exact-nonnegative-integer?
  v : any/c
Like raise-argument-error, but the error message describe v +as a “result” instead of an “argument.”

procedure

(raise-result-error* name realm expected v)  any

  name : symbol?
  realm : symbol?
  expected : string?
  v : any/c
(raise-result-error* name    
  realm    
  expected    
  bad-pos    
  v ...)  any
  name : symbol?
  realm : symbol?
  expected : string?
  bad-pos : exact-nonnegative-integer?
  v : any/c
Like raise-result-error, but using the given realm +for error-message adjustments.

Added in version 8.4.0.2 of package base.

procedure

(raise-arguments-error name    
  message    
  field    
  v ...    
  ...)  any
  name : symbol?
  message : string?
  field : string?
  v : any/c
Creates an exn:fail:contract value and raises it as +an exception. The name is used as the source procedure’s +name in the error message. The message is the error +message; if message contains newline characters, each extra line should be +suitably indented (with one extra space at the start of each line), but it should not end with a newline character. +Each field must have a corresponding v, +and the two are rendered on their own +line in the error message; each v is formatted +using the error value conversion handler (see +error-value->string-handler), unless v is a +unquoted-printing string, in which case the string content is +displayed without using the error value conversion handler.

The error message generated by raise-result-error is adjusted +via error-contract->adjusted-string and then +error-message->adjusted-string using the default +'racket realm.

Example:
> (raise-arguments-error 'eat
                         "fish is smaller than its given meal"
                         "fish" 12
                         "meal" 13)

eat: fish is smaller than its given meal

  fish: 12

  meal: 13

procedure

(raise-arguments-error* name    
  realm    
  message    
  field    
  v ...    
  ...)  any
  name : symbol?
  realm : symbol?
  message : string?
  field : string?
  v : any/c
Like raise-arguments-error, but using the given realm +for error-message adjustments.

Added in version 8.4.0.2 of package base.

procedure

(raise-range-error name    
  type-description    
  index-prefix    
  index    
  in-value    
  lower-bound    
  upper-bound    
  [alt-lower-bound])  any
  name : symbol?
  type-description : string?
  index-prefix : string?
  index : exact-integer?
  in-value : any/c
  lower-bound : exact-integer?
  upper-bound : exact-integer?
  alt-lower-bound : (or/c #f exact-integer?) = #f
Creates an exn:fail:contract value and raises it as +an exception to report an out-of-range error. The type-description +string describes the value for which the index is meant to select an element, +and index-prefix is a prefix for the word “index.” The index +argument is the rejected index. The in-value argument is the value +for which the index was meant. The lower-bound and upper-bound +arguments specify the valid range of indices, inclusive; if upper-bound +is below lower-bound, the value is characterized as “empty.” If alt-lower-bound +is not #f, and if index is between alt-lower-bound +and upper-bound, then the error is report as index being less +than the “starting” index lower-bound.

Since upper-bound is inclusive, a typical value is one +less than the size of a collection—for example, (sub1 (vector-length vec)), (sub1 (length lst)), and so on.

The error message generated by raise-range-error is adjusted +via error-message->adjusted-string using the default +'racket realm.

Examples:
> (raise-range-error 'vector-ref "vector" "starting " 5 #(1 2 3 4) 0 3)

vector-ref: starting index is out of range

  starting index: 5

  valid range: [0, 3]

  vector: '#(1 2 3 4)

> (raise-range-error 'vector-ref "vector" "ending " 5 #(1 2 3 4) 0 3)

vector-ref: ending index is out of range

  ending index: 5

  valid range: [0, 3]

  vector: '#(1 2 3 4)

> (raise-range-error 'vector-ref "vector" "" 3 #() 0 -1)

vector-ref: index is out of range for empty vector

  index: 3

> (raise-range-error 'vector-ref "vector" "ending " 1 #(1 2 3 4) 2 3 0)

vector-ref: ending index is smaller than starting index

  ending index: 1

  starting index: 2

  valid range: [0, 3]

  vector: '#(1 2 3 4)

procedure

(raise-range-error* name    
  realm    
  type-description    
  index-prefix    
  index    
  in-value    
  lower-bound    
  upper-bound    
  [alt-lower-bound])  any
  name : symbol?
  realm : symbol?
  type-description : string?
  index-prefix : string?
  index : exact-integer?
  in-value : any/c
  lower-bound : exact-integer?
  upper-bound : exact-integer?
  alt-lower-bound : (or/c #f exact-integer?) = #f
Like raise-range-error, but using the given realm +for error-message adjustments.

Added in version 8.4.0.2 of package base.

procedure

(raise-type-error name expected v)  any

  name : symbol?
  expected : string?
  v : any/c
(raise-type-error name expected bad-pos v ...)  any
  name : symbol?
  expected : string?
  bad-pos : exact-nonnegative-integer?
  v : any/c
Like raise-argument-error, but with Racket’s old formatting +conventions, and where expected is used as a “type” +description instead of a contract expression. Use raise-argument-error +or raise-result-error, instead.

The error message generated by raise-type-error is adjusted +via error-message->adjusted-string using the default +'racket realm.

procedure

(raise-mismatch-error name    
  message    
  v ...+    
  ...+)  any
  name : symbol?
  message : string?
  v : any/c
Similar to raise-arguments-error, but using Racket’s old +formatting conventions, with a required v immediately +after the first message string, and with further message +strings that are spliced into the message without line breaks or +space. Use raise-arguments-error, instead.

The error message generated by raise-mismatch-error is adjusted +via error-message->adjusted-string using the default +'racket realm.

procedure

(raise-arity-error name arity-v arg-v ...)  any

  name : (or/c symbol? procedure?)
  arity-v : 
(or/c exact-nonnegative-integer?
      arity-at-least?
      (listof
       (or/c exact-nonnegative-integer?
             arity-at-least?)))
  arg-v : any/c
Creates an exn:fail:contract:arity value and raises +it as an exception. The name is used for the source +procedure’s name in the error message.

The arity-v value must +be a possible result from procedure-arity, except +that it does not have to be normalized (see procedure-arity? for +the details of normalized arities); raise-arity-error +will normalize the arity and use the normalized form in the error message. +If name is a procedure, its actual arity is +ignored.

The arg-v arguments are the actual supplied +arguments, which are shown in the error message (using the error value +conversion handler; see error-value->string-handler); also, +the number of supplied arg-vs is explicitly mentioned in the +message.

The error message generated by raise-arity-error is adjusted +via error-message->adjusted-string using the default +'racket realm.

Example:
> (raise-arity-error 'unite (arity-at-least 13) "Virginia" "Maryland")

unite: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: at least 13

  given: 2

  arguments...:

   "Virginia"

   "Maryland"

procedure

(raise-arity-error* name    
  realm    
  arity-v    
  arg-v ...)  any
  name : (or/c symbol? procedure?)
  realm : symbol?
  arity-v : 
(or/c exact-nonnegative-integer?
      arity-at-least?
      (listof
       (or/c exact-nonnegative-integer?
             arity-at-least?)))
  arg-v : any/c

Like raise-arity-error, but using the given realm +for error-message adjustments.

Added in version 8.4.0.2 of package base.

procedure

(raise-arity-mask-error name mask arg-v ...)  any

  name : (or/c symbol? procedure?)
  mask : exact-integer?
  arg-v : any/c
The same as raise-arity-error, but using the arity representation +described with procedure-arity-mask.

Added in version 7.0.0.11 of package base.

procedure

(raise-arity-mask-error* name    
  realm    
  mask    
  arg-v ...)  any
  name : (or/c symbol? procedure?)
  realm : symbol?
  mask : exact-integer?
  arg-v : any/c
Like raise-arity-mask-error, but using the given realm +for error-message adjustments.

Added in version 8.4.0.2 of package base.

procedure

(raise-result-arity-error name    
  arity-v    
  detail-str    
  result-v ...)  any
  name : (or/c symbol? #f)
  arity-v : exact-nonnegative-integer?
  detail-str : (or/c string? #f)
  result-v : any/c
Like raise-arity-error, but reports a “result” mismatch +instead of an “argument” mismatch. The name argument can be +#f to omit an initial source for the error. The +detail-str argument, if non-#f, should be a string +that starts with a newline, since it is added near the end of the +generated error message.

The error message generated by raise-result-arity-error is +adjusted via error-message->adjusted-string using the default +'racket realm.

Example:
> (raise-result-arity-error 'let-values 2 "\n  in: example" 'a 2.0 "three")

let-values: result arity mismatch;

 expected number of values not received

  expected: 2

  received: 3

  in: example

  arguments...:

   'a

   2.0

   "three"

Added in version 6.90.0.26 of package base.

procedure

(raise-result-arity-error* name    
  realm    
  arity-v    
  detail-str    
  result-v ...)  any
  name : (or/c symbol? #f)
  realm : symbol?
  arity-v : exact-nonnegative-integer?
  detail-str : (or/c string? #f)
  result-v : any/c
Like raise-result-arity-error, but using the given realm +for error-message adjustments.

Added in version 8.4.0.2 of package base.

procedure

(raise-syntax-error name    
  message    
  [expr    
  sub-expr    
  extra-sources    
  message-suffix    
  #:exn exn])  any
  name : (or/c symbol? #f)
  message : string?
  expr : any/c = #f
  sub-expr : any/c = #f
  extra-sources : (listof syntax?) = null
  message-suffix : string? = ""
  exn : 
(-> string?
    continuation-mark-set?
    (listof syntax?)
    exn:fail:syntax?)
 = exn:fail:syntax
Creates an exn:fail:syntax? value and raises it as an +exception. Macros use this procedure to report syntax errors.

The name argument is usually #f when expr +is provided; it is described in more detail below. The +message is used as the main body of the error message; if +message contains newline characters, each new line should be +suitably indented (with one space at the start), and it should not end with a newline character.

The optional expr argument is the erroneous source syntax +object or S-expression (but the expression #f cannot be +represented by itself; it must be wrapped as a syntax +object). The optional sub-expr argument is a syntax object +or S-expression (again, #f cannot represent itself) within +expr that more precisely locates the error. Both may appear +in the generated error-message text if +error-print-source-location is #t. Source location +information in the error-message text is similarly extracted from +sub-expr or expr when at least one is a syntax +object and error-print-source-location is #t.

If sub-expr is provided and not #f, it is used (in +syntax form) for the exprs field of the generated exception +record, else the expr is used if provided and not +#f. In either case, the syntax object is consed onto +extra-sources to produce the exprs field, or +extra-sources is used directly for exprs if neither +expr nor sub-expr is provided and not #f. +The extra-sources argument is also used directly for +exprs in the unusual case that the sub-expr or +expr that would be included in exprs cannot be +converted to a syntax object (because it contains a cycle).

The form name used in the generated error message is determined +through a combination of the name, expr, and +sub-expr arguments:

  • When name is #f, and when expr is +either an identifier or a syntax pair containing an identifier as +its first element, then the form name from the error message is the +identifier’s symbol.

  • When name is #f and when expr is not +an identifier or a syntax pair containing an identifier as its +first element, then the form name in the error message is +"?".

  • When name is a symbol, then the symbol +is used as the form name in the generated error message.

The message-suffix string is appended to the end of the error +message. If not "", it should normally start with a newline +and two spaces to add extra fields to the message (see +Error Message Conventions).

If specified, exn should be a constructor or function that +has the same signature as the exn:fail:syntax constructor.

Examples:
> (raise-syntax-error #f "bad syntax" '(bad syntax))

?: bad syntax

  in: (bad syntax)

> (raise-syntax-error #f "unbound identifier" 'unbound-id #:exn exn:fail:syntax:unbound)

?: unbound identifier

  in: unbound-id

Changed in version 6.90.0.18 of package base: Added the message-suffix optional argument.
Changed in version 8.4.0.6: Added the exn optional argument.

An unquoted-printing string wraps a string and +prints, writes, and displays the same way +that the string displays. An unquoted-printing string +is especially useful with raise-arguments-error to serve as a +field “value” that causes literal text to be printed as the field +content.

The unquoted-printing-string? procedure returns #t +if v is a unquoted-printing string, #f +otherwise. The unquoted-printing-string creates a +unquoted-printing string value that encapsulates the string +s, and unquoted-printing-string-value returns the +string within a unquoted-printing string.

Added in version 6.10.0.2 of package base.

10.2.3 Handling Exceptions

procedure

(call-with-exception-handler f thunk)  any

  f : (any/c . -> . any)
  thunk : (-> any)
Installs f as the exception handler for the +dynamic extent of the call to thunk. If an exception +is raised during the evaluation of thunk (in an extension of +the current continuation that does not have its own exception +handler), then f is applied to the raised value in +the continuation of the raise call (but the continuation is +normally extended +with a continuation barrier; see Prompts, Delimited Continuations, and Barriers and +raise).

Any procedure that takes one argument can be an exception handler. +Normally, an exception handler escapes from the context of the +raise call via abort-current-continuation or some other escape +mechanism. To propagate an exception to the “previous” exception +handler—that is, the exception handler associated with the rest of +the continuation after the point where the called exception handler +was associated with the continuation—an exception handler can simply +return a result instead of escaping, in which case the raise call +propagates the value to the previous exception handler (still in the +dynamic extent of the call to raise, and under the same +barrier, if any). If an exception handler returns a result and no +previous handler is available, the uncaught-exception handler +is used.

A call to an exception handler is parameterize-breaked to +disable breaks, and it is wrapped with +call-with-exception-handler to install an exception handler +that reports both the original and newly raised exceptions via the +error display handler and then escapes via the error +escape handler.

parameter

(uncaught-exception-handler)  (any/c . -> . any)

(uncaught-exception-handler f)  void?
  f : (any/c . -> . any)
A parameter that determines an uncaught-exception handler used by +raise when the relevant continuation has no exception handler +installed with call-with-exception-handler or +with-handlers. Unlike exception handlers installed with +call-with-exception-handler, the uncaught-exception +handler must not return a value when called by raise; if +it returns, an exception is raised (to be handled by an exception +handler that reports both the original and newly raised exception).

The default uncaught-exception handler prints an error message using +the current error display handler (see error-display-handler), +unless the argument to the handler is an instance of exn:break:hang-up. +If the argument to the handler is an instance of exn:break:hang-up +or exn:break:terminate, the default uncaught-exception handler +then calls the exit handler with 1, which normally exits +or escapes. For any argument, the default uncaught-exception handler +then escapes by calling the current error escape handler (see +error-escape-handler). The call to each handler is +parameterized to set error-display-handler to the +default error display handler, and it is parameterize-breaked +to disable breaks. The call to the error escape handler is further +parameterized to set error-escape-handler to the default +error escape handler; if the error escape handler returns, then +the default error escape handler is called.

When the current error display handler is the default handler, then the +error-display call is parameterized to install an emergency error +display handler that logs an error (see log-error) and never +fails.

syntax

(with-handlers ([pred-expr handler-expr] ...)
  body ...+)
Evaluates each pred-expr and handler-expr in the +order that they are specified, and then evaluates the bodys +with a new exception handler during its dynamic extent.

The new exception handler processes an exception only if one of the +pred-expr procedures returns a true value when applied to the +exception, otherwise the exception handler is invoked from the +continuation of the with-handlers expression (by raising the +exception again). If an exception is handled by one of the +handler-expr procedures, the result of the entire +with-handlers expression is the return value of the handler.

When an exception is raised during the evaluation of bodys, +each predicate procedure pred-expr is applied to the +exception value; if a predicate returns a true value, the +corresponding handler-expr procedure is invoked with the +exception as an argument. The predicates are tried in the order that +they are specified.

Before any predicate or handler procedure is invoked, the continuation +of the entire with-handlers expression is restored, but also +parameterize-breaked to disable breaks. Thus, breaks are +disabled by default during the predicate and handler procedures (see +Breaks), and the exception handler is the one from +the continuation of the with-handlers expression.

The exn:fail? procedure is useful as a handler predicate to +catch all error exceptions. Avoid using (lambda (x) #t) as a +predicate, because the exn:break exception typically should +not be caught (unless it will be re-raised to cooperatively +break). Beware, also, of catching and discarding exceptions, because +discarding an error message can make debugging unnecessarily +difficult; instead of discarding an error message, consider logging it +via log-error or a logging form created by +define-logger.

Examples:
> (with-handlers ([exn:fail:syntax?
                   (λ (e) (displayln "got a syntax error"))])
    (raise-syntax-error #f "a syntax error"))

got a syntax error

> (with-handlers ([exn:fail:syntax?
                   (λ (e) (displayln "got a syntax error"))]
                  [exn:fail?
                   (λ (e) (displayln "fallback clause"))])
    (raise-syntax-error #f "a syntax error"))

got a syntax error

syntax

(with-handlers* ([pred-expr handler-expr] ...)
  body ...+)
Like with-handlers, but if a handler-expr procedure +is called, breaks are not explicitly disabled, and the handler call is +in tail position with respect to the with-handlers* form.

10.2.4 Configuring Default Handling

parameter

(error-escape-handler)  (-> any)

(error-escape-handler proc)  void?
  proc : (-> any)
A parameter for the error escape handler, which takes no +arguments and escapes from the dynamic context of an exception. The +default error escape handler escapes using +(abort-current-continuation (default-continuation-prompt-tag) void).

The error escape handler is normally called directly by an exception +handler, in a parameterization that sets the error +display handler and error escape handler to the default +handlers, and it is normally parameterize-breaked to disable +breaks. To escape from a run-time error in a different context, use +raise or error.

Due to a continuation barrier around exception-handling calls, +an error escape handler cannot invoke a full continuation that was +created prior to the exception, but it can abort to a prompt (see +call-with-continuation-prompt) or invoke an escape +continuation (see call-with-escape-continuation).

parameter

(error-display-handler)  (string? any/c . -> . any)

(error-display-handler proc)  void?
  proc : (string? any/c . -> . any)
A parameter for the error display handler, which is called +by the default exception handler with an error message and the +exception value. More generally, the handler’s first argument is a +string to print as an error message, and the second is a value +representing a raised exception. An error display handler can +print errors in different ways, but it should always print to the +current error port.

The default error display handler displays its first argument +to the current error port (determined by the +current-error-port parameter) and extracts a stack trace (see +continuation-mark-set->context) to display from the second +argument if it is an exn value but not an +exn:fail:user value.

The default error display handler in DrRacket also uses +the second argument to highlight source locations.

To report a run-time error, use raise or procedures like +error, instead of calling the error display handler +directly.

parameter

(error-print-width)  (and/c exact-integer? (>=/c 3))

(error-print-width width)  void?
  width : (and/c exact-integer? (>=/c 3))
A parameter whose value is used as the maximum number of characters +used to print a Racket value that is embedded in a primitive error +message.

A parameter whose value is used by the default error display handler +as the maximum number of lines of context (or “stack trace”) to +print; a single “...” line is printed if more lines are available +after the first cnt lines. A 0 value for +cnt disables context printing entirely.

parameter

(error-print-source-location)  boolean?

(error-print-source-location include?)  void?
  include? : any/c
A parameter that controls whether read and syntax error messages +include source information, such as the source line and column or the +expression. This parameter also controls the error message when a +module-defined variable is accessed before its definition is executed; +the parameter determines whether the message includes a module +name. Only the message field of an exn:fail:read, +exn:fail:syntax, or exn:fail:contract:variable +structure is affected by the parameter. The default is #t.

parameter

(error-value->string-handler)

  
(any/c exact-nonnegative-integer?
       . -> .
       string?)
(error-value->string-handler proc)  void?
  proc : 
(any/c exact-nonnegative-integer?
       . -> .
       string?)
A parameter that determines the error value conversion +handler, which is used to print a Racket value that is embedded in a +primitive error message.

The integer argument to the handler specifies the maximum number of +characters that should be used to represent the value in the resulting +string. The default error value conversion handler prints +the value into a string (using the current global port print +handler; see global-port-print-handler). If the printed form +is too long, the printed form is truncated and the last three +characters of the return string are set to “...”.

If the string returned by an error value conversion handler is longer +than requested, the string is destructively “truncated” by setting +the first extra position in the string to the null character. If a +non-string is returned, then the string "..." is used. If a +primitive error string needs to be generated before the handler has +returned, the default error value conversion handler is used.

Calls to an error value conversion handler are parameterized +to re-install the default error value conversion handler, and to +enable printing of unreadable values (see print-unreadable).

parameter

(error-syntax->string-handler)

  
(any/c (or/c exact-nonnegative-integer? #f)
      . -> .
      string?)
(error-syntax->string-handler proc)  void?
  proc : 
(any/c (or/c exact-nonnegative-integer? #f)
      . -> .
      string?)
A parameter that determines the error syntax +conversion handler, which is used to print a syntax form that is +embedded in an error message, such as from raise-syntax-error +when error-print-source-location is #t.

The arguments to the handler are analogous to the arguments for a +error value conversion handler as configured with +error-value->string-handler, except that #f can be +provided instead of an integer for the length, meaning that the +printed form should not be truncated. The first argument is normally a +syntax object, but in the same way that +raise-syntax-error accepts other S-expressions, the error +syntax conversion handler must also handle representations that are +not syntax objects.

Added in version 8.2.0.8 of package base.

10.2.5 Built-in Exception Types

struct

(struct exn (message continuation-marks)
    #:extra-constructor-name make-exn
    #:transparent)
  message : string?
  continuation-marks : continuation-mark-set?
The base structure type for exceptions. The message +field contains an error message, and the continuation-marks +field contains the value produced by (current-continuation-marks) +immediately before the exception was raised.

Exceptions raised by Racket form a hierarchy under exn:

exn
  exn:fail
    exn:fail:contract
      exn:fail:contract:arity
      exn:fail:contract:divide-by-zero
      exn:fail:contract:non-fixnum-result
      exn:fail:contract:continuation
      exn:fail:contract:variable
    exn:fail:syntax
      exn:fail:syntax:unbound
      exn:fail:syntax:missing-module
    exn:fail:read
      exn:fail:read:eof
      exn:fail:read:non-char
    exn:fail:filesystem
      exn:fail:filesystem:exists
      exn:fail:filesystem:version
      exn:fail:filesystem:errno
      exn:fail:filesystem:missing-module
    exn:fail:network
      exn:fail:network:errno
    exn:fail:out-of-memory
    exn:fail:unsupported
    exn:fail:user
  exn:break
    exn:break:hang-up
    exn:break:terminate

struct

(struct exn:fail exn ()
    #:extra-constructor-name make-exn:fail
    #:transparent)
Raised for exceptions that represent errors, as opposed to +exn:break.

struct

(struct exn:fail:contract exn:fail ()
    #:extra-constructor-name make-exn:fail:contract
    #:transparent)
Raised for errors from the inappropriate run-time use of a function or +syntactic form.

struct

(struct exn:fail:contract:arity exn:fail:contract ()
    #:extra-constructor-name make-exn:fail:contract:arity
    #:transparent)
Raised when a procedure is applied to the wrong number of arguments.

struct

(struct exn:fail:contract:divide-by-zero exn:fail:contract ()
    #:extra-constructor-name
    make-exn:fail:contract:divide-by-zero
    #:transparent)
Raised for division by exact zero.

struct

(struct exn:fail:contract:non-fixnum-result exn:fail:contract ()
    #:extra-constructor-name
    make-exn:fail:contract:non-fixnum-result
    #:transparent)
Raised by functions like fx+ when the result would not be a fixnum.

struct

(struct exn:fail:contract:continuation exn:fail:contract ()
    #:extra-constructor-name make-exn:fail:contract:continuation
    #:transparent)
Raised when a continuation is applied where the jump would cross a +continuation barrier.

struct

(struct exn:fail:contract:variable exn:fail:contract (id)
    #:extra-constructor-name make-exn:fail:contract:variable
    #:transparent)
  id : symbol?
Raised for a reference to a not-yet-defined top-level variable +or module-level variable.

struct

(struct exn:fail:syntax exn:fail (exprs)
    #:extra-constructor-name make-exn:fail:syntax
    #:transparent)
  exprs : (listof syntax?)
Raised for a syntax error that is not a read error. The +exprs indicate the relevant source expressions, +least-specific to most-specific.

This structure type implements the prop:exn:srclocs property.

struct

(struct exn:fail:syntax:unbound exn:fail:syntax ()
    #:extra-constructor-name make-exn:fail:syntax:unbound
    #:transparent)
Raised by #%top or set! for an +unbound identifier within a module.

struct

(struct exn:fail:syntax:missing-module exn:fail:syntax (path)
    #:extra-constructor-name make-exn:fail:syntax:missing-module
    #:transparent)
  path : module-path?
Raised by the default module name resolver or default +load handler to report a module path—a reported in the +path field—whose implementation file cannot be +found.

The default module name resolver raises this exception only +when it is given a syntax object as its second argument, and the +default load handler raises this exception only when the value +of current-module-path-for-load is a syntax object (in which +case both the exprs field and the path field +are determined by the syntax object).

This structure type implements the prop:exn:missing-module property.

struct

(struct exn:fail:read exn:fail (srclocs)
    #:extra-constructor-name make-exn:fail:read
    #:transparent)
  srclocs : (listof srcloc?)
Raised for a read error. The srclocs indicate the +relevant source expressions.

struct

(struct exn:fail:read:eof exn:fail:read ()
    #:extra-constructor-name make-exn:fail:read:eof
    #:transparent)
Raised for a read error, specifically when the error is due +to an unexpected end-of-file.

struct

(struct exn:fail:read:non-char exn:fail:read ()
    #:extra-constructor-name make-exn:fail:read:non-char
    #:transparent)
Raised for a read error, specifically when the error is due +to an unexpected non-character (i.e., “special”) element in the +input stream.

struct

(struct exn:fail:filesystem exn:fail ()
    #:extra-constructor-name make-exn:fail:filesystem
    #:transparent)
Raised for an error related to the filesystem (such as a file not +found).

struct

(struct exn:fail:filesystem:exists exn:fail:filesystem ()
    #:extra-constructor-name make-exn:fail:filesystem:exists
    #:transparent)
Raised for an error when attempting to create a file that exists +already.

struct

(struct exn:fail:filesystem:version exn:fail:filesystem ()
    #:extra-constructor-name make-exn:fail:filesystem:version
    #:transparent)
Raised for a version-mismatch error when loading an extension.

struct

(struct exn:fail:filesystem:errno exn:fail:filesystem (errno)
    #:extra-constructor-name make-exn:fail:filesystem:errno
    #:transparent)
  errno : (cons/c exact-integer? (or/c 'posix 'windows 'gai))
Raised for a filesystem error for which a system error code is +available. The symbol part of an errno field indicates the +category of the error code: 'posix indicates a C/Posix +errno value, 'windows indicates a Windows system error +code (under Windows, only), and 'gai indicates a +getaddrinfo error code (which shows up only in +exn:fail:network:errno exceptions for operations that resolve +hostnames, but is allowed in exn:fail:filesystem:errno +instances for consistency).

struct

(struct exn:fail:filesystem:missing-module exn:fail:filesystem
  (path)
    #:extra-constructor-name
    make-exn:fail:filesystem:missing-module
    #:transparent)
  path : module-path?
Raised by the default module name resolver or default +load handler to report a module path—a reported in the +path field—whose implementation file cannot be +found.

The default module name resolver raises this exception only +when it is not given a syntax object as its second argument, and the +default load handler raises this exception only when the value +of current-module-path-for-load is not a syntax object.

This structure type implements the prop:exn:missing-module property.

struct

(struct exn:fail:network exn:fail ()
    #:extra-constructor-name make-exn:fail:network
    #:transparent)
Raised for TCP and UDP errors.

struct

(struct exn:fail:network:errno exn:fail:network (errno)
    #:extra-constructor-name make-exn:fail:network:errno
    #:transparent)
  errno : (cons/c exact-integer? (or/c 'posix 'windows 'gai))
Raised for a TCP or UDP error for which a system error code is +available, where the errno field is as for +exn:fail:filesystem:errno.

struct

(struct exn:fail:out-of-memory exn:fail ()
    #:extra-constructor-name make-exn:fail:out-of-memory
    #:transparent)
Raised for an error due to insufficient memory, in cases where sufficient +memory is at least available for raising the exception.

struct

(struct exn:fail:unsupported exn:fail ()
    #:extra-constructor-name make-exn:fail:unsupported
    #:transparent)
Raised for an error due to an unsupported feature on the current +platform or configuration.

struct

(struct exn:fail:user exn:fail ()
    #:extra-constructor-name make-exn:fail:user
    #:transparent)
Raised for errors that are intended to be seen by end users. In +particular, the default error printer does not show the program +context when printing the error message.

struct

(struct exn:break exn (continuation)
    #:extra-constructor-name make-exn:break
    #:transparent)
  continuation : continuation?
Raised asynchronously (when enabled) in response to a break request. +The continuation field can be used to resume the interrupted +computation in the uncaught-exception handler or +call-with-exception-handler (but not +with-handlers because it escapes from the exception context +before evaluating any predicates or handlers).

struct

(struct exn:break:hang-up exn:break ()
    #:extra-constructor-name make-exn:break:hang-up
    #:transparent)
Raised asynchronously for hang-up breaks. The default + uncaught-exception handler reacts to this exception type by + calling the exit handler.

struct

(struct exn:break:terminate exn:break ()
    #:extra-constructor-name make-exn:break:terminate
    #:transparent)
Raised asynchronously for termination-request breaks. The default + uncaught-exception handler reacts to this exception type by + calling the exit handler.

A property that identifies structure types that provide a list of +srcloc values. The property is normally attached to structure +types used to represent exception information.

The property value must be a procedure that accepts a single +value—the structure type instance from which to extract source +locations—and returns a list of srclocs. Some error +display handlers use only the first returned location.

As an example, +
#lang racket
 
;; We create a structure that supports the
;; prop:exn:srcloc protocol.  It carries
;; with it the location of the syntax that
;; is guilty.
(struct exn:fail:he-who-shall-not-be-named exn:fail
  (a-srcloc)
  #:property prop:exn:srclocs
  (lambda (a-struct)
    (match a-struct
      [(exn:fail:he-who-shall-not-be-named msg marks a-srcloc)
       (list a-srcloc)])))
 
;; We can play with this by creating a form that
;; looks at identifiers, and only flags specific ones.
(define-syntax (skeeterize stx)
  (syntax-case stx ()
    [(_ expr)
     (cond
       [(and (identifier? #'expr)
             (eq? (syntax-e #'expr) 'voldemort))
        (quasisyntax/loc stx
          (raise (exn:fail:he-who-shall-not-be-named
                  "oh dear don't say his name"
                  (current-continuation-marks)
                  (srcloc '#,(syntax-source #'expr)
                          '#,(syntax-line #'expr)
                          '#,(syntax-column #'expr)
                          '#,(syntax-position #'expr)
                          '#,(syntax-span #'expr)))))]
       [else
        ;; Otherwise, leave the expression alone.
        #'expr])]))
 
(define (f x)
  (* (skeeterize x) x))
 
(define (g voldemort)
  (* (skeeterize voldemort) voldemort))
 
;; Examples:
(f 7)
(g 7)
;; The error should highlight the use
;; of voldemort in g.

procedure

(exn:srclocs? v)  boolean?

  v : any/c
Returns #t if v has the prop:exn:srclocs +property, #f otherwise.

procedure

(exn:srclocs-accessor v)

  (exn:srclocs? . -> . (listof srcloc))
  v : exn:srclocs?
Returns the srcloc-getting procedure associated with v.

struct

(struct srcloc (source line column position span)
    #:extra-constructor-name make-srcloc
    #:transparent)
  source : any/c
  line : (or/c exact-positive-integer? #f)
  column : (or/c exact-nonnegative-integer? #f)
  position : (or/c exact-positive-integer? #f)
  span : (or/c exact-nonnegative-integer? #f)
A source location is most frequently represented by a +srcloc structure. More generally, a source location has the +same information as a srcloc structure, but potentially +represented or accessed differently. For example, source-location +information is accessed from a syntax object with functions +like syntax-source and syntax-line, while +datum->syntax accepts a source location as a list, vector, or +another syntax object. For ports, a combination of +object-name and port-next-location provides location +information, especially in a port for which counting has been enabled +through port-count-lines!.

The fields of a srcloc instance are as follows:

  • source An arbitrary value identifying the source, +often a path (see Paths).

  • line The line number (counts from 1) or +#f (unknown).

  • column The column number (counts from 0) or +#f (unknown).

  • position The starting position (counts from 1) or +#f (unknown).

  • span The number of covered positions (counts from +0) or #f (unknown).

See Printing Compiled Code for information about the treatment of +srcloc values that are embedded in compiled code.

procedure

(srcloc->string srcloc)  (or/c string? #f)

  srcloc : srcloc?
Formats srcloc as a string suitable for error reporting. A +path source in srcloc is shown relative to the value of +current-directory-for-user. The result is #f if +srcloc does not contain enough information to format a +string.

A property that identifies structure types that provide a module path +for a load that fails because a module is not found.

The property value must be a procedure that accepts a single +value—the structure type instance from which to extract source +locations—and returns a module path.

procedure

(exn:missing-module? v)  boolean?

  v : any/c
Returns #t if v has the prop:exn:missing-module +property, #f otherwise.

Returns the module path-getting procedure associated with v.

10.2.6 Additional Exception Functions

 (require racket/exn) package: base
The bindings documented in this section are provided by the racket/exn library, not racket/base or racket.

Added in version 6.3 of package base.

procedure

(exn->string exn)  string?

  exn : (or/c exn? any/c)
Formats exn as a string. If exn is an exn?, +collects and returns the output from the current +(error-display-handler); otherwise, simply converts +exn to a string using (format "~s\n" exn).

10.2.7 Realms and Error Message Adjusters

A realm identifies a convention for naming functions and +specifying contracts for function arguments and results. Realms are +intended to help improve layering and interoperability among languages +that are implemented on top of Racket.

Realms primarily enable a language to recognize and rewrite error +messages that are generated by lower layers of an implementation. For +example, a language’s implementation of “arrays” might use Racket +vectors directly, but when an object-type or primitive bounds check +fails for a vector, the generated error message mentions “vector” +and possibly a contract like vector? and a function name like +vector-ref. Since these error messages are identified as +being from the 'racket/primitive realm, a language +implementation can look for 'racket/primitive to detect and +rewrite error messages with minimal danger of mangling error messages +from other parts of an application (possibly implemented in the new +language) that happen to use the word “vector.”

Each procedure and each module also has a realm. A procedure’s realm +is relevant, for example, when it is applied to the wrong number of +arguments; in that case, the arity-error message itself is from the +'racket/primitive realm, but the error message also should +include the name of the procedure, which can be from some different +realm. Along similar lines, continuation-mark-set->context +can report the realm associated with (the procedure for) each frame in +a continuation, which might be useful to identify boundary crossings.

The construction of an error message must cooperate explicitly with +error-message adjusting. The most basic may to cooperate is through +functions like error-message->adjusted-string and +error-contract->adjusted-string, which run error-message +adjusters via the current-error-message-adjuster parameter +and other adjusters associated with the current continuation using +error-message-adjuster-key as a continuation-mark key. +Functions like raise-argument-error and +raise-arity-error use error-message->adjusted-string +and error-contract->adjusted-string with the default realm, +'racket. Functions like raise-argument-error* and +raise-arity-error* accept an explicit realm argument.

Not all error functions automatically cooperate with error-message +adjusting. For example, the raise-reader-error and +raise-syntax-error functions do not call adjusters, because +they report errors that are intimately tied to syntax (and, along +those lines, errors of a more static nature).

procedure

(error-message->adjusted-string name    
  name-realm    
  message    
  message-realm)  string?
  name : (or/c symbol? #f)
  name-realm : symbol?
  message : string?
  message-realm : symbol?
Combines name (if it is not #f) with ": " +and then message to generate an error-message string, but +first giving error-message adjusters a chance to adjust name +and/or message.

Any adjuster functions associated with the current continuation as a +continuation mark with error-message-adjuster-key are +run first; the adjusters are run in order from shallowest to deepest. +Then, the adjuster value of current-error-message-adjuster is +used.

Each adjuster is tried with the 'message protocol, first. If +the adjuster responds with #f for 'message, then the +'name protocol is tried. See +current-error-message-adjuster for information on the +protocols. An adjuster that responds with #f for both is +skipped, as is any value associated as continuation mark using +error-message-adjuster-key where the value is not a procedure +that accepts one argument. In addition, the 'name protocol is +skipped if the (possibly adjusted) name is #f.

Added in version 8.4.0.2 of package base.

procedure

(error-contract->adjusted-string contract-str    
  contract-realm)  string?
  contract-str : string?
  contract-realm : symbol?
Analogous to error-message->adjusted-string, but for just the +contract part of an error message. The result string is typically +incorporated into a larger error message that may then be adjusted +further.

Adjustment of contract string uses the 'contract protocol as +described for current-error-message-adjuster.

Added in version 8.4.0.2 of package base.

parameter

(current-error-message-adjuster)

  (symbol? . -> . (or/c procedure? #f))
(current-error-message-adjuster proc)  void?
  proc : (symbol? . -> . (or/c procedure? #f))
A parameter that determines an error-message adjuster that is +applied after any adjusters associated to the current continuation via +error-message-adjuster-key.

An adjuster procedure receives a symbol identifying a protocol, and it +must return either #f or a procedure for performing +adjustments through that protocol. The following protocols are +currently defined, but more may be added in the future:

  • 'name: the procedure receives two arguments, a name +symbol and a realm symbol; it returns an adjusted name symbol +and an adjusted realm symbol.

  • 'message: the procedure receives four arguments: a +name symbol or #f (which means that no name will be +prefixed on the message), a name-realm symbol, an message +string, and a message-realm symbol; it returns four adjusted +values.

  • 'contract: the procedure receives two arguments, a +contract string and a realm symbol; it returns an adjusted +contract string and an adjusted realm symbol.

A new library or language can introduce additional mode symbols, too. +To avoid conflicts, prefix the mode symbol with a collection or +library name followed by /.

If an adjuster procedure returns #f for a protocol, it’s the +same as returning a function that performs no adjustment and returns +its arguments. The default value of this parameter returns #f +for any symbol argument except the protocols listed above, for which +it returns a procedure that checks its arguments and returns them with +no adjustment.

Added in version 8.4.0.2 of package base.

An uninterned symbol intended for use as a continuation +mark key with an error-adjuster procedure value. An error adjuster +associated with the key should follow the same protocol as a value of +current-error-message-adjuster.

See error-message->adjusted-string for a description of how +marks using this key are can adjust error messages.

Added in version 8.4.0.2 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/extflonums.html b/clones/docs.racket-lang.org/reference/extflonums.html new file mode 100644 index 00000000..bf5ae02b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/extflonums.html @@ -0,0 +1,51 @@ + +4.3.5 Extflonums
4.3.5 Extflonums

 (require racket/extflonum) package: base

An extflonum is an extended-precision (80-bit) +floating-point number. Extflonum arithmetic is supported on +platforms with extended-precision hardware and where the +extflonum implementation does not conflict with normal +double-precision arithmetic (i.e., on x86 and x86_64 platforms when +Racket is compiled to use SSE instructions for floating-point +operations, and on Windows when "longdouble.dll" +is available).

A extflonum is not a number in the sense of +number?. Only extflonum-specific operations such as +extfl+ perform extflonum arithmetic.

A literal extflonum is written like an inexact number, +but using an explicit t or T exponent marker (see +Reading Extflonums). For example, 3.5t0 is an +extflonum. The extflonum values for infinity are ++inf.t and -inf.t. The +extflonum value for not-a-number is +nan.t or +-nan.t.

If (extflonum-available?) produces #f, then all +operations exported by racket/extflonum raise +exn:fail:unsupported, except for extflonum?, +extflonum-available?, and extflvector? (which always +work). The reader (see The Reader) always accepts extflonum +input; when extflonum operations are not supported, printing an +extflonum from the reader uses its source notation (as opposed to +normalizing the format).

Two extflonums are equal? if extfl= +produces #t for the extflonums. If extflonums +are not supported in a platform, extflonums are equal? +only if they are eq?.

procedure

(extflonum? v)  boolean?

  v : any/c
Returns #t if v is an extflonum, #f +otherwise.

Returns #t if extflonum operations are supported on the +current platform, #f otherwise.

4.3.5.1 Extflonum Arithmetic

procedure

(extfl+ a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(extfl- a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(extfl* a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(extfl/ a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(extflabs a)  extflonum?

  a : extflonum?
Like fl+, fl-, fl*, fl/, and flabs, +but for extflonums.

procedure

(extfl= a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(extfl< a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(extfl> a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(extfl<= a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(extfl>= a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(extflmin a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(extflmax a b)  extflonum?

  a : extflonum?
  b : extflonum?
Like fl=, fl<, fl>, fl<=, fl>=, +flmin, and flmax, but for extflonums.

procedure

(extflround a)  extflonum?

  a : extflonum?

procedure

(extflfloor a)  extflonum?

  a : extflonum?

procedure

(extflceiling a)  extflonum?

  a : extflonum?

procedure

(extfltruncate a)  extflonum?

  a : extflonum?

procedure

(extflsin a)  extflonum?

  a : extflonum?

procedure

(extflcos a)  extflonum?

  a : extflonum?

procedure

(extfltan a)  extflonum?

  a : extflonum?

procedure

(extflasin a)  extflonum?

  a : extflonum?

procedure

(extflacos a)  extflonum?

  a : extflonum?

procedure

(extflatan a)  extflonum?

  a : extflonum?

procedure

(extfllog a)  extflonum?

  a : extflonum?

procedure

(extflexp a)  extflonum?

  a : extflonum?

procedure

(extflsqrt a)  extflonum?

  a : extflonum?

procedure

(extflexpt a b)  extflonum?

  a : extflonum?
  b : extflonum?
Like flsin, flcos, fltan, flasin, +flacos, flatan, fllog, flexp, and +flsqrt, and flexpt, but for extflonums.

procedure

(->extfl a)  extflonum?

  a : exact-integer?

procedure

(extfl->exact-integer a)  exact-integer?

  a : extflonum?

procedure

(real->extfl a)  extflonum?

  a : real?

procedure

(extfl->exact a)  (and/c real? exact?)

  a : extflonum?

procedure

(extfl->fx a)  fixnum?

  a : extflonum?

procedure

(fx->extfl a)  extflonum?

  a : fixnum?

procedure

(extfl->inexact a)  flonum?

  a : extflonum?
The first six are like ->fl, fl->exact-integer, +real->double-flonum, inexact->exact, fl->fx, +and fx->fl, but for extflonums. +The extfl->inexact function converts a extflonum to +its closest flonum approximation.

Changed in version 7.7.0.8 of package base: Changed extfl->fx to truncate.

4.3.5.2 Extflonum Constants

value

pi.t : extflonum?

Like pi, but with 80 bits precision.

4.3.5.3 Extflonum Vectors

An extflvector is like an flvector, but it holds only +extflonums. See also Unsafe Extflonum Operations.

Two extflvectors are equal? if they have the same length, +and if the values in corresponding slots of the extflvectors are +equal?.

procedure

(extflvector? v)  boolean?

  v : any/c

procedure

(extflvector x ...)  extflvector?

  x : extflonum?

procedure

(make-extflvector size [x])  extflvector?

  size : exact-nonnegative-integer?
  x : extflonum? = 0.0t0

procedure

(extflvector-length vec)  exact-nonnegative-integer?

  vec : extflvector?

procedure

(extflvector-ref vec pos)  extflonum?

  vec : extflvector?
  pos : exact-nonnegative-integer?

procedure

(extflvector-set! vec pos x)  extflonum?

  vec : extflvector?
  pos : exact-nonnegative-integer?
  x : extflonum?

procedure

(extflvector-copy vec [start end])  extflvector?

  vec : extflvector?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (vector-length v)

procedure

(in-extflvector vec [start stop step])  sequence?

  vec : extflvector?
  start : exact-nonnegative-integer? = 0
  stop : (or/c exact-integer? #f) = #f
  step : (and/c exact-integer? (not/c zero?)) = 1

syntax

(for/extflvector maybe-length (for-clause ...) body ...)

syntax

(for*/extflvector maybe-length (for-clause ...) body ...)

 
maybe-length = 
  | #:length length-expr
  | #:length length-expr #:fill fill-expr
 
  length-expr : exact-nonnegative-integer?
  fill-expr : extflonum?

procedure

(shared-extflvector x ...)  extflvector?

  x : extflonum?

procedure

(make-shared-extflvector size [x])  extflvector?

  size : exact-nonnegative-integer?
  x : extflonum? = 0.0t0

4.3.5.4 Extflonum Byte Strings

procedure

(floating-point-bytes->extfl bstr    
  [big-endian?    
  start    
  end])  extflonum?
  bstr : bytes?
  big-endian? : any/c = (system-big-endian?)
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Like floating-point-bytes->real, but for extflonums: +Converts the extended-precision floating-point number encoded in +bstr from position start (inclusive) to end +(exclusive) to an extflonum. The difference between +start an end must be 10 bytes.

procedure

(extfl->floating-point-bytes x    
  [big-endian?    
  dest-bstr    
  start])  bytes?
  x : extflonum?
  big-endian? : any/c = (system-big-endian?)
  dest-bstr : (and/c bytes? (not/c immutable?))
   = (make-bytes 10)
  start : exact-nonnegative-integer? = 0
Like real->floating-point-bytes, but for extflonums: +Converts x to its representation in a byte +string of length 10.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/extras.css b/clones/docs.racket-lang.org/reference/extras.css new file mode 100644 index 00000000..3a091557 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/extras.css @@ -0,0 +1,12 @@ + +.ghost { + color: white; +} + +.inferencetop { + border-bottom: 1px solid black; + text-align: center; +} +.inferencebottom { + text-align: center; +} diff --git a/clones/docs.racket-lang.org/reference/fasl.html b/clones/docs.racket-lang.org/reference/fasl.html new file mode 100644 index 00000000..f4224c9b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/fasl.html @@ -0,0 +1,56 @@ + +13.10 Fast-Load Serialization

13.10 Fast-Load Serialization

 (require racket/fasl) package: base
The bindings documented in this section are provided by the racket/fasl library, not racket/base or racket.

procedure

(s-exp->fasl v 
  [out 
  #:keep-mutable? keep-mutable? 
  #:handle-fail handle-fail 
  #:external-lift? external-lift? 
  #:skip-prefix? skip-prefix?]) 
  (or/c (void) bytes?)
  v : any/c
  out : (or/c output-port? #f) = #f
  keep-mutable? : any/c = #f
  handle-fail : (or/c #f (any/c . -> . any/c)) = #f
  external-lift? : (or/c #f (any/c . -> . any/c)) = #f
  skip-prefix? : any/c = #f

procedure

(fasl->s-exp in    
  [#:datum-intern? datum-intern?    
  #:external-lifts external-lifts    
  #:skip-prefix? skip-prefix?])  any/c
  in : (or/c input-port? bytes?)
  datum-intern? : any/c = #t
  external-lifts : vector? = '#()
  skip-prefix? : any/c = #f
The s-exp->fasl function serializes v to a byte +string, printing it directly to out if out is an +output port or returning the byte string otherwise. The +fasl->s-exp function decodes a value from a byte string +(supplied either directly or as an input port) that was encoded with +s-exp->fasl.

The v argument must be a value that could be quoted +as a literal—that is, a value without syntax objects for which +(compile `',v) would work and be readable +after writeor it can include correlated +objects mixed with those values. The byte string produced by +s-exp->fasl does not use the same format as compiled code, +however.

If a value within v is not valid as a quoted +literal, and if handle-fail is not #f, then +handle-fail is called on the nested value, and the result of +handle-fail is written in that value’s place. The +handle-fail procedure might raise an exception instead of +returning a replacement value. If handle-fail is #f, +then the exn:fail:contract exception is raised when an invalid value is +encountered.

If external-lift? is not #f, then it receives each +value v-sub encountered in v by +s-exp->fasl. If the result of external-lift? on +v-sub is true, then v-sub is not encoded in the +result, and it instead treated as externally lifted. A +deserializing fasl->s-exp receives a external-lifts +vector that has one value for each externally lifted value, in the +same order as passed to external-lift? on serialization.

Like (compile `',v), s-exp->fasl does not +preserve graph structure, support cycles, or handle non-prefab +structures. Compose s-exp->fasl with serialize to +preserve graph structure, handle cyclic data, and encode serializable +structures. The s-exp->fasl and fasl->s-exp +functions consult current-write-relative-directory and +current-load-relative-directory +(falling back to current-directory), respectively, in the same +way as bytecode saving and loading to store paths in relative form, +and they similarly allow and convert constrained srcloc +values (see Printing Compiled Code).

Unless keep-mutable? is provided as true to +s-exp->fasl, then mutable values in v are replaced +by immutable values when the result is decoded by +fasl->s-exp. Unless datum-intern? is provided as +#f, then any immutable value produced by fasl->s-exp +is filtered by datum-intern-literal. The defaults make the +composition of s-exp->fasl and fasl->s-exp behave +like the composition of write and read.

If skip-prefix? is not #f, then a prefix that +identifies the stream as a serialization is not written by +s-exp->fasl or read by fasl->s-exp. Omitting a +prefix can save a small amount of space, which can useful when +serializing small values, but it gives up a sanity check on the +fasl->s-exp that is often useful.

The byte-string encoding produced by s-exp->fasl is +independent of the Racket version, except as future Racket versions +introduce extensions that are not currently recognized. In particular, +the result of s-exp->fasl will be valid as input to any +future version of fasl->s-exp (as long as the +skip-prefix? arguments are consistent).

Examples:
> (define fasl (s-exp->fasl (list #("speed") 'racer #\!)))
> fasl

#"racket/fasl:\0\24\34\3 \1\23\5speed\16\5racer\r!"

> (fasl->s-exp fasl)

'(#("speed") racer #\!)

Changed in version 6.90.0.21 of package base: Made s-exp->fasl format version-independent +and added the #:keep-mutable? +and #:datum-intern? arguments.
Changed in version 7.3.0.7: Added support for correlated objects.
Changed in version 7.5.0.3: Added the #:handle-fail argument.
Changed in version 7.5.0.9: Added the #:external-lift? and #:external-lifts arguments.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/file-ports.html b/clones/docs.racket-lang.org/reference/file-ports.html new file mode 100644 index 00000000..2788c98b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/file-ports.html @@ -0,0 +1,163 @@ + +13.1.5 File Ports
13.1.5 File Ports

A port created by open-input-file, open-output-file, +subprocess, and related functions is a file-stream +port. The initial input, output, and error ports in racket +are also file-stream ports. The file-stream-port? predicate +recognizes file-stream ports.

When an input or output file-stream port is created, it is placed into +the management of the current custodian (see +Custodians). In the case of an output port, a flush +callback is registered with the current plumber to flush the port.

procedure

(open-input-file path    
  [#:mode mode-flag    
  #:for-module? for-module?])  input-port?
  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
  for-module? : any/c = #f
Opens the file specified by path for input. The +mode-flag argument specifies how the file’s bytes are +translated on input:

  • 'binary bytes are returned from the port +exactly as they are read from the file.

  • 'text return and linefeed bytes (10 and +13) as read from the file are filtered by the port in a platform +specific manner:

    • Unix and Mac OS: no filtering occurs.

    • Windows: a return-linefeed combination from a file is returned +by the port as a single linefeed; no filtering occurs for +return bytes that are not followed by a linefeed, or for a +linefeed that is not preceded by a return.

On Windows, 'text mode works only with regular files; +attempting to use 'text with other kinds of files triggers an +exn:fail:filesystem exception.

Otherwise, the file specified by path need not be a regular +file. It might be a device that is connected through the filesystem, such +as "aux" on Windows or "/dev/null" on Unix. In all +cases, the port is buffered by default.

The port produced by open-input-file should be explicitly +closed, either though close-input-port or indirectly via +custodian-shutdown-all, to release the OS-level file +handle. The input port will not be closed automatically if it is +otherwise available for garbage collection (see +Garbage Collection); a will could be associated with an input port +to close it more automatically (see Wills and Executors).

A path value that is the cleansed version of +path is used as the name of the opened port.

If opening the file fails due to an error in the filesystem, +then exn:fail:filesystem:errno exception is raised—as long as +for-module? is #f, +current-module-path-for-load has a non-#f value, or +the filesystem error is not recognized as a file-not-found error. Otherwise, +when for-module? is true, +current-module-path-for-load has a non-#f value, +and the filesystem error is recognized as a file-not-found error, +then the raised exception is either +exn:fail:syntax:missing-module (if the value of +current-module-path-for-load is a syntax object) or +exn:fail:filesystem:missing-module (otherwise).

Changed in version 6.0.1.6 of package base: Added #:for-module?.

Examples:
> (with-output-to-file some-file
    (lambda () (printf "hello world")))
> (define in (open-input-file some-file))
> (read-string 11 in)

"hello world"

> (close-input-port in)

procedure

(open-output-file path    
  [#:mode mode-flag    
  #:exists exists-flag    
  #:permissions permissions])  output-port?
  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update 'can-update
      'replace 'truncate
      'must-truncate 'truncate/replace)
   = 'error
  permissions : (integer-in 0 65535) = #o666
Opens the file specified by path for output. The +mode-flag argument specifies how bytes written to the port +are translated when written to the file:

  • 'binary bytes are written to the file exactly +as written to the port.

  • 'text on Windows, a linefeed byte (10) written +to the port is translated to a return-linefeed combination in the +file; no filtering occurs for returns.

On Windows, 'text mode works only with regular files; +attempting to use 'text with other kinds of files triggers an +exn:fail:filesystem exception.

The exists-flag argument specifies how to handle/require +files that already exist:

  • 'error raise exn:fail:filesystem +if the file exists.

  • 'replace remove the old file, if it +exists, and write a new one.

  • 'truncate remove all old data, if the file +exists.

  • 'must-truncate remove all old data in an +existing file; if the file does not exist, the +exn:fail:filesystem exception is raised.

  • 'truncate/replace try 'truncate; +if it fails (perhaps due to file permissions), try +'replace.

  • 'update open an existing file without +truncating it; if the file does not exist, the +exn:fail:filesystem exception is raised. Use file-position +to change the current read/write position.

  • 'can-update open an existing file without +truncating it, or create the file if it does not exist.

  • 'append append to the end of the file, +whether it already exists or not; on Windows, +'append is equivalent to 'update, except that +the file is not required to exist, and the file position is +immediately set to the end of the file after opening it.

When the file specified by path is created, +permissions specifies the permissions of the created file, +where an integer representation of permissions is treated the same as +for file-or-directory-permissions. On Unix and Mac OS, these +permissions bits are combined with the process’s umask. On Windows, +the only relevant property of permissions is whether it has +the #o2 bit set for write permission. Note that a +read-only file can be created with open-output-file, in which +case writing is prohibited only for later attempts to open the file.

The file specified by path need not be a regular file. It +might be a device that is connected through the filesystem, such as +"aux" on Windows or "/dev/null" on Unix. The output +port is block-buffered by default, unless the file corresponds to a +terminal, in which case it is line-buffered by default. On Unix and +Mac OS, if the file is a fifo, then the port will block for writing +until a reader for the fifo is available; see also +port-waiting-peer?.

The port produced by open-output-file should be explicitly +closed, either though close-output-port or indirectly via +custodian-shutdown-all, to release the OS-level file +handle. The output port will not be closed automatically if it is +otherwise available for garbage collection (see +Garbage Collection); a will could be associated with an output port +to close it more automatically (see Wills and Executors).

A path value that is the cleansed version of +path is used as the name of the opened port.

If opening the file fails due to an error in the underlying filesystem +then exn:fail:filesystem:errno exception is raised.

Examples:
> (define out (open-output-file some-file))
> (write "hello world" out)
> (close-output-port out)

Changed in version 6.9.0.6 of package base: On Unix and Mac OS, make 'truncate/replace +replace on a permission error. On Windows, make +'replace always replace instead truncating +like 'truncate/replace.
Changed in version 7.4.0.5: Changed handling of a fifo on Unix and Mac OS to +make the port block for output until the fifo has a +reader.
Changed in version 8.1.0.3: Added the #:permissions argument.

procedure

(open-input-output-file path 
  [#:mode mode-flag 
  #:exists exists-flag 
  #:permissions permissions]) 
  
input-port? output-port?
  path : path-string?
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update 'can-update
      'replace 'truncate 'truncate/replace)
   = 'error
  permissions : (integer-in 0 65535) = #o666
Like open-output-file, but producing two values: an input +port and an output port. The two ports are connected in that they +share the underlying file descriptor. This procedure is intended for use +with special devices that can be opened by only one process, such as +"COM1" in Windows. For regular files, sharing the file descriptor can be +confusing. For example, using one port does not automatically flush +the other port’s buffer, and reading or writing in one port moves the +file position (if any) for the other port. For regular files, use +separate open-input-file and open-output-file calls +to avoid confusion.

procedure

(call-with-input-file path    
  proc    
  [#:mode mode-flag])  any
  path : path-string?
  proc : (input-port? . -> . any)
  mode-flag : (or/c 'binary 'text) = 'binary
Calls open-input-file with the path and +mode-flag arguments, and passes the resulting port +to proc. The result of proc is the result of the +call-with-input-file call, but the newly opened port is closed +when proc returns.

Examples:
> (with-output-to-file some-file
    (lambda () (printf "text in a file")))
> (call-with-input-file some-file
    (lambda (in) (read-string 14 in)))

"text in a file"

procedure

(call-with-output-file path    
  proc    
  [#:mode mode-flag    
  #:exists exists-flag    
  #:permissions permissions])  any
  path : path-string?
  proc : (output-port? . -> . any)
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update
      'replace 'truncate 'truncate/replace)
   = 'error
  permissions : (integer-in 0 65535) = #o666
Analogous to call-with-input-file, but passing path, +mode-flag, exists-flag, and permissions to +open-output-file.

Examples:
> (call-with-output-file some-file
    (lambda (out)
      (write 'hello out)))
> (call-with-input-file some-file
    (lambda (in)
      (read-string 5 in)))

"hello"

Changed in version 8.1.0.3 of package base: Added the #:permissions argument.

procedure

(call-with-input-file* path    
  proc    
  [#:mode mode-flag])  any
  path : path-string?
  proc : (input-port? . -> . any)
  mode-flag : (or/c 'binary 'text) = 'binary
Like call-with-input-file, but the newly opened port is +closed whenever control escapes the dynamic extent of the +call-with-input-file* call, whether through proc’s +return, a continuation application, or a prompt-based abort.

procedure

(call-with-output-file* path    
  proc    
  [#:mode mode-flag    
  #:exists exists-flag    
  #:permissions permissions])  any
  path : path-string?
  proc : (output-port? . -> . any)
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update
      'replace 'truncate 'truncate/replace)
   = 'error
  permissions : (integer-in 0 65535) = #o666
Like call-with-output-file, but the newly opened port is +closed whenever control escapes the dynamic extent of the +call-with-output-file* call, whether through proc’s +return, a continuation application, or a prompt-based abort.

Changed in version 8.1.0.3 of package base: Added the #:permissions argument.

procedure

(with-input-from-file path    
  thunk    
  [#:mode mode-flag])  any
  path : path-string?
  thunk : (-> any)
  mode-flag : (or/c 'binary 'text) = 'binary
Like call-with-input-file*, but instead of passing the newly +opened port to the given procedure argument, the port is installed as +the current input port (see current-input-port) using +parameterize around the call to thunk.

Examples:
> (with-output-to-file some-file
    (lambda () (printf "hello")))
> (with-input-from-file some-file
    (lambda () (read-string 5)))

"hello"

procedure

(with-output-to-file path    
  thunk    
  [#:mode mode-flag    
  #:exists exists-flag    
  #:permissions permissions])  any
  path : path-string?
  thunk : (-> any)
  mode-flag : (or/c 'binary 'text) = 'binary
  exists-flag : 
(or/c 'error 'append 'update
      'replace 'truncate 'truncate/replace)
   = 'error
  permissions : (integer-in 0 65535) = #o666
Like call-with-output-file*, but instead of passing the newly +opened port to the given procedure argument, the port is installed as +the current output port (see current-output-port) using +parameterize around the call to thunk.

Examples:
> (with-output-to-file some-file
    (lambda () (printf "hello")))
> (with-input-from-file some-file
    (lambda () (read-string 5)))

"hello"

Changed in version 8.1.0.3 of package base: Added the #:permissions argument.

procedure

(port-try-file-lock? port mode)  boolean?

  port : file-stream-port?
  mode : (or/c 'shared 'exclusive)
Attempts to acquire a lock on the file using the current platform’s +facilities for file locking. Multiple processes can acquire a +'shared lock on a file, but at most one process can hold an +'exclusive lock, and 'shared and 'exclusive +locks are mutually exclusive. When mode is 'shared, +then port must be an input port; when mode is +'exclusive, then port must be an output port.

The result is #t if the requested lock is acquired, +#f otherwise. When a lock is acquired, it is held until +either it is released with port-file-unlock or the port is closed +(perhaps because the process terminates).

Depending on the platform, locks may be merely advisory (i.e., locks +affect only the ability of processes to acquire locks) or they may +correspond to mandatory locks that prevent reads and writes to the +locked file. Specifically, locks are mandatory on Windows and advisory +on other platforms. Multiple tries for a 'shared lock on a +single port can succeed; on Unix and Mac OS, a single +port-file-unlock release the lock, while on other Windows, a +port-file-unlock is needed for each successful +port-try-file-lock?. On Unix and Mac OS, multiple tries for +a 'exclusive lock can succeed and a single +port-file-unlock releases the lock, while on Windows, a try +for an 'exclusive lock fails for a given port if the port +already holds the lock.

A lock acquired for an input port from open-input-output-file +can be released through port-file-unlock on the corresponding +output port, and vice versa. If the output port from +open-input-output-file holds an 'exclusive lock, the +corresponding input port can still acquire a 'shared lock, +even multiple times; on Windows, a port-file-unlock is needed +for each successful lock try, while a single port-file-unlock +balances the lock tries on Unix and Mac OS. A 'shared lock on +an input port can be upgraded to an 'exclusive lock through the +corresponding output port on Unix and Mac OS, in which case a single +port-file-unlock (on either port) releases the lock, while +such upgrades are not allowed on Windows.

Locking is normally supported only for file ports, and attempting to +acquire a lock with other kinds of file-stream ports raises an +exn:fail:filesystem exception.

procedure

(port-file-unlock port)  void?

  port : file-stream-port?
Releases a lock held by the current process on the file of +port.

Returns a number that represents +the identity of the device and file read or written by +port. For two ports whose open times overlap, the +result of port-file-identity is the same for both ports if +and only if the ports access the same device and file. For ports whose +open times do not overlap, no guarantee can be provided for the port +identities (even if the ports actually access the same file)—except +as can be inferred through relationships with other ports. If +port is closed, the exn:fail exception is raised. On +Windows 95, 98, and Me, if port is connected to a +pipe instead of a file, the exn:fail:filesystem exception is raised.

Examples:
> (define file1 (open-output-file some-file))
> (define file2 (open-output-file some-other-file))
> (port-file-identity file1)

7653369648741355870027010

> (port-file-identity file2)

7653388095485429579578626

> (close-output-port file1)
> (close-output-port file2)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/finger.png b/clones/docs.racket-lang.org/reference/finger.png new file mode 100644 index 0000000000000000000000000000000000000000..af521e80ad42a9ae5407c620edc296e7c4bba598 GIT binary patch literal 430 zcmV;f0a5;mP)eTsH8vpRWL7c@7w$U2V zgi@`8IW*&B=1?m>V;Oz8ig#GY1&kt(uaRJL+|!8fSVRHkJ&~^XDC0gRu!4Eqz@dty zF5_O6gc~p!Nf9Mxd4uOT6++))|5)r5@Cfa=i3Q1`CbZ!=hVh`9z`8RzWV-*AXPoi+C>$z!PbFr~XFZC^~RnYUHzs60YM8UZEf3*hQz`yocb^Zf> Y0+i!VsAM9jdH?_b07*qoM6N<$g28abDF6Tf literal 0 HcmV?d00001 diff --git a/clones/docs.racket-lang.org/reference/fixnums.html b/clones/docs.racket-lang.org/reference/fixnums.html new file mode 100644 index 00000000..0649eeac --- /dev/null +++ b/clones/docs.racket-lang.org/reference/fixnums.html @@ -0,0 +1,79 @@ + +4.3.4 Fixnums
4.3.4 Fixnums

 (require racket/fixnum) package: base

The racket/fixnum library provides operations like +fx+ that consume and produce only fixnums. The operations in +this library are meant to be safe versions of unsafe operations like +unsafe-fx+. These safe operations are generally no faster +than using generic primitives like +.

The expected use of the racket/fixnum library is for +code where the require of racket/fixnum is +replaced with

(require (filtered-in
          (λ (name)
            (and (regexp-match #rx"^unsafe-fx" name)
                 (regexp-replace #rx"unsafe-" name "")))
          racket/unsafe/ops))

to drop in unsafe versions of the library. Alternately, when +encountering crashes with code that uses unsafe fixnum operations, use +the racket/fixnum library to help debug the problems.

4.3.4.1 Fixnum Arithmetic

procedure

(fx+ a ...)  fixnum?

  a : fixnum?

procedure

(fx- a b ...)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fx* a ...)  fixnum?

  a : fixnum?

procedure

(fxquotient a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fxremainder a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fxmodulo a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fxabs a)  fixnum?

  a : fixnum?
Safe versions of unsafe-fx+, unsafe-fx-, +unsafe-fx*, unsafe-fxquotient, +unsafe-fxremainder, unsafe-fxmodulo, and +unsafe-fxabs. The +exn:fail:contract:non-fixnum-result exception is raised if the arithmetic +result would not be a fixnum.

Changed in version 7.0.0.13 of package base: Allow zero or more arguments for fx+ and fx* +and one or more arguments for fx-.

procedure

(fxand a ...)  fixnum?

  a : fixnum?

procedure

(fxior a ...)  fixnum?

  a : fixnum?

procedure

(fxxor a ...)  fixnum?

  a : fixnum?

procedure

(fxnot a)  fixnum?

  a : fixnum?

procedure

(fxlshift a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fxrshift a b)  fixnum?

  a : fixnum?
  b : fixnum?
Like bitwise-and, bitwise-ior, +bitwise-xor, bitwise-not, and +arithmetic-shift, but constrained to consume fixnums; +the result is always a fixnum. The unsafe-fxlshift and +unsafe-fxrshift operations correspond to +arithmetic-shift, but require non-negative arguments; +unsafe-fxlshift is a positive (i.e., left) shift, and +unsafe-fxrshift is a negative (i.e., right) shift, where the +number of bits to shift must be no more than the number of bits used to +represent a fixnum. The +exn:fail:contract:non-fixnum-result exception is raised if the arithmetic +result would not be a fixnum.

Changed in version 7.0.0.13 of package base: Allow any number of arguments for fxand, fxior, +and fxxor.

procedure

(fxpopcount a)  fixnum?

  a : (and/c fixnum? (not/c negative?))

procedure

(fxpopcount32 a)  fixnum?

  a : (and/c fixnum? (integer-in 0 #xFFFFFFFF))

procedure

(fxpopcount16 a)  fixnum?

  a : (and/c fixnum? (integer-in 0 #xFFFF))
Counts the number of bits in the two’s complement representation of +a. Depending on the platform, the fxpopcount32 and +fxpopcount16 operations can be faster when the result is +known to be no more than 32 or 16, respectively.

Added in version 8.5.0.7 of package base.

procedure

(fx+/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fx-/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fx*/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fxlshift/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?
Like fx+, fx-, fx*, and fxlshift, +but a fixnum result is produced for any allowed arguments (i.e., for +any fixnum argument, except that the second +fxlshift/wraparound argument must be between 0 and the number +of bits in a fixnum, inclusive). The result is produced by simply discarding bits +that do not fit in a fixnum representation. The result is negative if +the highest of the retained bits is set—even, for example, if the +value was produced by adding two positive fixnums.

Added in version 7.9.0.6 of package base.

procedure

(fx= a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(fx< a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(fx> a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(fx<= a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(fx>= a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(fxmin a b ...)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(fxmax a b ...)  fixnum?

  a : fixnum?
  b : fixnum?
Like =, <, >, +<=, >=, min, and max, but +constrained to consume fixnums.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(fx->fl a)  flonum?

  a : fixnum?

procedure

(fl->fx fl)  fixnum?

  fl : flonum?
Conversion between fixnums and flonums with truncation +in the case of converting a flonum to a fixnum.

The fx->fl function is the same as exact->inexact or +->fl constrained to a fixnum argument.

The fl->fx function is the same as truncate followed +by inexact->exact or fl->exact-integer constrained +to returning a fixnum. If the truncated flonum does not fit into a +fixnum, the exn:fail:contract exception is raised.

Changed in version 7.7.0.8 of package base: Changed fl->fx to truncate.

procedure

(fixnum-for-every-system? v)  boolean?

  v : any/c
Returns #t if v is a fixnum and is +represented by fixnum by every Racket implementation, #f +otherwise.

Added in version 7.3.0.11 of package base.

4.3.4.2 Fixnum Vectors

A fxvector is like a vector, but it holds only +fixnums. The only advantage of a fxvector over a +vector is that a shared version can be created with functions +like shared-fxvector.

Two fxvectors are equal? if they have the same length, +and if the values in corresponding slots of the fxvectors are +equal?.

A printed fxvector starts with #fx(, optionally with +a number between the #fx and +(. See Reading Vectors + for information on reading + fxvectors and Printing Vectors + for information on printing fxvectors.

procedure

(fxvector? v)  boolean?

  v : any/c
Returns #t if v is a fxvector, #f otherwise.

procedure

(fxvector x ...)  fxvector?

  x : fixnum?
Creates a fxvector containing the given fixnums.

Example:
> (fxvector 2 3 4 5)

(fxvector 2 3 4 5)

procedure

(make-fxvector size [x])  fxvector?

  size : exact-nonnegative-integer?
  x : fixnum? = 0
Creates a fxvector with size elements, where every +slot in the fxvector is filled with x.

Example:
> (make-fxvector 4 3)

(fxvector 3 3 3 3)

procedure

(fxvector-length vec)  exact-nonnegative-integer?

  vec : fxvector?
Returns the length of vec (i.e., the number of slots in the +fxvector).

procedure

(fxvector-ref vec pos)  fixnum?

  vec : fxvector?
  pos : exact-nonnegative-integer?
Returns the fixnum in slot pos of +vec. The first slot is position 0, and the last slot +is one less than (fxvector-length vec).

procedure

(fxvector-set! vec pos x)  fixnum?

  vec : fxvector?
  pos : exact-nonnegative-integer?
  x : fixnum?
Sets the fixnum in slot pos of vec. The +first slot is position 0, and the last slot is one less than +(fxvector-length vec).

procedure

(fxvector-copy vec [start end])  fxvector?

  vec : fxvector?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (vector-length v)
Creates a fresh fxvector of size (- end start), with all of the +elements of vec from start (inclusive) to +end (exclusive).

procedure

(in-fxvector vec [start stop step])  sequence?

  vec : fxvector?
  start : exact-nonnegative-integer? = 0
  stop : (or/c exact-integer? #f) = #f
  step : (and/c exact-integer? (not/c zero?)) = 1
Returns a sequence equivalent to vec when no optional +arguments are supplied.

The optional arguments start, stop, and +step are as in in-vector.

An in-fxvector application can provide better +performance for fxvector iteration when it appears directly in a for clause.

syntax

(for/fxvector maybe-length (for-clause ...) body ...)

syntax

(for*/fxvector maybe-length (for-clause ...) body ...)

 
maybe-length = 
  | #:length length-expr
  | #:length length-expr #:fill fill-expr
 
  length-expr : exact-nonnegative-integer?
  fill-expr : fixnum?
Like for/vector or for*/vector, but for +fxvectors. The default fill-expr produces 0.

procedure

(shared-fxvector x ...)  fxvector?

  x : fixnum?
Creates a fxvector containing the given fixnums. +For communication among places, the new fxvector is +allocated in the shared memory space.

Example:
> (shared-fxvector 2 3 4 5)

(fxvector 2 3 4 5)

procedure

(make-shared-fxvector size [x])  fxvector?

  size : exact-nonnegative-integer?
  x : fixnum? = 0
Creates a fxvector with size elements, where every +slot in the fxvector is filled with x. +For communication among places, the new fxvector is +allocated in the shared memory space.

Example:
> (make-shared-fxvector 4 3)

(fxvector 3 3 3 3)

4.3.4.3 Fixnum Range

procedure

(most-positive-fixnum)  fixnum?

procedure

(most-negative-fixnum)  fixnum?

Returns the largest-magnitude positive and negative fixnums. +The values of (most-positive-fixnum) and +(most-negative-fixnum) depend on the platform and virtual +machine, but all fixnums are in the range +(most-negative-fixnum) to (most-positive-fixnum) +inclusive, and all exact integers in that range are fixnums.

Added in version 8.1.0.7 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/flonums.html b/clones/docs.racket-lang.org/reference/flonums.html new file mode 100644 index 00000000..3307c2d8 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/flonums.html @@ -0,0 +1,73 @@ + +4.3.3 Flonums
4.3.3 Flonums

 (require racket/flonum) package: base

The racket/flonum library provides operations like +fl+ that consume and produce only +flonums. Flonum-specific operations can provide better +performance when used consistently, and they are as safe as generic +operations like +.

+See also Fixnum and Flonum Optimizations in The Racket Guide.

4.3.3.1 Flonum Arithmetic

procedure

(fl+ a ...)  flonum?

  a : flonum?

procedure

(fl- a b ...)  flonum?

  a : flonum?
  b : flonum?

procedure

(fl* a ...)  flonum?

  a : flonum?

procedure

(fl/ a b ...)  flonum?

  a : flonum?
  b : flonum?

procedure

(flabs a)  flonum?

  a : flonum?
Like +, -, *, /, and abs, +but constrained to consume flonums. The result is always a +flonum.

Changed in version 7.0.0.13 of package base: Allow zero or more arguments for fl+ and fl* +and one or more arguments for fl- and fl/.

procedure

(fl= a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(fl< a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(fl> a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(fl<= a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(fl>= a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(flmin a b ...)  flonum?

  a : flonum?
  b : flonum?

procedure

(flmax a b ...)  flonum?

  a : flonum?
  b : flonum?
Like =, <, >, <=, >=, +min, and max, but constrained to consume +flonums.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(flround a)  flonum?

  a : flonum?

procedure

(flfloor a)  flonum?

  a : flonum?

procedure

(flceiling a)  flonum?

  a : flonum?

procedure

(fltruncate a)  flonum?

  a : flonum?
Like round, floor, ceiling, and +truncate, but constrained to consume flonums.

procedure

(flsingle a)  flonum?

  a : flonum?
Returns a value like a, but potentially discards precision +and range so that the result can be represented as a single-precision +IEEE floating-point number (even if single-flonums are not +supported).

Using flsingle on the arguments and results of fl+, +fl-, fl*, fl/, and flsqrtthat +is, performing double-precision operations on values representable in +single precision and then rounding the result to single precision—is +always the same as performing the corresponding single-precision +operation [Roux14]. (For other operations, the IEEE +floating-point specification does not make enough guarantees to say +more about the interaction with flsingle.)

Added in version 7.8.0.7 of package base.

procedure

(flsin a)  flonum?

  a : flonum?

procedure

(flcos a)  flonum?

  a : flonum?

procedure

(fltan a)  flonum?

  a : flonum?

procedure

(flasin a)  flonum?

  a : flonum?

procedure

(flacos a)  flonum?

  a : flonum?

procedure

(flatan a)  flonum?

  a : flonum?

procedure

(fllog a)  flonum?

  a : flonum?

procedure

(flexp a)  flonum?

  a : flonum?

procedure

(flsqrt a)  flonum?

  a : flonum?
Like sin, cos, tan, asin, +acos, atan, log, exp, and +sqrt, but constrained to consume and produce +flonums. The result is +nan.0 when a number outside +the range -1.0 to 1.0 is given to flasin or +flacos, or when a negative number is given to fllog +or flsqrt.

procedure

(flexpt a b)  flonum?

  a : flonum?
  b : flonum?
Like expt, but constrained to consume and produce +flonums.

Due to the result constraint, the results compared to expt +differ in the following cases: +These special cases correspond to pow in C99 [C99]. +
  • (flexpt -1.0 +inf.0) 1.0

  • (flexpt a +inf.0) where a is +negative — (expt (abs a) +inf.0)

  • (flexpt a -inf.0) where a is +negative — (expt (abs a) -inf.0)

  • (expt -inf.0 b) where b is a non-integer: +
    • b is negative — 0.0

    • b is positive — +inf.0

  • (flexpt a b) where a is +negative and b is not an integer — +nan.0

procedure

(->fl a)  flonum?

  a : exact-integer?
Like exact->inexact, but constrained to consume exact +integers, so the result is always a flonum.

procedure

(fl->exact-integer a)  exact-integer?

  a : flonum?
Like inexact->exact, but constrained to consume an +integer flonum, so the result is always an exact +integer.

procedure

(make-flrectangular a b)

  
(and/c complex?
       (lambda (c) (flonum? (real-part c)))
       (lambda (c) (flonum? (imag-part c))))
  a : flonum?
  b : flonum?

procedure

(flreal-part a)  flonum?

  a : 
(and/c complex?
       (lambda (c) (flonum? (real-part c)))
       (lambda (c) (flonum? (imag-part c))))

procedure

(flimag-part a)  flonum?

  a : 
(and/c complex?
       (lambda (c) (flonum? (real-part c)))
       (lambda (c) (flonum? (imag-part c))))
Like make-rectangular, real-part, and +imag-part, but both parts of the complex number must be +inexact.

procedure

(flrandom rand-gen)  (and flonum? (>/c 0) (</c 1))

  rand-gen : pseudo-random-generator?
Equivalent to (random rand-gen).

4.3.3.2 Flonum Vectors

A flvector is like a vector, but it holds only +inexact real numbers. This representation can be more compact, and +unsafe operations on flvectors (see +racket/unsafe/ops) can execute more efficiently than +unsafe operations on vectors of inexact reals.

An f64vector as provided by ffi/vector stores the +same kinds of values as a flvector, but with extra +indirections that make f64vectors more convenient for working with +foreign libraries. The lack of indirections makes unsafe +flvector access more efficient.

Two flvectors are equal? if they have the same length, +and if the values in corresponding slots of the flvectors are +equal?.

A printed flvector starts with #fl(, optionally with +a number between the #fl and +(. See Reading Vectors + for information on reading + flvectors and Printing Vectors + for information on printing flvectors.

procedure

(flvector? v)  boolean?

  v : any/c
Returns #t if v is a flvector, #f otherwise.

procedure

(flvector x ...)  flvector?

  x : flonum?
Creates a flvector containing the given inexact real numbers.

Example:
> (flvector 2.0 3.0 4.0 5.0)

(flvector 2.0 3.0 4.0 5.0)

procedure

(make-flvector size [x])  flvector?

  size : exact-nonnegative-integer?
  x : flonum? = 0.0
Creates a flvector with size elements, where every +slot in the flvector is filled with x.

Example:
> (make-flvector 4 3.0)

(flvector 3.0 3.0 3.0 3.0)

procedure

(flvector-length vec)  exact-nonnegative-integer?

  vec : flvector?
Returns the length of vec (i.e., the number of slots in the +flvector).

procedure

(flvector-ref vec pos)  flonum?

  vec : flvector?
  pos : exact-nonnegative-integer?
Returns the inexact real number in slot pos of +vec. The first slot is position 0, and the last slot +is one less than (flvector-length vec).

procedure

(flvector-set! vec pos x)  flonum?

  vec : flvector?
  pos : exact-nonnegative-integer?
  x : flonum?
Sets the inexact real number in slot pos of vec. The +first slot is position 0, and the last slot is one less than +(flvector-length vec).

procedure

(flvector-copy vec [start end])  flvector?

  vec : flvector?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (vector-length v)
Creates a fresh flvector of size (- end start), with all of the +elements of vec from start (inclusive) to +end (exclusive).

procedure

(in-flvector vec [start stop step])  sequence?

  vec : flvector?
  start : exact-nonnegative-integer? = 0
  stop : (or/c exact-integer? #f) = #f
  step : (and/c exact-integer? (not/c zero?)) = 1
Returns a sequence equivalent to vec when no optional +arguments are supplied.

The optional arguments start, stop, and +step are as in in-vector.

A in-flvector application can provide better +performance for flvector iteration when it appears directly in a for clause.

syntax

(for/flvector maybe-length (for-clause ...) body ...)

syntax

(for*/flvector maybe-length (for-clause ...) body ...)

 
maybe-length = 
  | #:length length-expr
  | #:length length-expr #:fill fill-expr
 
  length-expr : exact-nonnegative-integer?
  fill-expr : flonum?
Like for/vector or for*/vector, but for +flvectors. The default fill-expr produces 0.0.

procedure

(shared-flvector x ...)  flvector?

  x : flonum?
Creates a flvector containing the given inexact real numbers. +For communication among places, the new flvector is +allocated in the shared memory space.

Example:
> (shared-flvector 2.0 3.0 4.0 5.0)

(flvector 2.0 3.0 4.0 5.0)

procedure

(make-shared-flvector size [x])  flvector?

  size : exact-nonnegative-integer?
  x : flonum? = 0.0
Creates a flvector with size elements, where every +slot in the flvector is filled with x. +For communication among places, the new flvector is +allocated in the shared memory space.

Example:
> (make-shared-flvector 4 3.0)

(flvector 3.0 3.0 3.0 3.0)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/for.html b/clones/docs.racket-lang.org/reference/for.html new file mode 100644 index 00000000..27385b75 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/for.html @@ -0,0 +1,259 @@ + +3.18 Iterations and Comprehensions: for, for/list, ...

3.18 Iterations and Comprehensions: for, for/list, ...

+Iterations and Comprehensions in The Racket Guide introduces iterations and comprehensions.

The for iteration forms are based on SRFI-42 +[SRFI-42].

3.18.1 Iteration and Comprehension Forms

syntax

(for (for-clause ...) body-or-break ... body)

 
for-clause = [id seq-expr]
  | [(id ...) seq-expr]
  | #:when guard-expr
  | #:unless guard-expr
  | #:do [do-body ...]
  | break-clause
  | #:splice (splicing-id . form)
     
break-clause = #:break guard-expr
  | #:final guard-expr
     
body-or-break = body
  | break-clause
 
  seq-expr : sequence?
Iteratively evaluates bodys. The for-clauses +introduce bindings whose scope includes body and that +determine the number of times that body is evaluated. +A break-clause either among the for-clauses +or bodys stops further iteration.

In the simple case, each for-clause has one of its first two +forms, where [id seq-expr] is a shorthand for [(id) seq-expr]. In this simple case, the seq-exprs are evaluated +left-to-right, and each must produce a sequence value (see +Sequences).

The for form iterates by drawing an element from each +sequence; if any sequence is empty, then the iteration stops, and +#<void> is the result of the for expression. Otherwise +a location is created for each id to hold the values of each +element; the sequence produced by a seq-expr must return as +many values for each iteration as corresponding ids.

The ids are then bound in the body, which is +evaluated, and whose results are ignored. Iteration continues with the +next element in each sequence and with fresh locations for each +id.

A for form with zero for-clauses is equivalent to a +single for-clause that binds an unreferenced id to +a sequence containing a single element. All of the ids must +be distinct according to bound-identifier=?.

If any for-clause has the form #:when guard-expr, +then only the preceding clauses (containing no #:when, #:unless, or #:do) +determine iteration as above, and the body is effectively +wrapped as

(when guard-expr
  (for (for-clause ...) body ...+))

using the remaining for-clauses. A for-clause of +the form #:unless guard-expr corresponds to the same transformation +with unless in place of when. A for-clause of +the form #:do [do-body ...] similarly creates nesting and +corresponds to

(let ()
  do-body ...
  (for (for-clause ...) body ...+))

where the do-body forms may introduce definitions that are +visible in the remaining for-clauses.

A #:break guard-expr clause is similar to a +#:unless guard-expr clause, but when #:break +avoids evaluation of the bodys, it also effectively ends all +sequences within the for form. A #:final guard-expr clause is similar to #:break guard-expr, but +instead of immediately ending sequences and skipping the +bodys, it allows at most one more element from each later +sequence and at most one more evaluation of the following +bodys. Among the bodys, besides stopping the +iteration and preventing later body evaluations, a +#:break guard-expr or #:final guard-expr +clause starts a new internal-definition context.

A #:splice (splicing-id . form) clause is replaced by the +sequence of forms that are produced by expanding (splicing-id . form), where splicing-id is bound using +define-splicing-for-clause-syntax. The binding context of +that expansion includes previous binding from any clause preceding +both the #:splice form and a #:when, +#:unless, #:do, #:break, or +#:final form. The result of a #:splice expansion can +include more #:splice forms to further interleave clause +binding and expansion. Support for #:splicing clauses is +intended less for direct use in source for forms than for +building new forms that expand to for.

In the case of list and stream sequences, the +for form itself does not keep each element reachable. If a +list or stream produced by a seq-expr is otherwise +unreachable, and if the for body can no longer reference an +id for a list element, then the element is subject to +garbage collection. The make-do-sequence sequence +constructor supports additional sequences that behave like lists and +streams in this way.

If a seq-expr is a quoted literal list, vector, exact integer, +string, byte string, immutable hash, or expands to such a literal, +then it may be treated as if a sequence transformer such as +in-list was used, unless the seq-expr has a true +value for the 'for:no-implicit-optimization syntax +property; in most cases this improves performance.

Examples:
> (for ([i '(1 2 3)]
        [j "abc"]
        #:when (odd? i)
        [k #(#t #f)])
    (display (list i j k)))

(1 a #t)(1 a #f)(3 c #t)(3 c #f)

> (for ([i '(1 2 3)]
        #:do [(define neg-i (* i -1))]
        [j (list neg-i 0 i)])
    (display (list j)))

(-1)(0)(1)(-2)(0)(2)(-3)(0)(3)

> (for ([(i j) #hash(("a" . 1) ("b" . 20))])
    (display (list i j)))

(a 1)(b 20)

> (for ([i '(1 2 3)]
        [j "abc"]
        #:break (not (odd? i))
        [k #(#t #f)])
    (display (list i j k)))

(1 a #t)(1 a #f)

> (for ([i '(1 2 3)]
        [j "abc"]
        #:final (not (odd? i))
        [k #(#t #f)])
    (display (list i j k)))

(1 a #t)(1 a #f)(2 b #t)

> (for ([i '(1 2 3)]
        [j "abc"]
        [k #(#t #f)])
    #:break (not (or (odd? i) k))
    (display (list i j k)))

(1 a #t)

> (for ()
    (display "here"))

here

> (for ([i '()])
    (error "doesn't get here"))

Changed in version 6.7.0.4 of package base: Added support for the optional second result.
Changed in version 7.8.0.11: Added support for implicit optimization.
Changed in version 8.4.0.2: Added #:do.
Changed in version 8.4.0.3: Added #:splice.

syntax

(for/list (for-clause ...) body-or-break ... body)

Iterates like +for, but that the last expression in the bodys must +produce a single value, and the result of the for/list +expression is a list of the results in order. +When evaluation of a body is skipped due to a #:when +or #:unless clause, the result list includes no corresponding +element.

Examples:
> (for/list ([i '(1 2 3)]
             [j "abc"]
             #:when (odd? i)
             [k #(#t #f)])
    (list i j k))

'((1 #\a #t) (1 #\a #f) (3 #\c #t) (3 #\c #f))

> (for/list ([i '(1 2 3)]
             [j "abc"]
             #:break (not (odd? i))
             [k #(#t #f)])
    (list i j k))

'((1 #\a #t) (1 #\a #f))

> (for/list () 'any)

'(any)

> (for/list ([i '()])
    (error "doesn't get here"))

'()

syntax

(for/vector maybe-length (for-clause ...) body-or-break ... body)

 
maybe-length = 
  | #:length length-expr
  | #:length length-expr #:fill fill-expr
 
  length-expr : exact-nonnegative-integer?
Iterates like for/list, but results are accumulated into +a vector instead of a list.

If the optional #:length clause is specified, the result of +length-expr determines the length of the result vector. In +that case, the iteration can be performed more efficiently, and it +terminates when the vector is full or the requested number of +iterations have been performed, whichever comes first. If +length-expr specifies a length longer than the number of +iterations, then the remaining slots of the vector are initialized to +the value of fill-expr, which defaults to 0 (i.e., +the default argument of make-vector).

Examples:
> (for/vector ([i '(1 2 3)]) (number->string i))

'#("1" "2" "3")

> (for/vector #:length 2 ([i '(1 2 3)]) (number->string i))

'#("1" "2")

> (for/vector #:length 4 ([i '(1 2 3)]) (number->string i))

'#("1" "2" "3" 0)

> (for/vector #:length 4 #:fill "?" ([i '(1 2 3)]) (number->string i))

'#("1" "2" "3" "?")

The for/vector form may allocate a vector and mutate it after +each iteration of body, which means that capturing a +continuation during body and applying it multiple times may +mutate a shared vector.

syntax

(for/hash (for-clause ...) body-or-break ... body)

syntax

(for/hasheq (for-clause ...) body-or-break ... body)

syntax

(for/hasheqv (for-clause ...) body-or-break ... body)

syntax

(for/hashalw (for-clause ...) body-or-break ... body)

Like for/list, but the result is an immutable hash +table; for/hash creates a table using equal? to +distinguish keys, for/hasheq produces a table using +eq?, for/hasheqv produces a table using +eqv?, and for/hashalw produces a table using +equal-always?. +The last expression in the bodys must return +two values: a key and a value to extend the hash table accumulated by +the iteration.

Example:
> (for/hash ([i '(1 2 3)])
    (values i (number->string i)))

'#hash((1 . "1") (2 . "2") (3 . "3"))

Changed in version 8.5.0.3 of package base: Added the for/hashalw form.

syntax

(for/and (for-clause ...) body-or-break ... body)

Iterates like +for, but when last expression of body produces +#f, then iteration terminates, and the result of the +for/and expression is #f. If the body +is never evaluated, then the result of the for/and +expression is #t. Otherwise, the result is the (single) +result from the last evaluation of body.

Examples:
> (for/and ([i '(1 2 3 "x")])
    (i . < . 3))

#f

> (for/and ([i '(1 2 3 4)])
    i)

4

> (for/and ([i '(1 2 3 4)])
    #:break (= i 3)
    i)

2

> (for/and ([i '()])
    (error "doesn't get here"))

#t

syntax

(for/or (for-clause ...) body-or-break ... body)

Iterates like +for, but when last expression of body produces +a value other than #f, then iteration terminates, and +the result of the for/or expression is the same +(single) value. If the body is never evaluated, then the +result of the for/or expression is +#f. Otherwise, the result is #f.

Examples:
> (for/or ([i '(1 2 3 "x")])
    (i . < . 3))

#t

> (for/or ([i '(1 2 3 4)])
    i)

1

> (for/or ([i '()])
    (error "doesn't get here"))

#f

syntax

(for/sum (for-clause ...) body-or-break ... body)

Iterates like for, but each result of the last body +is accumulated into a result with +.

Example:
> (for/sum ([i '(1 2 3 4)]) i)

10

syntax

(for/product (for-clause ...) body-or-break ... body)

Iterates like for, but each result of the last body +is accumulated into a result with *.

Example:
> (for/product ([i '(1 2 3 4)]) i)

24

syntax

(for/lists (id ... maybe-result)
           (for-clause ...)
  body-or-break ... body)
 
maybe-result = 
  | #:result result-expr
Similar to for/list, but the last body expression +should produce as many values as given ids. +The ids are bound to +the reversed lists accumulated so far in the for-clauses and +bodys.

If a result-expr is provided, it is used as with for/fold +when iteration terminates; +otherwise, the result is as many lists as supplied ids.

The scope of id bindings is the same as for accumulator +identifiers in for/fold. Mutating a id affects the +accumulated lists, and mutating it in a way that produces a non-list +can cause a final reverse for each id to fail.

Examples:
> (for/lists (l1 l2 l3)
             ([i '(1 2 3)]
              [j "abc"]
              #:when (odd? i)
              [k #(#t #f)])
    (values i j k))

'(1 1 3 3)

'(#\a #\a #\c #\c)

'(#t #f #t #f)

> (for/lists (acc)
             ([x '(tvp tofu seitan tvp tofu)]
              #:unless (member x acc))
    x)

'(tvp tofu seitan)

> (for/lists (firsts seconds #:result (list firsts seconds))
             ([pr '((1 . 2) (3 . 4) (5 . 6))])
    (values (car pr) (cdr pr)))

'((1 3 5) (2 4 6))

Changed in version 7.1.0.2 of package base: Added the #:result form.

syntax

(for/first (for-clause ...) body-or-break ... body)

Iterates like +for, but after body is evaluated the first +time, then the iteration terminates, and the for/first +result is the (single) result of body. If the +body is never evaluated, then the result of the +for/first expression is #f.

Examples:
> (for/first ([i '(1 2 3 "x")]
              #:when (even? i))
     (number->string i))

"2"

> (for/first ([i '()])
    (error "doesn't get here"))

#f

syntax

(for/last (for-clause ...) body-or-break ... body)

Iterates like +for, but the for/last result is the (single) +result of the last evaluation of body. If the +body is never evaluated, then the result of the +for/last expression is #f.

Examples:
> (for/last ([i '(1 2 3 4 5)]
              #:when (even? i))
     (number->string i))

"4"

> (for/last ([i '()])
    (error "doesn't get here"))

#f

syntax

(for/fold ([accum-id init-expr] ... maybe-result) (for-clause ...)
  body-or-break ... body)
 
maybe-result = 
  | #:result result-expr
Iterates like for. Before iteration starts, the +init-exprs are evaluated to produce initial accumulator +values. At the start of each iteration, a location is generated +for each accum-id, and the corresponding current accumulator +value is placed into the location. The last expression in +body must produce as many values as accum-ids, and +those values become the current accumulator values. When iteration +terminates, if a result-expr is provided then the result of the + for/fold is the result of evaluating result-expr + (with accum-ids in scope and bound to their final values), + otherwise the results of the for/fold expression are the + accumulator values.

Examples:
> (for/fold ([sum 0]
             [rev-roots null])
            ([i '(1 2 3 4)])
    (values (+ sum i) (cons (sqrt i) rev-roots)))

10

'(2 1.7320508075688772 1.4142135623730951 1)

> (for/fold ([acc '()]
             [seen (hash)]
             #:result (reverse acc))
            ([x (in-list '(0 1 1 2 3 4 4 4))])
    (cond
      [(hash-ref seen x #f)
       (values acc seen)]
      [else (values (cons x acc)
                    (hash-set seen x #t))]))

'(0 1 2 3 4)

The binding and evaluation order of accum-ids and +init-exprs do not completely follow the textual, +left-to-right order relative to the for-clauses. Instead, the +sequence expressions in for-clauses that determine the +outermost iteration are evaluated first, then the init-exprs +are evaluated and the accum-ids are bound, and finally the +outermost iteration’s identifiers are bound. One consequence is that +the accum-ids are not bound in for-clauses for the +outermost initialization. At the same time, when a accum-id +is used as a for-clause binding for the outermost iteration, +the for-clause binding shadows the accum-id binding +in the loop body (which is what you would expect syntactically). +A fresh variable for each accum-id (at a +fresh location) is bound in each nested iteration that is created by a +later group for for-clauses (after a #:when or +#:unless, for example).

Changed in version 6.11.0.1 of package base: Added the #:result form.

syntax

(for/foldr ([accum-id init-expr] ... accum-option ...)
           (for-clause ...)
  body-or-break ... body)
 
accum-option = #:result result-expr
  | #:delay
  | #:delay-as delayed-id
  | #:delay-with delayer-id
Like for/fold, but analogous to foldr rather than +foldl: the given sequences are still iterated in the same order, but +the loop body is evaluated in reverse order. Evaluation of a for/foldr +expression uses space proportional to the number of iterations it performs, and +all elements produced by the given sequences are retained until backwards +evaluation of the loop body begins (assuming the element is, in fact, +referenced in the body).

Examples:
> (define (in-printing seq)
    (sequence-map (lambda (v) (println v) v) seq))
> (for/foldr ([acc '()])
             ([v (in-printing (in-range 1 4))])
    (println v)
    (cons v acc))

1

2

3

3

2

1

'(1 2 3)

Furthermore, unlike for/fold, the accum-ids are not bound +within guard-exprs or body-or-break forms that appear before +a break-clause.

While the aforementioned limitations make for/foldr less generally +useful than for/fold, for/foldr provides the additional +capability to iterate lazily via the #:delay, #:delay-as, and +#:delay-with options, which can mitigate many of for/foldr’s +disadvantages. If at least one such option is specified, the loop body is given +explicit control over when iteration continues: by default, each +accum-id is bound to a promise that, when forced, produces the +accum-id’s current value.

In this mode, iteration does not continue until one such promise is forced, +which triggers any additional iteration necessary to produce a value. If the +loop body is lazy in its accum-ids—that is, it returns a value +without forcing any of them—then the loop (or any of its iterations) will +produce a value before iteration has completely finished. If a reference to at +least one such promise is retained, then forcing it will resume iteration from +the point at which it was suspended, even if control has left the dynamic extent +of the loop body.

Examples:
> (for/foldr ([acc '()] #:delay)
             ([v (in-range 1 4)])
    (printf "--> ~v\n" v)
    (begin0
      (cons v (force acc))
      (printf "<-- ~v\n" v)))

--> 1

--> 2

--> 3

<-- 3

<-- 2

<-- 1

'(1 2 3)

> (define resume
    (for/foldr ([acc '()] #:delay)
               ([v (in-range 1 5)])
      (printf "--> ~v\n" v)
      (begin0
        (cond
          [(= v 1) (force acc)]
          [(= v 2) acc]
          [else    (cons v (force acc))])
        (printf "<-- ~v\n" v))))

--> 1

--> 2

<-- 2

<-- 1

> (force resume)

--> 3

--> 4

<-- 4

<-- 3

'(3 4)

This extra control over iteration order allows for/foldr to both +consume and construct infinite sequences, so long as it is at least sometimes +lazy in its accumulators.

+See also for/stream for a more convenient (albeit less flexible) way +to lazily transform infinite sequences. (Internally, for/stream is +defined in terms of for/foldr.)

Examples:
> (define squares (for/foldr ([s empty-stream] #:delay)
                             ([n (in-naturals)])
                    (stream-cons (* n n) (force s))))
> (stream->list (stream-take squares 10))

'(0 1 4 9 16 25 36 49 64 81)

The suspension introduced by the #:delay option does not ordinarily +affect the loop’s eventual return value, but if #:delay and +#:result are combined, the accum-ids will be delayed in the +scope of the result-expr in the same way they are delayed within the +loop body. This can be used to introduce an additional layer of suspension +around the evaluation of the entire loop, if desired.

Examples:
> (define evaluated-yet? #f)
> (for/foldr ([acc (set! evaluated-yet? #t)] #:delay) ()
    (force acc))
> evaluated-yet?

#t

> (define evaluated-yet? #f)
> (define start
    (for/foldr ([acc (set! evaluated-yet? #t)] #:delay #:result acc) ()
      (force acc)))
> evaluated-yet?

#f

> (force start)
> evaluated-yet?

#t

If the #:delay-as option is provided, then delayed-id is +bound to an additional promise that returns the values of all accum-ids +at once. When multiple accum-ids are provided, forcing this promise can +be slightly more efficient than forcing the promises bound to the +accum-ids individually.

If the #:delay-with option is provided, the given delayer-id +is used to suspend nested iterations (instead of the default, delay). +A form of the shape (delayer-id recur-expr) is constructed and placed +in expression position, where recur-expr is an expression that, when +evaluated, will perform the next iteration and return its result (or results). +Sensible choices for delayer-id include lazy, +delay/sync, delay/thread, or any of the other promise +constructors from racket/promise, as well as thunk from +racket/function. However, beware that choices such as +thunk or delay/name may evaluate their subexpression multiple +times, which can lead to nonsensical results for sequences that have state, as +the state will be shared between all evaluations of the recur-expr.

If multiple accum-ids are given, the #:delay-with option is +provided, and delayer-id is not bound to one of delay, +lazy, delay/strict, delay/sync, +delay/thread, or delay/idle, the accum-ids will not +be bound at all, even within the loop body. Instead, the #:delay-as +option must be specified to access the accumulator values via +delayed-id.

Added in version 7.3.0.3 of package base.

syntax

(for* (for-clause ...) body-or-break ... body)

Like for, but with an implicit #:when #t between +each pair of for-clauses, so that all sequence iterations are +nested.

Example:
> (for* ([i '(1 2)]
         [j "ab"])
    (display (list i j)))

(1 a)(1 b)(2 a)(2 b)

syntax

(for*/list (for-clause ...) body-or-break ... body)

syntax

(for*/lists (id ... maybe-result) (for-clause ...)
  body-or-break ... body)

syntax

(for*/vector maybe-length (for-clause ...) body-or-break ... body)

syntax

(for*/hash (for-clause ...) body-or-break ... body)

syntax

(for*/hasheq (for-clause ...) body-or-break ... body)

syntax

(for*/hasheqv (for-clause ...) body-or-break ... body)

syntax

(for*/hashalw (for-clause ...) body-or-break ... body)

syntax

(for*/and (for-clause ...) body-or-break ... body)

syntax

(for*/or (for-clause ...) body-or-break ... body)

syntax

(for*/sum (for-clause ...) body-or-break ... body)

syntax

(for*/product (for-clause ...) body-or-break ... body)

syntax

(for*/first (for-clause ...) body-or-break ... body)

syntax

(for*/last (for-clause ...) body-or-break ... body)

syntax

(for*/fold ([accum-id init-expr] ... maybe-result) (for-clause ...)
  body-or-break ... body)

syntax

(for*/foldr ([accum-id init-expr] ... accum-option ...)
            (for-clause ...)
  body-or-break ... body)
Like for/list, etc., but with the implicit nesting of +for*.

Example:
> (for*/list ([i '(1 2)]
              [j "ab"])
    (list i j))

'((1 #\a) (1 #\b) (2 #\a) (2 #\b))

Changed in version 7.3.0.3 of package base: Added the for*/foldr form.
Changed in version 8.5.0.3: Added the for*/hashalw form.

3.18.2 Deriving New Iteration Forms

syntax

(for/fold/derived orig-datum
  ([accum-id init-expr] ... maybe-result) (for-clause ...)
  body-or-break ... body)
Like for/fold, but the extra orig-datum is used as the +source for all syntax errors.

A macro that expands to for/fold/derived should typically use +split-for-body to handle the possibility of macros and other +definitions mixed with keywords like #:break.

Examples:
> (require (for-syntax syntax/for-body)
           syntax/parse/define)
> (define-syntax-parse-rule (for/digits clauses body ... tail-expr)
    #:with original this-syntax
    #:with ((pre-body ...) (post-body ...)) (split-for-body this-syntax #'(body ... tail-expr))
    (for/fold/derived original ([n 0] [k 1] #:result n)
      clauses
      pre-body ...
      (values (+ n (* (let () post-body ...) k)) (* k 10))))
; If we misuse for/digits, we can get good error reporting
; because the use of orig-datum allows for source correlation:
> (for/digits
      [a (in-list '(1 2 3))]
      [b (in-list '(4 5 6))]
    (+ a b))

eval:4:0: for/digits: bad sequence binding clause

  at: a

  in: (for/digits (a (in-list (quote (1 2 3)))) (b (in-list

(quote (4 5 6)))) (+ a b))

> (for/digits
      ([a (in-list '(1 2 3))]
       [b (in-list '(2 4 6))])
    (+ a b))

963

; Another example: compute the max during iteration:
> (define-syntax-parse-rule (for/max clauses body ... tail-expr)
    #:with original this-syntax
    #:with ((pre-body ...) (post-body ...)) (split-for-body this-syntax #'(body ... tail-expr))
    (for/fold/derived original
      ([current-max -inf.0])
      clauses
      pre-body ...
      (define maybe-new-max (let () post-body ...))
      (if (> maybe-new-max current-max)
          maybe-new-max
          current-max)))
> (for/max ([n '(3.14159 2.71828 1.61803)]
            [s '(-1      1       1)])
    (* n s))

2.71828

Changed in version 6.11.0.1 of package base: Added the #:result form.

syntax

(for*/fold/derived orig-datum
  ([accum-id init-expr] ... maybe-result) (for-clause ...)
  body-or-break ... body)
Like for*/fold, but the extra orig-datum is used as the source for all syntax errors.

Examples:
> (require (for-syntax syntax/for-body)
           syntax/parse/define)
> (define-syntax-parse-rule (for*/digits clauses body ... tail-expr)
    #:with original this-syntax
    #:with ((pre-body ...) (post-body ...)) (split-for-body this-syntax #'(body ... tail-expr))
    (for*/fold/derived original ([n 0] [k 1] #:result n)
      clauses
      pre-body ...
      (values (+ n (* (let () post-body ...) k)) (* k 10))))
> (for*/digits
      [ds (in-list '((8 3) (1 1)))]
      [d (in-list ds)]
    d)

eval:10:0: for*/digits: bad sequence binding clause

  at: ds

  in: (for*/digits (ds (in-list (quote ((8 3) (1 1))))) (d

(in-list ds)) d)

> (for*/digits
      ([ds (in-list '((8 3) (1 1)))]
       [d (in-list ds)])
    d)

1138

Changed in version 6.11.0.1 of package base: Added the #:result form.

syntax

(for/foldr/derived orig-datum
  ([accum-id init-expr] ... accum-option ...) (for-clause ...)
  body-or-break ... body)

syntax

(for*/foldr/derived orig-datum
  ([accum-id init-expr] ... accum-option ...) (for-clause ...)
  body-or-break ... body)
Like for/foldr and for*/foldr, but the extra +orig-datum is used as the source for all syntax errors as in +for/fold/derived and for*/fold/derived.

Added in version 7.3.0.3 of package base.

syntax

(define-sequence-syntax id
  expr-transform-expr
  clause-transform-expr)
 
  expr-transform-expr : 
(or/c (-> identifier?)
      (syntax? . -> . syntax?))
  clause-transform-expr : (syntax? . -> . syntax?)
Defines id as syntax. An (id . rest) form is +treated specially when used to generate a sequence in a +for-clause of for (or one of its variants). In that +case, the procedure result of clause-transform-expr is called +to transform the clause.

When id is used in any other expression position, the result +of expr-transform-expr is used. If it is a procedure of zero +arguments, then the result must be an identifier other-id, +and any use of id is converted to a use of +other-id. Otherwise, expr-transform-expr must +produce a procedure (of one argument) that is used as a macro +transformer.

When the clause-transform-expr transformer is used, it is +given a for-clause as an argument, where the clause’s form is +normalized so that the left-hand side is a parenthesized sequence of +identifiers. The right-hand side is of the form (id . rest). +The result can be either #f, to indicate that the forms +should not be treated specially (perhaps because the number of bound +identifiers is inconsistent with the (id . rest) form), or a +new for-clause to replace the given one. The new clause might +use :do-in. To protect identifiers in the result of +clause-transform-expr, use for-clause-syntax-protect +instead of syntax-protect.

Examples:
> (define (check-nat n)
    (unless (exact-nonnegative-integer? n)
      (raise-argument-error 'in-digits "exact-nonnegative-integer?" n)))
> (define-sequence-syntax in-digits
    (lambda () #'in-digits/proc)
    (lambda (stx)
      (syntax-case stx ()
        [[(d) (_ nat)]
         #'[(d)
            (:do-in
              ([(n) nat])
              (check-nat n)
              ([i n])
              (not (zero? i))
              ([(j d) (quotient/remainder i 10)])
              #t
              #t
              [j])]]
        [_ #f])))
> (define (in-digits/proc n)
    (for/list ([d (in-digits n)]) d))
> (for/list ([d (in-digits 1138)]) d)

'(8 3 1 1)

> (map in-digits (list 137 216))

'((7 3 1) (6 1 2))

syntax

(:do-in ([(outer-id ...) outer-expr] ...)
        outer-check
        ([loop-id loop-expr] ...)
        pos-guard
        ([(inner-id ...) inner-expr] ...)
        pre-guard
        post-guard
        (loop-arg ...))
A form that can only be used as a seq-expr in a +for-clause of for (or one of its variants).

Within a for, the pieces of the :do-in form are +spliced into the iteration essentially as follows:

(let-values ([(outer-id ...) outer-expr] ...)
  outer-check
  (let loop ([loop-id loop-expr] ...)
    (if pos-guard
        (let-values ([(inner-id ...) inner-expr] ...)
          (if pre-guard
              (let body-bindings
                   (if post-guard
                       (loop loop-arg ...)
                       done-expr))
              done-expr))
         done-expr)))

where body-bindings and done-expr are from the +context of the :do-in use. The identifiers bound by the +for clause are typically part of the ([(inner-id ...) inner-expr] ...) section.

Beware that body-bindings and done-expr can +contain arbitrary expressions, potentially including set! on +outer-id or inner-id identifiers if they are visible +in the original for form, so beware of depending on such +identifiers in post-guard and loop-arg.

The actual loop binding and call has additional loop +arguments to support iterations in parallel with the :do-in +form, and the other pieces are similarly accompanied by pieces from +parallel iterations.

For an example of :do-in, see define-sequence-syntax.

procedure

(for-clause-syntax-protect stx)  syntax?

  stx : syntax?
Provided for-syntax: Like syntax-protect, just +returns its argument.

Changed in version 8.2.0.4 of package base: Changed to just return stx instead +of returning “armed” syntax.

syntax

(define-splicing-for-clause-syntax id proc-expr)

Binds id for reference via a #:splicing clause in a +for form. The proc-expr expression is evaluated in +phase level 1, and it must produce a procedure that accepts a +syntax object and returns a syntax object.

The procedure’s input is a syntax object that appears after +#:splicing. The result syntax object must be a parenthesized +sequence of forms, and the forms are spliced in place of the +#:splicing clause in the enclosing for form.

Examples:
> (define-splicing-for-clause-syntax cross3
    (lambda (stx)
      (syntax-case stx ()
        [(_ n m) #'([n (in-range 3)]
                    #:when #t
                    [m (in-range 3)])])))
> (for (#:splice (cross3 n m))
    (println (list n m)))

'(0 0)

'(0 1)

'(0 2)

'(1 0)

'(1 1)

'(1 2)

'(2 0)

'(2 1)

'(2 2)

Added in version 8.4.0.3 of package base.

3.18.3 Do Loops

syntax

(do ([id init-expr step-expr-maybe] ...)
    (stop?-expr finish-expr ...)
  expr ...)
 
step-expr-maybe = 
  | step-expr
Iteratively evaluates the exprs for as long as +stop?-expr returns #f.

To initialize the loop, the init-exprs are evaluated in order +and bound to the corresponding ids. The ids are +bound in all expressions within the form other than the +init-exprs.

After the ids have been bound, the stop?-expr is +evaluated. If it produces #f, each expr is evaluated +for its side-effect. The ids are then effectively updated +with the values of the step-exprs, where the default +step-expr for id is just id; more +precisely, iteration continues with fresh locations for the +ids that are initialized with the values of the corresponding +step-exprs.

When stop?-expr produces a true value, then the +finish-exprs are evaluated in order, and the last one is +evaluated in tail position to produce the overall value for the +do form. If no finish-expr is provided, the value of +the do form is #<void>.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/function-contracts.html b/clones/docs.racket-lang.org/reference/function-contracts.html new file mode 100644 index 00000000..f6b262fe --- /dev/null +++ b/clones/docs.racket-lang.org/reference/function-contracts.html @@ -0,0 +1,192 @@ + +8.2 Function Contracts

8.2 Function Contracts

A function contract wraps a procedure to delay +checks for its arguments and results. There are three +primary function contract combinators that have increasing +amounts of expressiveness and increasing additional +overheads. The first -> is the cheapest. It +generates wrapper functions that can call the original +function directly. Contracts built with ->* require +packaging up arguments as lists in the wrapper function and +then using either keyword-apply or +apply. Finally, ->i +is the most expensive (along with ->d), +because it requires delaying the evaluation of the contract +expressions for the domain and range until the function +itself is called or returns.

The case-> contract is a specialized contract, +designed to match case-lambda and +unconstrained-domain-> allows range checking +without requiring that the domain have any particular shape +(see below for an example use).

syntax

(-> dom ... range)

(-> dom ... ellipsis dom-expr ... range)
 
dom = dom-expr
  | keyword dom-expr
     
range = range-expr
  | (values range-expr ...)
  | any
     
ellipsis = ...
Produces a contract for a function that accepts the argument +specified by the dom-expr contracts and returns +either a fixed number of +results or completely unspecified results (the latter when +any is specified).

Each dom-expr is a contract on an argument to a +function, and each range-expr is a contract on a +result of the function.

If the domain contain ... +then the function accepts as many arguments as the rest of +the contracts in the domain portion specify, as well as +arbitrarily many more that match the contract just before the +.... Otherwise, the contract accepts exactly the +argument specified.

Using a -> between two whitespace-delimited +.s is the same as putting the -> right +after the enclosing opening parenthesis. See +Lists and Racket Syntax or Reading Pairs and Lists for more +information.

For example, +
produces a contract on functions of two arguments. The first argument +must be an integer, and the second argument must be a boolean. The +function must produce an integer.

Examples:
> (define/contract (maybe-invert i b)
    (-> integer? boolean? integer?)
    (if b (- i) i))
> (maybe-invert 1 #t)

-1

> (maybe-invert #f 1)

maybe-invert: contract violation

  expected: integer?

  given: #f

  in: the 1st argument of

      (-> integer? boolean? integer?)

  contract from: (function maybe-invert)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

A domain specification may include a keyword. If so, the function must +accept corresponding (mandatory) keyword arguments, and the values for +the keyword arguments must match the corresponding contracts. For +example: +

(integer? #:invert? boolean? . -> . integer?)

is a contract on a function that accepts a by-position argument that +is an integer and an #:invert? argument that is a boolean.

Examples:
> (define/contract (maybe-invert i #:invert? b)
    (-> integer? #:invert? boolean? integer?)
    (if b (- i) i))
> (maybe-invert 1 #:invert? #t)

-1

> (maybe-invert 1 #f)

maybe-invert: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 1 plus an argument with keyword #:invert?

  given: 2

  arguments...:

   1

   #f

As an example that uses an ..., this contract: +
on a function insists that the first and last arguments to +the function must be integers (and there must be at least +two arguments) and any other arguments must be strings.

Examples:
> (define/contract (string-length/between? lower-bound s1 . more-args)
    (-> integer? string? ... integer? boolean?)
  
    (define all-but-first-arg-backwards (reverse (cons s1 more-args)))
    (define upper-bound (first all-but-first-arg-backwards))
    (define strings (rest all-but-first-arg-backwards))
    (define strings-length
      (for/sum ([str (in-list strings)])
        (string-length str)))
    (<= lower-bound strings-length upper-bound))
> (string-length/between? 4 "farmer" "john" 40)

#t

> (string-length/between? 4 "farmer" 'john 40)

string-length/between?: contract violation

  expected: string?

  given: 'john

  in: the repeated argument of

      (-> integer? string? ... integer? boolean?)

  contract from:

      (function string-length/between?)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

> (string-length/between? 4 "farmer" "john" "fourty")

string-length/between?: contract violation

  expected: integer?

  given: "fourty"

  in: the last argument of

      (-> integer? string? ... integer? boolean?)

  contract from:

      (function string-length/between?)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

If any is used as the last sub-form for ->, no +contract checking is performed on the result of the function, and +thus any number of values is legal (even different numbers on different +invocations of the function).

Examples:
> (define/contract (multiple-xs n x)
    (-> natural? any/c any)
    (apply
     values
     (for/list ([_ (in-range n)])
       n)))
> (multiple-xs 4 "four")

4

4

4

4

If (values range-expr ...) is used as the last sub-form of +->, the function must produce a result for each contract, and +each value must match its respective contract.

Examples:
> (define/contract (multiple-xs n x)
    (-> natural? any/c (values any/c any/c any/c))
    (apply
     values
     (for/list ([_ (in-range n)])
       n)))
> (multiple-xs 3 "three")

3

3

3

> (multiple-xs 4 "four")

multiple-xs: broke its own contract;

 expected 3 values, returned 4 values

  in: the range of

      (->

       natural?

       any/c

       (values any/c any/c any/c))

  contract from: (function multiple-xs)

  blaming: (function multiple-xs)

   (assuming the contract is correct)

  at: eval:2:0

Changed in version 6.4.0.5 of package base: Added support for ellipses

syntax

(->* (mandatory-dom ...) optional-doms rest pre range post)

 
mandatory-dom = dom-expr
  | keyword dom-expr
     
optional-doms = 
  | (optional-dom ...)
     
optional-dom = dom-expr
  | keyword dom-expr
     
rest = 
  | #:rest rest-expr
     
pre = 
  | #:pre pre-cond-expr
  | #:pre/desc pre-cond-expr
     
range = range-expr
  | (values range-expr ...)
  | any
     
post = 
  | #:post post-cond-expr
  | #:post/desc post-cond-expr
The ->* contract combinator produces contracts for functions +that accept optional arguments (either keyword or positional) and/or +arbitrarily many arguments. The first clause of a ->* +contract describes the mandatory arguments, and is similar to the +argument description of a -> contract. The second clause +describes the optional arguments. The range of description can either +be any or a sequence of contracts, indicating that the +function must return multiple values.

If present, the +rest-expr contract governs the arguments in the rest +parameter. Note that the rest-expr contract governs only +the arguments in the rest parameter, not those in mandatory arguments. +For example, this contract: +

(->* () #:rest (cons/c integer? (listof integer?)) any)

does not match the function +

(λ (x . rest) x)

because the contract insists that the function accept zero arguments +(because there are no mandatory arguments listed in the contract). The +->* contract does not know that the contract on the rest argument is +going to end up disallowing empty argument lists.

The pre-cond-expr and post-cond-expr +expressions are checked as the function is called and returns, +respectively, and allow checking of the environment without an +explicit connection to an argument (or a result). If the #:pre +or #:post keywords are used, then a #f result is +treated as a failure and any other result is treated as success. +If the #:pre/desc or #:post/desc keyword is used, +the result of the expression must be either a boolean, a string, or a +list of strings, where #t means success and any of the other +results mean failure. If the result is a string or a list of strings, +the strings are expected to have at exactly one space after each +newline and multiple are used as lines in the error message; the contract +itself adds single space of indentation to each of the strings in that case. +The formatting requirements are not checked but they +match the recommendations in Error Message Conventions.

As an example, the contract +

(->* () (boolean? #:x integer?) #:rest (listof symbol?) symbol?)

matches functions that optionally accept a boolean, an +integer keyword argument #:x and arbitrarily more +symbols, and that return a symbol.

syntax

(->i maybe-chaperone
     (mandatory-dependent-dom ...)
     dependent-rest
     pre-condition
     dependent-range
     post-condition)
(->i maybe-chaperone
     (mandatory-dependent-dom ...)
     (optional-dependent-dom ...)
     dependent-rest
     pre-condition
     dependent-range
     post-condition)
 
maybe-chaperone = #:chaperone
  | 
     
mandatory-dependent-dom = id+ctc
  | keyword id+ctc
     
optional-dependent-dom = id+ctc
  | keyword id+ctc
     
dependent-rest = 
  | #:rest id+ctc
     
pre-condition = 
  | 
#:pre (id ...)
boolean-expr pre-condition
  | 
#:pre/desc (id ...)
expr pre-condition
  | 
#:pre/name (id ...)
string boolean-expr pre-condition
     
dependent-range = any
  | id+ctc
  | un+ctc
  | (values id+ctc ...)
  | (values un+ctc ...)
     
post-condition = 
  | 
#:post (id ...)
boolean-expr post-condition
  | 
#:post/desc (id ...)
expr post-condition
  | 
#:post/name (id ...)
string boolean-expr post-condition
     
id+ctc = [id contract-expr]
  | [id (id ...) contract-expr]
     
un+ctc = [_ contract-expr]
  | [_ (id ...) contract-expr]
The ->i contract combinator differs from the ->* +combinator in that each argument and result is named and these names can +be used in the subcontracts and in the pre-/post-condition clauses. +In other words, ->i expresses dependencies among arguments and results.

The optional first keyword argument to ->i indicates if the result +contract will be a chaperone. If it is #:chaperone, all of the contract for the arguments +and results must be chaperone contracts and the result of ->i will be +a chaperone contract. If it is not present, then the result +contract will not be a chaperone contract.

The first sub-form of a ->i contract covers the mandatory and the +second sub-form covers the optional arguments. Following that is an optional +rest-args contract, and an optional pre-condition. The pre-condition is +introduced with the #:pre keyword followed by the list of names on +which it depends. If the #:pre/name keyword is used, the string +supplied is used as part of the error message; similarly with #:post/name. +If #:pre/desc or #:post/desc is used, the the result of +the expression is treated the same way as ->*.

The dependent-range non-terminal specifies the possible result +contracts. If it is any, then any value is allowed. Otherwise, the +result contract pairs a name and a contract or a multiple values return +with names and contracts. In the last two cases, the range contract may be +optionally followed by a post-condition; the post-condition expression is +not allowed if the range contract is any. Like the pre-condition, +the post-condition must specify the variables on which it depends.

Consider this sample contract: +
(->i ([x number?]
      [y (x) (>=/c x)])
     [result (x y) (and/c number? (>=/c (+ x y)))])
It specifies a function of two arguments, both numbers. The contract on the +second argument (y) demands that it is greater than the first +argument. The result contract promises a number that is greater than the +sum of the two arguments. While the dependency specification for y +signals that the argument contract depends on the value of the first +argument, the dependency sequence for result indicates that the +contract depends on both argument values. In general, an +empty sequence is (nearly) equivalent to not adding +a sequence at all except that the former is more expensive than the latter. +Since the contract for x does not depend on anything else, it does +not come with any dependency sequence, not even ().

This example is like the previous one, except the x and y +arguments are now optional keyword arguments, instead of mandatory, by-position +arguments: +
(->i ()
     (#:x [x number?]
      #:y [y (x) (>=/c x)])
     [result (x y)
      (and/c number?
             (if (and (number? x) (number? y))
                 (>=/c (+ x y))
                 any/c))])
The conditional in the range that tests x and y +is necessary to cover the situation where x or y +are not supplied by the calling context (meaning they might be bound +to the-unsupplied-arg).

The contract expressions are not always evaluated in +order. First, if there is no dependency for a given contract expression, +the contract expression is evaluated at the time that the ->i +expression is evaluated rather than the time when the function is called or +returns. These dependency-free contract expressions are evaluated in the +order in which they are listed. +Second, the dependent contract sub-expressions are evaluated when the +contracted function is called or returns in some order that satisfies the +dependencies. That is, if a contract for an argument depends on the value +of some other contract, the former is evaluated first (so that the +argument, with its contract checked, is available for the other). When +there is no dependency between two arguments (or the result and an +argument), then the contract that appears earlier in the source text is +evaluated first.

If all of the identifier positions of a range contract with + a dependency are _s (underscores), then the range + contract expressions are evaluated when the function is + called instead of when it returns. Otherwise, dependent + range expressions are evaluated when the function returns.

If there are optional arguments that are not supplied, then + the corresponding variables will be bound to a special value + called the-unsupplied-arg value. For example, in + this contract: +
(->i ([x (y) (if (unsupplied-arg? y)
                 real?
                 (>=/c y))])
     ([y real?])
     any)
the contract on x depends on y, but + y might not be supplied at the call site. In that + case, the value of y in the contract on + x is the-unsupplied-arg + and the ->i contract must check for it and tailor + the contract on x to + account for y not being supplied.

When the contract expressions for unsupplied arguments are dependent, +and the argument is not supplied at the call site, the contract +expressions are not evaluated at all. For example, in this contract, +y’s contract expression is evaluated only when y +is supplied: +
(->i ()
     ([x real?]
      [y (x) (>=/c x)])
     any)
In contrast, x’s expression is always evaluated (indeed, +it is evaluated when the ->i expression is evaluated because +it does not have any dependencies).

syntax

(->d (mandatory-dependent-dom ...)
     dependent-rest
     pre-condition
     dependent-range
     post-condition)
(->d (mandatory-dependent-dom ...)
     (optional-dependent-dom ...)
     dependent-rest
     pre-condition
     dependent-range
     post-condition)
 
mandatory-dependent-dom = [id dom-expr]
  | keyword [id dom-expr]
     
optional-dependent-dom = [id dom-expr]
  | keyword [id dom-expr]
     
dependent-rest = 
  | #:rest id rest-expr
     
pre-condition = 
  | #:pre boolean-expr
  | #:pre-cond boolean-expr
     
dependent-range = any
  | [_ range-expr]
  | (values [_ range-expr] ...)
  | [id range-expr]
  | (values [id range-expr] ...)
     
post-condition = 
  | #:post-cond boolean-expr
This contract is here for backwards compatibility; any new code should +use ->i instead.

This contract is similar to ->i, but is “lax”, meaning +that it does not enforce contracts internally. For example, using +this contract +
(->d ([f (-> integer? integer?)])
     #:pre
     (zero? (f #f))
     any)
will allow f to be called with #f, trigger whatever bad +behavior the author of f was trying to prohibit by insisting that +f’s contract accept only integers.

The #:pre-cond and #:post-cond keywords are aliases for +#:pre and #:post and are provided for backwards compatibility.

syntax

(case-> (-> dom-expr ... rest range) ...)

 
rest = 
  | #:rest rest-expr
     
range = range-expr
  | (values range-expr ...)
  | any
This contract form is designed to match +case-lambda. Each argument to case-> is a +contract that governs a clause in the +case-lambda. If the #:rest keyword is +present, the corresponding clause must accept an arbitrary +number of arguments. The range specification is +just like that for -> and ->*.

For example, this contract matches a function with two +cases, one that accepts an integer, returning void, and one +that accepts no arguments and returns an integer. +
(case-> (-> integer? void?)
        (-> integer?))
Such a contract could be used to guard a function that controls +access to a single shared integer.

procedure

(dynamic->* 
  [#:mandatory-domain-contracts mandatory-domain-contracts 
  #:optional-domain-contracts optional-domain-contracts 
  #:mandatory-keywords mandatory-keywords 
  #:mandatory-keyword-contracts mandatory-keyword-contracts 
  #:optional-keywords optional-keywords 
  #:optional-keyword-contracts optional-keyword-contracts 
  #:rest-contract rest-contract] 
  #:range-contracts range-contracts) 
  contract?
  mandatory-domain-contracts : (listof contract?) = '()
  optional-domain-contracts : (listof contract?) = '()
  mandatory-keywords : (listof keyword?) = '()
  mandatory-keyword-contracts : (listof contract?) = '()
  optional-keywords : (listof keyword?) = '()
  optional-keyword-contracts : (listof contract?) = '()
  rest-contract : (or/c #f contract?) = #f
  range-contracts : (or/c #f (listof contract?))
Like ->*, except the number of arguments and results can be computed +at runtime, instead of being fixed at compile-time. Passing #f as the +#:range-contracts argument produces a contract like one where any +is used with -> or ->*.

For many uses, dynamic->*’s result is slower than ->* (or ->), +but for some it has comparable speed. The name of the contract returned by +dynamic->* uses the -> or ->* syntax.

syntax

(unconstrained-domain-> range-expr ...)

Constructs a contract that accepts a function, but makes no constraint +on the function’s domain. The range-exprs determine the number +of results and the contract for each result.

Generally, this contract must be combined with another contract to +ensure that the domain is actually known to be able to safely call the +function itself.

For example, the contract

(provide
 (contract-out
  [f (->d ([size natural-number/c]
           [proc (and/c (unconstrained-domain-> number?)
                        (lambda (p)
                          (procedure-arity-includes? p size)))])
          ()
          [_ number?])]))

says that the function f accepts a natural number +and a function. The domain of the function that f +accepts must include a case for size arguments, +meaning that f can safely supply size +arguments to its input.

For example, the following is a definition of f that cannot +be blamed using the above contract:

(define (f i g)
  (apply g (build-list i add1)))

Use this contract to indicate that some function +is a predicate. It is semantically equivalent to +(-> any/c boolean?).

This contract also includes an optimization so that functions returning +#t from struct-predicate-procedure? are just returned directly, without +being wrapped. This contract is used by provide/contract’s +struct sub-form so that struct predicates end up not being wrapped.

Used by ->i (and ->d) to bind +optional arguments that are not supplied by a call site.

procedure

(unsupplied-arg? v)  boolean?

  v : any/c
A predicate to determine whether v is +the-unsupplied-arg.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/futures.html b/clones/docs.racket-lang.org/reference/futures.html new file mode 100644 index 00000000..0e493818 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/futures.html @@ -0,0 +1,140 @@ + +11.4 Futures

11.4 Futures

+Parallelism with Futures in The Racket Guide introduces futures.

 (require racket/future) package: base
The bindings documented in this section are provided by the racket/future and racket libraries, but not racket/base.

Currently, parallel support for future is enabled +by default for Windows, Linux x86/x86_64, and Mac OS x86/x86_64. To +enable support for other platforms, use --enable-futures with +configure when building Racket.

The future and touch functions from +racket/future provide access to parallelism as supported +by the hardware and operating system. In contrast to thread, +which provides concurrency for arbitrary computations without +parallelism, future provides parallelism for limited +computations. A future executes its work in parallel (assuming that +support for parallelism is available) until it detects an attempt to +perform an operation that is too complex for the system to run safely in +parallel. Similarly, work in a future is suspended if it depends in some +way on the current continuation, such as raising an exception. A +suspended computation for a future is resumed when touch is +applied to the future.

“Safe” parallel execution of a future means that all operations +provided by the system must be able to enforce contracts and produce +results as documented. “Safe” does not preclude concurrent access to +mutable data that is visible in the program. For example, a computation +in a future might use set! to modify a shared variable, in +which case concurrent assignment to the variable can be visible in other +futures and threads. Furthermore, guarantees about the visibility of +effects and ordering are determined by the operating system and +hardware—which rarely support, for example, the guarantee of +sequential consistency that is provided for thread-based +concurrency; see also Machine Memory Order. At the same time, operations +that seem obviously safe may +have a complex enough implementation internally that they cannot run in +parallel. See also Parallelism with Futures in The Racket Guide.

A future never runs in parallel if all of the custodians that +allow its creating thread to run are shut down. Such futures can +execute through a call to touch, however.

11.4.1 Creating and Touching Futures

procedure

(future thunk)  future?

  thunk : (-> any)

procedure

(touch f)  any

  f : future?
The future procedure returns a future value that encapsulates +thunk. The touch function forces the evaluation of +the thunk inside the given future, returning the values +produced by thunk. After touch forces the evaluation +of a thunk, the resulting values are retained by the future +in place of thunk, and additional touches of the +future return those values.

Between a call to future and touch for a given +future, the given thunk may run speculatively in parallel to +other computations, as described above.

Example:
> (let ([f (future (lambda () (+ 1 2)))])
    (list (+ 3 4) (touch f)))

'(7 3)

procedure

(futures-enabled?)  boolean?

Returns whether parallel support for futures is enabled +in the current Racket configuration.

procedure

(current-future)  (or/c #f future?)

Returns the descriptor of the future whose thunk execution is the +current continuation; that is, if a future descriptor f is returned, +(touch f) will produce the result of the current continuation. +If a future thunk itself uses touch, +future-thunk executions can be nested, in which case the descriptor of +the most immediately executing future is returned. If the current +continuation does not return to the touch of any future, the result is +#f.

procedure

(future? v)  boolean?

  v : any/c
Returns #t if v is a future value, #f +otherwise.

procedure

(would-be-future thunk)  future?

  thunk : (-> any)
Returns a future that never runs in parallel, but that consistently +logs all potentially “unsafe” operations during the execution of +the future’s thunk (i.e., operations that interfere with parallel +execution).

With a normal future, certain circumstances might prevent the logging +of unsafe operations. For example, when executed with debug-level logging,

(touch (future (lambda ()
                 (printf "hello1")
                 (printf "hello2")
                 (printf "hello3"))))

might log three messages, one for each printf +invocation. However, if the touch is performed before the future +has a chance to start running in parallel, the future thunk evaluates +in the same manner as any ordinary thunk, and no unsafe operations +are logged. Replacing future with would-be-future +ensures the logging of all three calls to printf.

Returns the number of parallel computation units (e.g., processors or +cores) that are available on the current machine.

This is the same binding as available from racket/place.

syntax

(for/async (for-clause ...) body ...+)

syntax

(for*/async (for-clause ...) body ...+)

Like for and for*, but each iteration of the +body is executed in a separate future, and +the futures may be touched in any order.

11.4.2 Future Semaphores

procedure

(make-fsemaphore init)  fsemaphore?

  init : exact-nonnegative-integer?
Creates and returns a new future semaphore with the +counter initially set to init.

A future semaphore is similar to a plain semaphore, but +future-semaphore operations can be performed safely in parallel (to synchronize +parallel computations). In contrast, operations on plain semaphores +are not safe to perform in parallel, and they therefore prevent +a computation from continuing in parallel.

Beware of trying to use an fsemaphore to implement a lock. A future +may run concurrently and in parallel to other futures, but a future +that is not demanded by a Racket thread can be suspended at any +time—such as just after it takes a lock and before it releases the +lock. If you must share mutable data among futures, lock-free data +structures are generally a better fit.

procedure

(fsemaphore? v)  boolean?

  v : any/c
Returns #t if v is an future semaphore +value, #f otherwise.

procedure

(fsemaphore-post fsema)  void?

  fsema : fsemaphore?
Increments the future semaphore’s internal counter and +returns #<void>.

procedure

(fsemaphore-wait fsema)  void?

  fsema : fsemaphore?
Blocks until the internal counter for fsema is non-zero. +When the counter is non-zero, it is decremented and +fsemaphore-wait returns #<void>.

procedure

(fsemaphore-try-wait? fsema)  boolean?

  fsema : fsemaphore?
Like fsemaphore-wait, but fsemaphore-try-wait? +never blocks execution. If fsema’s internal counter is zero, +fsemaphore-try-wait? returns #f immediately without +decrementing the counter. If fsema’s counter is positive, it +is decremented and #t is returned.

procedure

(fsemaphore-count fsema)  exact-nonnegative-integer?

  fsema : fsemaphore?
Returns fsema’s current internal counter value.

11.4.3 Future Performance Logging

Racket traces use logging (see Logging) extensively to +report information about how futures are evaluated. Logging output is +useful for debugging the performance of programs that use futures.

Though textual log output can be viewed directly (or retrieved in +code via trace-futures), it is much +easier to use the graphical profiler tool provided by +future-visualizer.

Future events are logged with the topic 'future. +In addition to its string message, each event logged for a future has +a data value that is an instance of a future-event +prefab structure:

(struct future-event (future-id proc-id action time prim-name user-data)
  #:prefab)

The future-id field is an exact integer that identifies a +future, or it is #f when action is +'missing. The future-id field is particularly useful +for correlating logged events.

The proc-id fields is an exact, non-negative integer that +identifies a parallel process. Process 0 is the main Racket process, +where all expressions other than future thunks evaluate.

The time field is an inexact number that represents time in +the same way as current-inexact-milliseconds.

The action field is a symbol:

  • 'create: a future was created.

  • 'complete: a future’s thunk evaluated successfully, so +that touch will produce a value for the future +immediately.

  • 'start-work and 'end-work: a particular +process started and ended working on a particular future.

  • 'start-0-work: like 'start-work, but for a +future thunk that for some structural reason could not be +started in a process other than 0 (e.g., the thunk requires too +much local storage to start).

  • 'start-overflow-work: like 'start-work, where +the future thunk’s work was previously stopped due to an +internal stack overflow.

  • 'sync: blocking (processes other than 0) or initiation +of handing (process 0) for an “unsafe” operation in a future +thunk’s evaluation; the operation must run in process 0.

  • 'block: like 'sync, but for a part of +evaluation that must be delayed until the future is +touched, because the evaluation may depend on the +current continuation.

  • 'touch (never in process 0): like 'sync or +'block, but for a touch operation within a +future thunk.

  • 'overflow (never in process 0): like 'sync or +'block, but for the case that a process encountered an +internal stack overflow while evaluating a future thunk.

  • 'result or 'abort: waiting or handling for +'sync, 'block, or 'touch ended with +a value or an error, respectively.

  • 'suspend (never in process 0): a process blocked by +'sync, 'block, or 'touch abandoned +evaluation of a future; some other process may pick up the +future later.

  • 'touch-pause and 'touch-resume (in process 0, +only): waiting in touch for a future whose thunk is +being evaluated in another process.

  • 'missing: one or more events for the process were lost +due to internal buffer limits before they could be reported, +and the time-id field reports an upper limit on the time +of the missing events; this kind of event is rare.

Assuming no 'missing events, then 'start-work, +'start-0-work, 'start-overflow-work is always paired with 'end-work; +'sync, 'block, and 'touch are always paired +with 'result, 'abort, or 'suspend; and +'touch-pause is always paired with 'touch-resume.

In process 0, some event pairs can be nested within other event pairs: +'sync, 'block, or 'touch with +'result or 'abort; 'touch-pause with +'touch-resume; and 'start-work with 'end-work.

A 'block in process 0 is generated when an unsafe operation +is handled. This type of event will contain a symbol in the +unsafe-op-name field that is the name of the operation. In all +other cases, this field contains #f.

The prim-name field will always be #f unless the event occurred +on process 0 and its action is either 'block or 'sync. If +these conditions are met, prim-name will contain the name +of the Racket primitive which required the future to synchronize with the runtime +thread (represented as a symbol).

The user-data field may take on a number of different +values depending on both the action and prim-name fields:

  • 'touch on process 0: contains the integer ID of the future + being touched.

  • 'sync and prim-name is '|allocate memory|: + The size (in bytes) of the requested allocation.

  • 'sync and prim-name is 'jit_on_demand: + The runtime thread is performing a JIT compilation on behalf of the + future future-id. The field contains the name of the function + being JIT compiled (as a symbol).

  • 'create: A new future was created. The field contains the integer ID + of the newly created future.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/garbagecollection.html b/clones/docs.racket-lang.org/reference/garbagecollection.html new file mode 100644 index 00000000..a797522a --- /dev/null +++ b/clones/docs.racket-lang.org/reference/garbagecollection.html @@ -0,0 +1,101 @@ + +16.4 Garbage Collection

16.4 Garbage Collection

Set the PLTDISABLEGC environment variable (to any +value) before Racket starts to disable garbage collection. Set +the PLT_INCREMENTAL_GC environment variable +to a value that starts with 1, y, or Y to +request incremental mode at all times, but calling +(collect-garbage 'incremental) in a program with a periodic +task is generally a better mechanism for requesting incremental mode. +Set the PLT_INCREMENTAL_GC environment variable +to a value that starts with 0, n, or N to +disable incremental-mode requests.

Each garbage collection logs a message (see Logging) at the +'debug level with topic 'GC. In the CS and 3m +implementations of Racket, “major” collections are also logged at the +'debug level with the topic 'GC:major. In the CS +and 3m implementations of Racket, the data portion of the message is an +instance of a gc-info prefab structure type +with 10 fields as follows, but future versions of Racket may use a +gc-info prefab structure with additional fields:

(struct gc-info (mode pre-amount pre-admin-amount code-amount
                      post-amount post-admin-amount
                      start-process-time end-process-time
                      start-time end-time)
  #:prefab)
  • The mode field is a symbol 'major, +'minor, or 'incremental; 'major +indicates a collection that inspects all memory, +'minor indicates collection that mostly inspects just +recent allocations, and 'incremental indicates a minor +collection that performs extra work toward the next major +collection.

    Changed in version 6.3.0.7 of package base: Changed first field from a +boolean (#t for +'major, #f +for 'minor) to a +mode symbol.

  • The pre-amount field reports place-local memory use +(i.e., not counting the memory use of child places) in bytes at +the time that the garbage collection started. Additional +bytes registered via make-phantom-bytes are included.

  • The pre-admin-amount is a larger number that includes +memory use for the garbage collector’s overhead, such as space +on memory pages that are mapped but not currently used.

  • The code-amount field reports additional memory use +for generated native code (which is the same just before and +after a garbage collection, since it is released via +finalization).

  • The post-amount and post-admin-amount fields +correspond to pre-amount and +pre-admin-amount, but after garbage collection. In +typical configurations, the difference between +post-amount and pre-amount contributes to +post-admin-amount, since reclaimed pages tend to stay +in reserve with the expectation that they’ll be needed again +(but the pages are released if multiple collections pass +without need for the pages).

  • The start-process-time and end-process-time +fields report processor time (in the sense of +current-process-milliseconds) at the start and end of +garbage collection. The difference between the times is the +processor time consumed by collection.

  • The start-time and end-time fields report +real time (in the sense of +current-inexact-milliseconds) at the start and end of +garbage collection. The difference between the times is the +real time consumed by garbage collection.

The format of the logged message’s text is subject to change. +Currently, after a prefix that indicates the place and +collection mode, the text has the format

used(admin)[code]; free reclaimed(adjust) elapsed @ timestamp

used

 

Collectable memory in use just prior to garbage collection

admin

 

Additional memory used as to manage collectable memory

code

 

Additional memory used for generated machine code

reclaimed

 

Collectable memory reclaimed by garbage collection

adjust

 

Negation of change to administrative memory minus reclaimed

elapsed

 

Processor time used to perform garbage collection

timestamp

 

Processor time since startup of garbage collection’s start

Changed in version 6.3.0.7 of package base: Added PLT_INCREMENTAL_GC.
Changed in version 7.6.0.9: Added major-collection logging for the topic 'GC:major.

procedure

(collect-garbage [request])  void?

  request : (or/c 'major 'minor 'incremental) = 'major
Requests an immediate garbage collection or requests a +garbage-collection mode, depending on request:

  • 'major Forces a “major” collection, which +inspects all memory. Some effectively unreachable data may +remain uncollected, because the collector cannot prove that it +is unreachable.

    This mode of collect-garbage procedure provides some +control over the timing of collections, but garbage will +obviously be collected even if this procedure is never +called—unless garbage collection is disabled by setting +PLTDISABLEGC.

  • 'minor Requests a “minor” collection, which +mostly inspects only recent allocations. If minor collection is +not supported (e.g., when (system-type 'gc) returns +'cgc) or if the next collection must be a major +collection, no collection is performed. More generally, minor collections +triggered by (collect-garbage 'minor) do not cause +major collections any sooner than they would occur otherwise.

  • 'incremental Does not request an immediate +collection, but requests extra effort going forward to avoid +major collections, even if it requires more work per minor +collection to incrementally perform the work of a major +collection. This incremental-mode request expires at the next +major collection.

    The intent of incremental mode is to significantly reduce pause +times due to major collections, but incremental mode may imply +longer minor-collection times and higher memory use. Currently, +incremental mode is only meaningful for CS and 3m +Racket implementations; it has no effect in +other Racket implementations.

    If the PLT_INCREMENTAL_GC environment variable’s value +starts with 0, n, or N on +start-up, then incremental-mode requests are ignored.

Changed in version 6.3 of package base: Added the request argument.
Changed in version 6.3.0.2: Added 'incremental mode.
Changed in version 7.7.0.4: Added 'incremental effect +for Racket CS.

procedure

(current-memory-use [mode])  exact-nonnegative-integer?

  mode : (or/c #f 'cumulative custodian?) = #f
Returns information about memory use:

  • If mode is #f (the default), the result is an +estimate of the number of bytes reachable from any custodian.

  • If mode is 'cumulative, returns an estimate +of the total number of bytes allocated since start up, +including bytes that have since been reclaimed by garbage +collection.

  • If mode is a custodian, returns an estimate of the +number of bytes of memory occupied by reachable data from +mode. This estimate is calculated by the last garbage +collection, and can be 0 if none occurred (or if none occurred +since the given custodian was created). The +current-memory-use function does not perform +a collection by itself; doing one before the call will +generally decrease the result (or increase it from 0 if no +collections happened yet).

    When Racket is compiled without support for memory accounting, +the estimate is the same as when mode is #f +(i.e., all memory) for any individual custodian. See also +custodian-memory-accounting-available?.

See also vector-set-performance-stats!.

Changed in version 6.6.0.3 of package base: Added 'cumulative mode.

procedure

(dump-memory-stats v ...)  any

  v : any/c
Dumps information about memory usage to the low-level error port + or console.

Various combinations of v arguments can control the +information in a dump. The information that is available depends on +your Racket build; check the end of a dump from a particular build to +see if it offers additional information; otherwise, all vs are +ignored.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/generic-numbers.html b/clones/docs.racket-lang.org/reference/generic-numbers.html new file mode 100644 index 00000000..7d2207f9 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/generic-numbers.html @@ -0,0 +1,273 @@ + +4.3.2 Generic Numerics
4.3.2 Generic Numerics

Most Racket numeric operations work on any kind of number.

4.3.2.1 Arithmetic

procedure

(+ z ...)  number?

  z : number?
Returns the sum of the zs, adding pairwise from left to + right. If no arguments are provided, the result is 0.

Examples:
> (+ 1 2)

3

> (+ 1.0 2+3i 5)

8.0+3.0i

> (+)

0

procedure

(- z)  number?

  z : number?
(- z w ...+)  number?
  z : number?
  w : number?
When no ws are supplied, returns (- 0 z). + Otherwise, returns the subtraction of the ws from z + working pairwise from left to right.

Examples:
> (- 5 3.0)

2.0

> (- 1)

-1

> (- 2+7i 1 3)

-2+7i

procedure

(* z ...)  number?

  z : number?
Returns the product of the zs, multiplying pairwise from left + to right. If no arguments are provided, the result is + 1. Multiplying any number by exact 0 produces exact + 0.

Examples:
> (* 2 3)

6

> (* 8.0 9)

72.0

> (* 1+2i 3+4i)

-5+10i

procedure

(/ z)  number?

  z : number?
(/ z w ...+)  number?
  z : number?
  w : number?
When no ws are supplied, returns (/ 1 z). + Otherwise, returns the division of z by the ws working + pairwise from left to right.

If z is exact 0 and no w is exact + 0, then the result is exact 0. If any w is + exact 0, the exn:fail:contract:divide-by-zero exception is raised.

Examples:
> (/ 3 4)

3/4

> (/ 81 3 3)

9

> (/ 10.0)

0.1

> (/ 1+2i 3+4i)

11/25+2/25i

procedure

(quotient n m)  integer?

  n : integer?
  m : integer?
Returns (truncate (/ n m)).

Examples:
> (quotient 10 3)

3

> (quotient -10.0 3)

-3.0

> (quotient +inf.0 3)

quotient: contract violation

  expected: integer?

  given: +inf.0

procedure

(remainder n m)  integer?

  n : integer?
  m : integer?
Returns q with the same sign as n such that

  • (abs q) is between 0 (inclusive) and (abs m) (exclusive), and

  • (+ q (* m (quotient n m))) equals n.

If m is exact 0, the + exn:fail:contract:divide-by-zero exception is raised.

Examples:
> (remainder 10 3)

1

> (remainder -10.0 3)

-1.0

> (remainder 10.0 -3)

1.0

> (remainder -10 -3)

-1

> (remainder +inf.0 3)

remainder: contract violation

  expected: integer?

  given: +inf.0

procedure

(quotient/remainder n m)  
integer? integer?
  n : integer?
  m : integer?
Returns (values (quotient n m) (remainder n m)), but the + combination may be computed more efficiently than separate calls to + quotient and remainder.

Example:
> (quotient/remainder 10 3)

3

1

procedure

(modulo n m)  integer?

  n : integer?
  m : integer?
Returns q with the same sign as m where

  • (abs q) is between 0 (inclusive) and (abs m) (exclusive), and

  • the difference between q and (- n (* m (quotient n m))) is a multiple of m.

If m is exact 0, the + exn:fail:contract:divide-by-zero exception is raised.

Examples:
> (modulo 10 3)

1

> (modulo -10.0 3)

2.0

> (modulo 10.0 -3)

-2.0

> (modulo -10 -3)

-1

> (modulo +inf.0 3)

modulo: contract violation

  expected: integer?

  given: +inf.0

procedure

(add1 z)  number?

  z : number?
Returns (+ z 1).

procedure

(sub1 z)  number?

  z : number?
Returns (- z 1).

procedure

(abs x)  number?

  x : real?
Returns the absolute value of + x.

Examples:
> (abs 1.0)

1.0

> (abs -1)

1

procedure

(max x ...+)  real?

  x : real?
Returns the largest of the xs, or +nan.0 if any + x is +nan.0. If any x is inexact, the + result is coerced to inexact. See also argmax.

Examples:
> (max 1 3 2)

3

> (max 1 3 2.0)

3.0

procedure

(min x ...+)  real?

  x : real?
Returns the smallest of the xs, or +nan.0 if any + x is +nan.0. If any x is inexact, the + result is coerced to inexact. See also argmin.

Examples:
> (min 1 3 2)

1

> (min 1 3 2.0)

1.0

procedure

(gcd n ...)  rational?

  n : rational?
Returns the greatest common divisor (a non-negative + number) of the ns; for non-integer ns, the result + is the gcd of the numerators divided + by the lcm of the denominators. + If no arguments are provided, the result + is 0. If all arguments are zero, the result is zero.

Examples:
> (gcd 10)

10

> (gcd 12 81.0)

3.0

> (gcd 1/2 1/3)

1/6

procedure

(lcm n ...)  rational?

  n : rational?
Returns the least common multiple (a non-negative number) + of the ns; non-integer ns, the result is + the absolute value of the product divided by the + gcd. If no arguments are provided, the result is + 1. If any argument is zero, the result is zero; furthermore, + if any argument is exact 0, the result is exact 0.

Examples:
> (lcm 10)

10

> (lcm 3 4.0)

12.0

> (lcm 1/2 2/3)

2

procedure

(round x)  (or/c integer? +inf.0 -inf.0 +nan.0)

  x : real?
Returns the integer closest to x, resolving ties in favor of + an even number, but +inf.0, -inf.0, and +nan.0 + round to themselves.

Examples:
> (round 17/4)

4

> (round -17/4)

-4

> (round 2.5)

2.0

> (round -2.5)

-2.0

> (round +inf.0)

+inf.0

procedure

(floor x)  (or/c integer? +inf.0 -inf.0 +nan.0)

  x : real?
Returns the largest integer that is no more than x, but + +inf.0, -inf.0, and +nan.0 floor to + themselves.

Examples:
> (floor 17/4)

4

> (floor -17/4)

-5

> (floor 2.5)

2.0

> (floor -2.5)

-3.0

> (floor +inf.0)

+inf.0

procedure

(ceiling x)  (or/c integer? +inf.0 -inf.0 +nan.0)

  x : real?
Returns the smallest integer that is at least as large as x, + but +inf.0, -inf.0, and +nan.0 ceiling to + themselves.

Examples:
> (ceiling 17/4)

5

> (ceiling -17/4)

-4

> (ceiling 2.5)

3.0

> (ceiling -2.5)

-2.0

> (ceiling +inf.0)

+inf.0

procedure

(truncate x)  (or/c integer? +inf.0 -inf.0 +nan.0)

  x : real?
Returns the integer farthest from 0 that is not farther from + 0 than x, but +inf.0, -inf.0, and + +nan.0 truncate to themselves.

Examples:
> (truncate 17/4)

4

> (truncate -17/4)

-4

> (truncate 2.5)

2.0

> (truncate -2.5)

-2.0

> (truncate +inf.0)

+inf.0

procedure

(numerator q)  integer?

  q : rational?
Coerces q to an exact number, finds the numerator of the + number expressed in its simplest fractional form, and returns this + number coerced to the exactness of q.

Examples:
> (numerator 5)

5

> (numerator 17/4)

17

> (numerator 2.3)

2589569785738035.0

procedure

(denominator q)  (and/c integer? positive?)

  q : rational?
Coerces q to an exact number, finds the denominator of the + number expressed in its simplest fractional form, and returns this + number coerced to the exactness of q.

Examples:
> (denominator 5)

1

> (denominator 17/4)

4

> (denominator 2.3)

1125899906842624.0

procedure

(rationalize x tolerance)  real?

  x : real?
  tolerance : real?
Among the real numbers within (abs tolerance) of x, + returns the one corresponding to an exact number whose + denominator is the smallest. If multiple integers are within + tolerance of x, the one closest to 0 is + used.

Examples:
> (rationalize 1/4 1/10)

1/3

> (rationalize -1/4 1/10)

-1/3

> (rationalize 1/4 1/4)

0

> (rationalize 11/40 1/4)

1/2

4.3.2.2 Number Comparison

procedure

(= z w ...)  boolean?

  z : number?
  w : number?
Returns + #t if all of the arguments are numerically equal, + #f otherwise. An inexact number is numerically equal to an + exact number when the exact coercion of the inexact number is the + exact number. Also, 0.0 and -0.0 are numerically + equal, but +nan.0 is not numerically equal to itself.

Examples:
> (= 1 1.0)

#t

> (= 1 2)

#f

> (= 2+3i 2+3i 2+3i)

#t

> (= 1)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(< x y ...)  boolean?

  x : real?
  y : real?
Returns #t if + the arguments in the given order are strictly increasing, + #f otherwise.

Examples:
> (< 1 1)

#f

> (< 1 2 3)

#t

> (< 1)

#t

> (< 1 +inf.0)

#t

> (< 1 +nan.0)

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(<= x y ...)  boolean?

  x : real?
  y : real?
Returns #t + if the arguments in the given order are non-decreasing, + #f otherwise.

Examples:
> (<= 1 1)

#t

> (<= 1 2 1)

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(> x y ...+)  boolean?

  x : real?
  y : real?
Returns #t if + the arguments in the given order are strictly decreasing, + #f otherwise.

Examples:
> (> 1 1)

#f

> (> 3 2 1)

#t

> (> +inf.0 1)

#t

> (> +nan.0 1)

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(>= x y ...)  boolean?

  x : real?
  y : real?
Returns #t + if the arguments in the given order are non-increasing, + #f otherwise.

Examples:
> (>= 1 1)

#t

> (>= 1 2 1)

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.3.2.3 Powers and Roots

procedure

(sqrt z)  number?

  z : number?
Returns the principal square root of z. The + result is exact if z is exact and z’s square root + is rational. See also integer-sqrt.

Examples:
> (sqrt 4/9)

2/3

> (sqrt 2)

1.4142135623730951

> (sqrt -1)

0+1i

procedure

(integer-sqrt n)  complex?

  n : integer?
Returns (floor (sqrt n)) for positive n. The + result is exact if n is exact. For + negative n, the result is (* (integer-sqrt (- n)) 0+1i).

Examples:
> (integer-sqrt 4.0)

2.0

> (integer-sqrt 5)

2

> (integer-sqrt -4.0)

0.0+2.0i

> (integer-sqrt -4)

0+2i

procedure

(integer-sqrt/remainder n)  
complex? integer?
  n : integer?
Returns (integer-sqrt n) and (- n (expt (integer-sqrt n) 2)).

Examples:

procedure

(expt z w)  number?

  z : number?
  w : number?
Returns z raised to the power of w.

If w is + exact 0, the result is exact 1. + If w is 0.0 or -0.0 and z is a real number + other than exact 1 or 0, the + result is 1.0 (even if z is +nan.0).

If z is exact 1, the result is exact 1. + If z is 1.0 and w is a real number, the + result is 1.0 (even if w is +nan.0).

If z is exact 0, the result is as follows: +

If w is exact 1/2, the result is the same as (sqrt z), +which can be exact. Other fractional powers are not treated specially in this manner: +

Examples:
> (expt 9 1/2)

3

> (expt 9 0.5)

3.0

> (expt 16 1/4)

2.0

> (expt 16 0.25)

2.0

Further special cases when w is a real number: +These special cases correspond to pow in C99 [C99], +except when z is negative and w is a not an +integer. +
  • (expt 0.0 w): +
    • w is negative — result is +inf.0

    • w is positive — result is 0.0

  • (expt -0.0 w): +
    • w is negative: +
      • w is an odd integer — result is -inf.0

      • w otherwise rational — result is +inf.0

    • w is positive: +
      • w is an odd integer — result is -0.0

      • w otherwise rational — result is 0.0

  • (expt z -inf.0) for positive z: +
    • z is less than 1.0 result is +inf.0

    • z is greater than 1.0 result is 0.0

  • (expt z +inf.0) for positive z: +
    • z is less than 1.0 result is 0.0

    • z is greater than 1.0 result is +inf.0

  • (expt -inf.0 w) for integer w: +
    • w is negative: +
      • w is odd — result is -0.0

      • w is even — result is 0.0

    • w is positive: +
      • w is odd — result is -inf.0

      • w is even — result is +inf.0

  • (expt +inf.0 w): +
    • w is negative — result is 0.0

    • w is positive — result is +inf.0

Examples:
> (expt 2 3)

8

> (expt 4 0.5)

2.0

> (expt +inf.0 0)

1

procedure

(exp z)  number?

  z : number?
Returns Euler’s number raised to the power of z. The result + is normally inexact, but it is exact 1 when z is an + exact 0. See also expt.

Examples:
> (exp 1)

2.718281828459045

> (exp 2+3i)

-7.315110094901103+1.0427436562359045i

> (exp 0)

1

procedure

(log z [b])  number?

  z : number?
  b : number? = (exp 1)
Returns the natural logarithm of z. The result is normally + inexact, but it is exact 0 when z is an exact + 1. When z is exact 0, + exn:fail:contract:divide-by-zero exception is raised.

If b is provided, it serves as an alternative + base. It is equivalent to (/ (log z) (log b)), but + can potentially run faster. If b is exact + 1, exn:fail:contract:divide-by-zero exception is raised.

Consider using fllogb instead when accuracy is + important.

Examples:
> (log (exp 1))

1.0

> (log 2+3i)

1.2824746787307684+0.982793723247329i

> (log 1)

0

> (log 100 10)

2.0

> (log 8 2)

3.0

> (log 5 5)

1.0

Changed in version 6.9.0.1 of package base: Added second argument for arbitrary bases.

4.3.2.4 Trigonometric Functions

procedure

(sin z)  number?

  z : number?
Returns the sine of z, where z is in radians. The + result is normally inexact, but it is exact 0 if z + is exact 0.

Examples:
> (sin 3.14159)

2.65358979335273e-6

> (sin 1.0+5.0i)

62.44551846769654+40.0921657779984i

procedure

(cos z)  number?

  z : number?
Returns the cosine of z, where z is in radians.

Examples:
> (cos 3.14159)

-0.9999999999964793

> (cos 1.0+5.0i)

40.09580630629883-62.43984868079963i

procedure

(tan z)  number?

  z : number?
Returns the tangent of z, where z is in radians. The + result is normally inexact, but it is exact 0 if z + is exact 0.

Examples:
> (tan 0.7854)

1.0000036732118496

> (tan 1.0+5.0i)

8.256719834229597e-5+1.0000377833796008i

procedure

(asin z)  number?

  z : number?
Returns the arcsine in radians of z. The result is normally + inexact, but it is exact 0 if z is exact 0.

Examples:
> (asin 0.25)

0.25268025514207865

> (asin 1.0+5.0i)

0.1937931365549322+2.3309746530493123i

procedure

(acos z)  number?

  z : number?
Returns the arccosine in radians of z.

Examples:
> (acos 0.25)

1.318116071652818

> (acos 1.0+5.0i)

1.3770031902399644-2.3309746530493123i

procedure

(atan z)  number?

  z : number?
(atan y x)  number?
  y : real?
  x : real?
In the one-argument case, returns the arctangent of the inexact + approximation of z, except that the result is an exact + 0 for z as 0, and the exn:fail:contract:divide-by-zero exception is raised + for z as exact 0+1i or exact 0-1i.

In the two-argument case, the result is roughly the same as (atan (/ (exact->inexact y)) (exact->inexact x)), but the signs of y + and x determine the quadrant of the result. Moreover, a + suitable angle is returned when y divided by x + produces +nan.0 in the case that neither y nor + x is +nan.0. Finally, if y is exact + 0 and x is a positive number, the result is + exact 0. If both x and y are exact + 0, the exn:fail:contract:divide-by-zero exception is raised.

Examples:
> (atan 0.5)

0.4636476090008061

> (atan 2 1)

1.1071487177940904

> (atan -2 -1)

-2.0344439357957027

> (atan 1.0+5.0i)

1.530881333938778+0.19442614214700213i

> (atan +inf.0 -inf.0)

2.356194490192345

Changed in version 7.2.0.2 of package base: Changed to raise exn:fail:contract:divide-by-zero +for 0+1i and 0-1i and to produce exact 0 +for any positive x (not just exact values) when y is 0.

4.3.2.5 Complex Numbers

procedure

(make-rectangular x y)  number?

  x : real?
  y : real?
Creates a complex number with x as the real part +and y as the imaginary part. That is, returns (+ x (* y 0+1i)).

Example:
> (make-rectangular 3 4.0)

3.0+4.0i

procedure

(make-polar magnitude angle)  number?

  magnitude : real?
  angle : real?
Creates a complex number which, if thought of as a point, +is magnitude away from the origin and is rotated +angle radians counter clockwise from the positive x-axis. +That is, returns (+ (* magnitude (cos angle)) (* magnitude (sin angle) 0+1i)).

Examples:
> (make-polar 10 (* pi 1/2))

6.123233995736766e-16+10.0i

> (make-polar 10 (* pi 1/4))

7.0710678118654755+7.071067811865475i

procedure

(real-part z)  real?

  z : number?
Returns the real part of the complex number z in rectangle + coordinates.

Examples:
> (real-part 3+4i)

3

> (real-part 5.0)

5.0

procedure

(imag-part z)  real?

  z : number?
Returns the imaginary part of the complex number z in + rectangle coordinates.

Examples:
> (imag-part 3+4i)

4

> (imag-part 5.0)

0

> (imag-part 5.0+0.0i)

0.0

procedure

(magnitude z)  (and/c real? (not/c negative?))

  z : number?
Returns the magnitude of the complex number z in polar + coordinates. A complex number with +inf.0 or -inf.0 + as a component has magnitude +inf.0, even if the other + component is +nan.0.

Examples:
> (magnitude -3)

3

> (magnitude 3.0)

3.0

> (magnitude 3+4i)

5

Changed in version 7.2.0.2 of package base: Changed to always return +inf.0 +for a complex number with a +inf.0 +or -inf.0 component.

procedure

(angle z)  real?

  z : number?
Returns the angle of + the complex number z in polar coordinates.

The result is guaranteed to be between (- pi) and + pi, possibly equal to pi (but never equal + to (- pi)).

Examples:
> (angle -3)

3.141592653589793

> (angle 3.0)

0

> (angle 3+4i)

0.9272952180016122

> (angle +inf.0+inf.0i)

0.7853981633974483

> (angle -1)

3.141592653589793

4.3.2.6 Bitwise Operations

procedure

(bitwise-ior n ...)  exact-integer?

  n : exact-integer?
Returns + the bitwise “inclusive or” of the ns in their (semi-infinite) + two’s complement representation. If no arguments are provided, the + result is 0.

Examples:
> (bitwise-ior 1 2)

3

> (bitwise-ior -32 1)

-31

procedure

(bitwise-and n ...)  exact-integer?

  n : exact-integer?
Returns + the bitwise “and” of the ns in their (semi-infinite) two’s + complement representation. If no arguments are provided, the result + is -1.

Examples:
> (bitwise-and 1 2)

0

> (bitwise-and -32 -1)

-32

procedure

(bitwise-xor n ...)  exact-integer?

  n : exact-integer?
Returns + the bitwise “exclusive or” of the ns in their (semi-infinite) + two’s complement representation. If no arguments are provided, the + result is 0.

Examples:
> (bitwise-xor 1 5)

4

> (bitwise-xor -32 -1)

31

procedure

(bitwise-not n)  exact-integer?

  n : exact-integer?
Returns the + bitwise “not” of n in its (semi-infinite) two’s complement + representation.

Examples:
> (bitwise-not 5)

-6

> (bitwise-not -1)

0

procedure

(bitwise-bit-set? n m)  boolean?

  n : exact-integer?
  m : exact-nonnegative-integer?
Returns #t when the mth bit of n is set in n’s + (semi-infinite) two’s complement representation.

This operation is equivalent to +(not (zero? (bitwise-and n (arithmetic-shift 1 m)))), +but it is faster and runs in constant time when n is positive.

Examples:
> (bitwise-bit-set? 5 0)

#t

> (bitwise-bit-set? 5 2)

#t

> (bitwise-bit-set? -5 (expt 2 700))

#t

procedure

(bitwise-bit-field n start end)  exact-integer?

  n : exact-integer?
  start : exact-nonnegative-integer?
  end : 
(and/c exact-nonnegative-integer?
       (>=/c start))
Extracts the bits between position start and (- end 1) (inclusive) +from n and shifts them down to the least significant portion of the number.

This operation is equivalent to the computation

(bitwise-and (sub1 (arithmetic-shift 1 (- end start)))
             (arithmetic-shift n (- start)))

but it runs in constant time when n is positive, start and +end are fixnums, and (- end start) is no more than +the maximum width of a fixnum.

Each pair of examples below uses the same numbers, showing the result +both in binary and as integers.

Examples:
> (format "~b" (bitwise-bit-field (string->number "1101" 2) 1 1))

"0"

> (bitwise-bit-field 13 1 1)

0

> (format "~b" (bitwise-bit-field (string->number "1101" 2) 1 3))

"10"

> (bitwise-bit-field 13 1 3)

2

> (format "~b" (bitwise-bit-field (string->number "1101" 2) 1 4))

"110"

> (bitwise-bit-field 13 1 4)

6

procedure

(arithmetic-shift n m)  exact-integer?

  n : exact-integer?
  m : exact-integer?
Returns the bitwise “shift” of n in its + (semi-infinite) two’s complement representation. If m is + non-negative, the integer n is shifted left by m bits; + i.e., m new zeros are introduced as rightmost digits. If + m is negative, n is shifted right by (- m) + bits; i.e., the rightmost m digits are dropped.

Examples:
> (arithmetic-shift 1 10)

1024

> (arithmetic-shift 255 -3)

31

procedure

(integer-length n)  exact-integer?

  n : exact-integer?
Returns + the number of bits in the (semi-infinite) two’s complement + representation of n after removing all leading zeros (for + non-negative n) or ones (for negative n).

Examples:

4.3.2.7 Random Numbers

When security is a concern, use crypto-random-bytes instead of random.

procedure

(random k [rand-gen])  exact-nonnegative-integer?

  k : (integer-in 1 4294967087)
  rand-gen : pseudo-random-generator?
   = (current-pseudo-random-generator)
(random min max [rand-gen])  exact-nonnegative-integer?
  min : exact-integer?
  max : (integer-in (+ 1 min) (+ 4294967087 min))
  rand-gen : pseudo-random-generator?
   = (current-pseudo-random-generator)
(random [rand-gen])  (and/c real? inexact? (>/c 0) (</c 1))
  rand-gen : pseudo-random-generator?
   = (current-pseudo-random-generator)
When called with an integer argument k, returns a random +exact integer in the range 0 to k-1.

When called with two integer arguments min and max, returns a +random exact integer in the range min to max-1.

When called with zero arguments, returns a random inexact number between +0 and 1, exclusive.

In each case, the number is provided by the given pseudo-random number +generator (which defaults to the current one, as produced by +current-pseudo-random-generator). The generator maintains an +internal state for generating numbers. The random number generator +uses L’Ecuyer’s MRG32k3a algorithm [L'Ecuyer02] that has a +state space of practically 192 bits.

Changed in version 6.4 of package base: Added support for ranges.

procedure

(random-seed k)  void?

  k : (integer-in 0 (sub1 (expt 2 31)))
Seeds the current pseudo-random number generator with +k. Seeding a generator sets its internal state +deterministically; that is, seeding a generator with a particular +number forces it to produce a sequence of pseudo-random numbers that +is the same across runs and across platforms.

The random-seed function is convenient for some purposes, but +note that the space of states for a pseudo-random number generator is +much larger that the space of allowed values for k. Use +vector->pseudo-random-generator! to set a pseudo-random +number generator to any of its possible states.

Returns a new pseudo-random number generator. The new generator is +seeded with a number derived from (current-milliseconds).

procedure

(pseudo-random-generator? v)  boolean?

  v : any/c
Returns #t if v is a pseudo-random number generator, +#f otherwise.

A parameter that determines the pseudo-random number generator +used by random.

Produces a vector that represents the complete internal state of +rand-gen. The vector is suitable as an argument to +vector->pseudo-random-generator to recreate the generator in +its current state (across runs and across platforms).

Produces a pseudo-random number generator whose internal state +corresponds to vec.

procedure

(vector->pseudo-random-generator! rand-gen    
  vec)  void?
  rand-gen : pseudo-random-generator?
  vec : pseudo-random-generator-vector?
Like vector->pseudo-random-generator, but changes +rand-gen to the given state, instead of creating a new +generator.

procedure

(pseudo-random-generator-vector? v)  boolean?

  v : any/c
Returns #t if v is a vector of six exact integers, +where the first three integers are in the range 0 to +4294967086, inclusive; the last three integers are in the +range 0 to 4294944442, inclusive; at least one of +the first three integers is non-zero; and at least one of the last +three integers is non-zero. Otherwise, the result is #f.

4.3.2.8 Other Randomness Utilities

 (require racket/random) package: base

Provides an interface to randomness from the underlying operating system. Use +crypto-random-bytes instead of random wherever security is a +concern.

Returns n random bytes. On Unix systems, the bytes are +obtained from "/dev/urandom", while Windows uses +the RtlGenRand system function.

Example:
> (crypto-random-bytes 14)

#"\0\1\1\2\3\5\b\r\25\"7Y\220\351"

Added in version 6.3 of package base.

procedure

(random-ref seq [rand-gen])  any/c

  seq : sequence?
  rand-gen : pseudo-random-generator?
   = (current-pseudo-random-generator)
Returns a random element of the sequence. Like sequence-length, does +not terminate on infinite sequences, and evaluates the entire sequence.

Added in version 6.4 of package base.

procedure

(random-sample seq    
  n    
  [rand-gen    
  #:replacement? replacement?])  (listof any/c)
  seq : sequence?
  n : exact-positive-integer?
  rand-gen : pseudo-random-generator?
   = (current-pseudo-random-generator)
  replacement? : any/c = #t
Returns a list of n elements of seq, picked at random, listed +in any order. +If replacement? is non-false, elements are drawn with replacement, +which allows for duplicates.

Like sequence-length, does not terminate on infinite sequences, and +evaluates the entire sequence.

Added in version 6.4 of package base.

4.3.2.9 Number–String Conversions

procedure

(number->string z [radix])  string?

  z : number?
  radix : (or/c 2 8 10 16) = 10
Returns a string that is the printed form of z (see Printing Numbers) + in the base specified by radix. If z is inexact, + radix must be 10, otherwise the + exn:fail:contract exception is raised.

Examples:
> (number->string 3.0)

"3.0"

> (number->string 255 8)

"377"

procedure

(string->number s 
  [radix 
  convert-mode 
  decimal-mode 
  single-mode]) 
  (or/c number? #f string? extflonum?)
  s : string?
  radix : (integer-in 2 16) = 10
  convert-mode : (or/c 'number-or-false 'read)
   = 'number-or-false
  decimal-mode : (or/c 'decimal-as-inexact 'decimal-as-exact)
   = 
(if (read-decimal-as-inexact)
    'decimal-as-inexact
    'decimal-as-exact)
  single-mode : (or/c 'single 'double)
   = 
(if (read-single-flonum)
    'single
    'double)
Reads and returns a number datum from s (see +Reading Numbers). The optional radix argument +specifies the default base for the number, which can be overridden by +#b, #o, #d, or #x in the +string.

If convert-mode is 'number-or-false, the result is +#f if s does not parse exactly as a number datum +(with no whitespace). If convert-mode is 'read, the +result can be an extflonum, and it can be a string that +contains an error message if read of s would report +a reader exception (but the result can still be #f if +read would report a symbol).

The decimal-mode argument controls number parsing the same +way that the read-decimal-as-inexact parameter affects +read.

The single-mode argument controls number parsing the same way +that the read-single-flonum parameter affects read.

Examples:
> (string->number "3.0+2.5i")

3.0+2.5i

> (string->number "hello")

#f

> (string->number "111" 7)

57

> (string->number "#b111" 7)

7

> (string->number "#e+inf.0" 10 'read)

"no exact representation for +inf.0"

> (string->number "10.3" 10 'read 'decimal-as-exact)

103/10

Changed in version 6.8.0.2 of package base: Added the convert-mode and +decimal-mode arguments.
Changed in version 7.3.0.5: Added the single-mode argument.

procedure

(real->decimal-string n [decimal-digits])  string?

  n : rational?
  decimal-digits : exact-nonnegative-integer? = 2
Prints n into a string and returns the string. The printed +form of n shows exactly decimal-digits digits after +the decimal point. The printed form uses a minus sign if n is +negative, and it does not use a plus sign if n is positive.

Before printing, n is converted to an exact number, +multiplied by (expt 10 decimal-digits), rounded, and then +divided again by (expt 10 decimal-digits). The result of this +process is an exact number whose decimal representation has no more +than decimal-digits digits after the decimal (and it is +padded with trailing zeros if necessary).

If n is a real number with no decimal representation (e.g. ++nan.0, +inf.0), then the exn:fail:contract exception is raised. +(Any real number that is convertible to decimal notation is rational, +so n must be rational?, despite the name of the +function.)

Examples:
> (real->decimal-string pi)

"3.14"

> (real->decimal-string pi 5)

"3.14159"

procedure

(integer-bytes->integer bstr    
  signed?    
  [big-endian?    
  start    
  end])  exact-integer?
  bstr : bytes?
  signed? : any/c
  big-endian? : any/c = (system-big-endian?)
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Converts the machine-format number encoded in bstr to an +exact integer. The start and end arguments specify +the substring to decode, where (- end start) must be 1, +2, 4, or 8. If signed? is true, +then the bytes are decoded as a two’s-complement number, otherwise it +is decoded as an unsigned integer. If big-endian? is true, +then the first byte’s value provides the most significant +eight bits of the number, otherwise the first byte provides the +least-significant eight bits, and so on.

Changed in version 6.10.0.1 of package base: Added support for decoding a 1-byte string.

procedure

(integer->integer-bytes n    
  size-n    
  signed?    
  [big-endian?    
  dest-bstr    
  start])  bytes?
  n : exact-integer?
  size-n : (or/c 1 2 4 8)
  signed? : any/c
  big-endian? : any/c = (system-big-endian?)
  dest-bstr : (and/c bytes? (not/c immutable?))
   = (make-bytes size-n)
  start : exact-nonnegative-integer? = 0
Converts the exact integer n to a machine-format number +encoded in a byte string of length size-n, which must be 1, +2, 4, or 8. If signed? is true, +then the number is encoded as two’s complement, otherwise it is +encoded as an unsigned bit stream. If big-endian? is true, +then the most significant eight bits of the number are encoded in the +first byte of the resulting byte string, otherwise the +least-significant bits are encoded in the first byte, and so on.

The dest-bstr argument must be a mutable byte string of +length size-n. The encoding of n is written into +dest-bstr starting at offset start, and +dest-bstr is returned as the result.

If n cannot be encoded in a byte string of the requested size and +format, the exn:fail:contract exception is raised. If dest-bstr is not +of length size-n, the exn:fail:contract exception is raised.

Changed in version 6.10.0.1 of package base: Added support for encoding a 1-byte value.

procedure

(floating-point-bytes->real bstr    
  [big-endian?    
  start    
  end])  flonum?
  bstr : bytes?
  big-endian? : any/c = (system-big-endian?)
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (bytes-length bstr)
Converts the IEEE floating-point number encoded in bstr from +position start (inclusive) to end (exclusive) to an +inexact real number. The difference between start an +end must be either 4 or 8 bytes. If big-endian? is +true, then the first byte’s ASCII value provides the most significant +eight bits of the IEEE representation, otherwise the first byte +provides the least-significant eight bits, and so on.

procedure

(real->floating-point-bytes x    
  size-n    
  [big-endian?    
  dest-bstr    
  start])  bytes?
  x : real?
  size-n : (or/c 4 8)
  big-endian? : any/c = (system-big-endian?)
  dest-bstr : (and/c bytes? (not/c immutable?))
   = (make-bytes size-n)
  start : exact-nonnegative-integer? = 0
Converts the real number x to its IEEE representation in a +byte string of length size-n, which must be 4 or +8. If big-endian? is true, then the most significant +eight bits of the number are encoded in the first byte of the +resulting byte string, otherwise the least-significant bits are +encoded in the first character, and so on.

The dest-bstr argument must be a mutable byte string of +length size-n. The encoding of n is written into +dest-bstr starting with byte start, and +dest-bstr is returned as the result.

If dest-bstr is provided and it has less than start +plus size-n bytes, the exn:fail:contract exception is raised.

procedure

(system-big-endian?)  boolean?

Returns #t if the native encoding of numbers is big-endian +for the machine running Racket, #f if the native encoding +is little-endian.

4.3.2.10 Extra Constants and Functions

 (require racket/math) package: base
The bindings documented in this section are provided by the racket/math and racket libraries, but not racket/base.

value

pi : flonum?

An approximation of π, the ratio of a circle’s circumference to its +diameter. +

Examples:
> pi

3.141592653589793

> (cos pi)

-1.0

The same value as pi, but as a single-precision +floating-point number if the current platform supports it.

Changed in version 7.3.0.5 of package base: Allow value to be a double-precision flonum.

procedure

(degrees->radians x)  real?

  x : real?
Converts an x-degree angle to radians. +

Examples:
> (degrees->radians 180)

3.141592653589793

> (sin (degrees->radians 45))

0.7071067811865475

procedure

(radians->degrees x)  real?

  x : real?
Converts x radians to degrees. +

Examples:
> (radians->degrees pi)

180.0

> (radians->degrees (* 1/4 pi))

45.0

procedure

(sqr z)  number?

  z : number?
Returns (* z z).

procedure

(sgn x)  (or/c (=/c -1) (=/c 0) (=/c 1) +nan.0 +nan.f)

  x : real?
Returns the sign of x as either -1, 0 (or a signed-zero variant, when +inexact), 1, or not-a-number.

Examples:
> (sgn 10)

1

> (sgn -10.0)

-1.0

> (sgn 0)

0

> (sgn -0.0)

-0.0

> (sgn 0.0)

0.0

> (sgn +nan.0)

+nan.0

> (sgn +inf.0)

1.0

> (sgn -inf.0)

-1.0

procedure

(conjugate z)  number?

  z : number?
Returns the complex conjugate of z.

Examples:
> (conjugate 1)

1

> (conjugate 3+4i)

3-4i

procedure

(sinh z)  number?

  z : number?
Returns the hyperbolic sine of z.

procedure

(cosh z)  number?

  z : number?
Returns the hyperbolic cosine of z.

procedure

(tanh z)  number?

  z : number?
Returns the hyperbolic tangent of z.

procedure

(exact-round x)  exact-integer?

  x : rational?
Equivalent to (inexact->exact (round x)).

procedure

(exact-floor x)  exact-integer?

  x : rational?
Equivalent to (inexact->exact (floor x)).

procedure

(exact-ceiling x)  exact-integer?

  x : rational?
Equivalent to (inexact->exact (ceiling x)).

procedure

(exact-truncate x)  exact-integer?

  x : rational?
Equivalent to (inexact->exact (truncate x)).

procedure

(order-of-magnitude r)  (and/c exact? integer?)

  r : (and/c real? positive?)
Computes the greatest exact integer m such that: +
(<= (expt 10 m)
    (inexact->exact r))
Hence also: +
(< (inexact->exact r)
   (expt 10 (add1 m)))

Examples:

procedure

(nan? x)  boolean?

  x : real?
Returns #t if x is eqv? to +nan.0 or +nan.f; otherwise #f.

procedure

(infinite? x)  boolean?

  x : real?
Returns #t if x is +inf.0, -inf.0, +inf.f, -inf.f; otherwise #f.

procedure

(positive-integer? x)  boolean?

  x : any/c
Like exact-positive-integer?, but also returns +#t for positive inexact? integers. +

Added in version 6.8.0.2 of package base.

procedure

(negative-integer? x)  boolean?

  x : any/c
The same as (and (integer? x) (negative? x)). +

Added in version 6.8.0.2 of package base.

procedure

(nonpositive-integer? x)  boolean?

  x : any/c
The same as (and (integer? x) (not (positive? x))). +

Added in version 6.8.0.2 of package base.

procedure

(nonnegative-integer? x)  boolean?

  x : any/c
Like exact-nonnegative-integer?, but also returns +#t for non-negative inexact? integers. +

Added in version 6.8.0.2 of package base.

procedure

(natural? x)  boolean?

  x : any/c

Added in version 6.8.0.2 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/hashtables.html b/clones/docs.racket-lang.org/reference/hashtables.html new file mode 100644 index 00000000..3b997b4a --- /dev/null +++ b/clones/docs.racket-lang.org/reference/hashtables.html @@ -0,0 +1,278 @@ + +4.15 Hash Tables

4.15 Hash Tables

+Hash Tables in The Racket Guide introduces hash tables.

A hash table (or simply hash) maps each of its +keys to a single value. For a given hash table, keys are equivalent +via equal?, equal-always?, eqv?, or +eq?, and keys are retained either strongly, weakly +(see Weak Boxes), or like ephemerons. +A hash table is also either mutable or immutable. +Immutable hash tables support effectively constant-time access and +update, just like mutable hash tables; the constant on immutable +operations is usually larger, but the functional nature of immutable +hash tables can pay off in certain algorithms. Use immutable? +to check whether a hash table is immutable.

Immutable hash tables actually provide O(log N) +access and update. Since N is limited by the address space so +that log N is limited to less than 30 or 62 (depending on the +platform), log N can be treated reasonably as a constant.

For equal?-based hashing, the built-in hash functions on +strings, pairs, lists, vectors, +prefab or transparent structures, etc., take time +proportional to the size of the value. The hash code for a compound +data structure, such as a list or vector, depends on hashing each item +of the container, but the depth of such recursive hashing is +limited (to avoid potential problems with cyclic data). For a +non-list pair, both car and cdr +hashing is treated as a deeper hash, but the cdr of a +list is treated as having the same hashing depth as the list.

A hash table can be used as a two-valued sequence (see +Sequences). The keys and values of the hash table serve as +elements of the sequence (i.e., each element is a key and its +associated value). If a mapping is added to or removed from the hash +table during iteration, then an iteration step may fail with +exn:fail:contract, or the iteration may skip or duplicate +keys and values. See also in-hash, in-hash-keys, +in-hash-values, and in-hash-pairs.

Two hash tables cannot be equal? unless they have the same +mutability, use the same key-comparison procedure (equal?, +equal-always?, eqv?, or eq?), both hold +keys strongly, weakly, or like ephemerons. +Empty immutable hash tables are eq? +when they are equal?.

Changed in version 7.2.0.9 of package base: Made empty immutable hash tables +eq? when they are +equal?.

Caveats concerning concurrent +modification: A mutable hash table can be manipulated with +hash-ref, hash-set!, and hash-remove! +concurrently by multiple threads, and the operations are protected by +a table-specific semaphore as needed. Several caveats apply, however:

  • If a thread is terminated while applying hash-ref, +hash-ref-key, hash-set!, hash-remove!, +hash-ref!, hash-update!, or hash-clear! +to a hash table that +uses equal?, equal-always?, or eqv? key +comparisons, all current and future operations on the hash table may +block indefinitely.

  • The hash-map, hash-for-each, and hash-clear! procedures do +not use the table’s semaphore to guard the traversal as a whole +(if a traversal is needed, in the case of hash-clear!). +Changes by one thread to a hash table can affect the keys and values +seen by another thread part-way through its traversal of the same +hash table.

  • The hash-update! and hash-ref! functions +use a table’s semaphore +independently for the hash-ref and hash-set! parts +of their functionality, which means that the update as a whole is not +“atomic.”

  • Adding a mutable hash table as a key in itself is trouble on +the grounds that the key is being mutated (see the caveat below), +but it is also a kind of concurrent use of the hash table: computing +a hash table’s hash code may require waiting on the table’s +semaphore, but the semaphore is already held for modifying the hash +table, so the hash-table addition can block indefinitely.

Caveat concerning mutable +keys: If a key in an equal?-based hash table is mutated +(e.g., a key string is modified with string-set!), then the +hash table’s behavior for insertion and lookup operations becomes +unpredictable.

A literal or printed hash table starts with #hash, +#hashalw, #hasheqv, or +#hasheq. See Reading Hash Tables + for information on reading + hash tables and Printing Hash Tables + for information on printing hash tables.

procedure

(hash? v)  boolean?

  v : any/c
Returns #t if v is a hash table, #f +otherwise.

procedure

(hash-equal? hash)  boolean?

  hash : hash?
Returns #t if hash compares keys with equal?, +#f if it compares with eq?, eqv?, or +equal-always?.

procedure

(hash-equal-always? hash)  boolean?

  hash : hash?
Returns #t if hash compares keys with +equal-always?, #f if it compares with eq?, +eqv?, or equal?.

Added in version 8.5.0.3 of package base.

procedure

(hash-eqv? hash)  boolean?

  hash : hash?
Returns #t if hash compares keys with eqv?, +#f if it compares with equal?, +equal-always?, or eq?.

procedure

(hash-eq? hash)  boolean?

  hash : hash?
Returns #t if hash compares keys with eq?, +#f if it compares with equal?, +equal-always?, or eqv?.

procedure

(hash-strong? hash)  boolean?

  hash : hash?
Returns #t if hash retains its keys strongly, +#f if it retains keys weakly or like ephemerons.

Added in version 8.0.0.10 of package base.

procedure

(hash-weak? hash)  boolean?

  hash : hash?
Returns #t if hash retains its keys weakly, +#f if it retains keys strongly or like ephemerons.

procedure

(hash-ephemeron? hash)  boolean?

  hash : hash?
Returns #t if hash retains its keys like +ephemerons, #f if it retains keys strongly or merely +weakly.

Added in version 8.0.0.10 of package base.

procedure

(hash key val ... ...)

  (and/c hash? hash-equal? immutable? hash-strong?)
  key : any/c
  val : any/c

procedure

(hashalw key val ... ...)

  (and/c hash? hash-equal-always? immutable? hash-strong?)
  key : any/c
  val : any/c

procedure

(hasheq key val ... ...)

  (and/c hash? hash-eq? immutable? hash-strong?)
  key : any/c
  val : any/c

procedure

(hasheqv key val ... ...)

  (and/c hash? hash-eqv? immutable? hash-strong?)
  key : any/c
  val : any/c
Creates an immutable hash table with each given key mapped to +the following val; each key must have a val, +so the total number of arguments to hash must be even.

The hash procedure creates a table where keys are compared +with equal?, hashalw creates a table where keys are compared with +equal-always?, hasheq procedure creates a table where +keys are compared with eq?, hasheqv procedure +creates a table where keys are compared with eqv?.

The key to val mappings are added to the table in +the order that they appear in the argument list, so later mappings can +hide earlier mappings if the keys are equal.

Changed in version 8.5.0.3 of package base: Added hashalw.

procedure

(make-hash [assocs])

  (and/c hash? hash-equal? (not/c immutable?) hash-strong?)
  assocs : (listof pair?) = null

procedure

(make-hashalw [assocs])

  (and/c hash? hash-equal-always? (not/c immutable?) hash-strong?)
  assocs : (listof pair?) = null

procedure

(make-hasheqv [assocs])

  (and/c hash? hash-eqv? (not/c immutable?) hash-strong?)
  assocs : (listof pair?) = null

procedure

(make-hasheq [assocs])

  (and/c hash? hash-eq? (not/c immutable?) hash-strong?)
  assocs : (listof pair?) = null
Creates a mutable hash table that holds keys strongly.

The make-hash procedure creates a table where keys are +compared with equal?, make-hasheq procedure creates +a table where keys are compared with eq?, +make-hasheqv procedure creates a table where keys are +compared with eqv?, and make-hashalw creates a table +where keys are compared with equal-always?.

The table is initialized with the content of assocs. In each +element of assocs, the car is a key, and the +cdr is the corresponding value. The mappings are added to the +table in the order that they appear in assocs, so later +mappings can hide earlier mappings.

See also make-custom-hash.

Changed in version 8.5.0.3 of package base: Added make-hashalw.

procedure

(make-weak-hash [assocs])

  (and/c hash? hash-equal? (not/c immutable?) hash-weak?)
  assocs : (listof pair?) = null

procedure

(make-weak-hashalw [assocs])

  (and/c hash? hash-equal-always? (not/c immutable?) hash-weak?)
  assocs : (listof pair?) = null

procedure

(make-weak-hasheqv [assocs])

  (and/c hash? hash-eqv? (not/c immutable?) hash-weak?)
  assocs : (listof pair?) = null

procedure

(make-weak-hasheq [assocs])

  (and/c hash? hash-eq? (not/c immutable?) hash-weak?)
  assocs : (listof pair?) = null
Like make-hash, make-hasheq, +make-hasheqv, and make-hashalw, but creates a +mutable hash table that holds keys weakly.

Beware that values in a weak hash table are retained normally. If a value in +the table refers back to its key, then the table will retain the value +and therefore the key; the mapping will never be removed from the +table even if the key becomes otherwise inaccessible. To avoid that +problem, use an ephemeron hash table as created by +make-ephemeron-hash, make-ephemeron-hashalw, +make-ephemeron-hasheqv, or make-ephemeron-hasheq. +For values that do not refer to keys, +there is a modest extra cost to using an ephemeron hash table instead +of a weak hash table, but prefer an ephemeron hash table when in +doubt.

Changed in version 8.5.0.3 of package base: Added make-weak-hashalw.

procedure

(make-ephemeron-hash [assocs])

  (and/c hash? hash-equal? (not/c immutable?) hash-ephemeron?)
  assocs : (listof pair?) = null

procedure

(make-ephemeron-hashalw [assocs])

  (and/c hash? hash-equal-always? (not/c immutable?) hash-ephemeron?)
  assocs : (listof pair?) = null

procedure

(make-ephemeron-hasheqv [assocs])

  (and/c hash? hash-eqv? (not/c immutable?) hash-ephemeron?)
  assocs : (listof pair?) = null

procedure

(make-ephemeron-hasheq [assocs])

  (and/c hash? hash-eq? (not/c immutable?) hash-ephemeron?)
  assocs : (listof pair?) = null
Like make-hash, make-hasheq, +make-hasheqv, and make-hashalw, +but creates a mutable hash table that holds +key-value combinations in the same way as an ephemeron.

Using an ephemeron hash table is like using a weak hash table and +mapping each key to a ephemeron that pairs the key and value. +An advantage of an ephemeron hash table is that the value need not be +extracted with ephemeron-value from the result of functions +like hash-ref. An ephemeron hash table might also be +represented more compactly than a weak hash table with explicit +ephemeron values.

Added in version 8.0.0.10 of package base.
Changed in version 8.5.0.3: Added make-ephemeron-hashalw.

procedure

(make-immutable-hash [assocs])

  (and/c hash? hash-equal? immutable? hash-strong?)
  assocs : (listof pair?) = null

procedure

(make-immutable-hashalw [assocs])

  (and/c hash? hash-equal-always? immutable? hash-strong?)
  assocs : (listof pair?) = null

procedure

(make-immutable-hasheqv [assocs])

  (and/c hash? hash-eqv? immutable? hash-strong?)
  assocs : (listof pair?) = null

procedure

(make-immutable-hasheq [assocs])

  (and/c hash? hash-eq? immutable? hash-strong?)
  assocs : (listof pair?) = null
Like hash, hashalw, hasheq, and +hasheqv, but accepts +the key–value mapping in association-list form like +make-hash, make-hashalw, make-hasheq, and +make-hasheqv.

Changed in version 8.5.0.3 of package base: Added make-immutable-hashalw.

procedure

(hash-set! hash key v)  void?

  hash : (and/c hash? (not/c immutable?))
  key : any/c
  v : any/c
Maps key to v in hash, overwriting +any existing mapping for key.

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

procedure

(hash-set*! hash key v ... ...)  void?

  hash : (and/c hash? (not/c immutable?))
  key : any/c
  v : any/c
Maps each key to each v in hash, overwriting +any existing mapping for each key. Mappings are added from the left, so +later mappings overwrite earlier mappings.

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

procedure

(hash-set hash key v)  (and/c hash? immutable?)

  hash : (and/c hash? immutable?)
  key : any/c
  v : any/c
Functionally extends hash by mapping key to +v, overwriting any existing mapping for key, and +returning the extended hash table.

See also the caveat concerning mutable keys above.

procedure

(hash-set* hash key v ... ...)  (and/c hash? immutable?)

  hash : (and/c hash? immutable?)
  key : any/c
  v : any/c
Functionally extends hash by mapping each key to +v, overwriting any existing mapping for each key, and +returning the extended hash table. Mappings are added from the left, so +later mappings overwrite earlier mappings.

See also the caveat concerning mutable keys above.

procedure

(hash-ref hash key [failure-result])  any

  hash : hash?
  key : any/c
  failure-result : failure-result/c
   = 
(lambda ()
  (raise (make-exn:fail:contract ....)))
Returns the value for key in hash. If no value +is found for key, then failure-result determines the +result:

  • If failure-result is a procedure, it is called +(through a tail call) with no arguments to produce the result.

  • Otherwise, failure-result is returned as the result.

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

procedure

(hash-ref-key hash key [failure-result])  any

  hash : hash?
  key : any/c
  failure-result : failure-result/c
   = 
(lambda ()
  (raise (make-exn:fail:contract ....)))
Returns the key held by hash that is equivalent to key +according to hash’s key-comparison function. If no key is found, +then failure-result is used as in hash-ref to determine +the result.

If hash is not an impersonator, then the returned key, +assuming it is found, will be eq?-equivalent to the one +actually retained by hash:

Examples:
> (define original-key "hello")
> (define key-copy (string-copy original-key))
> (equal? original-key key-copy)

#t

> (eq? original-key key-copy)

#f

> (define table (make-hash))
> (hash-set! table original-key 'value)
> (eq? (hash-ref-key table "hello") original-key)

#t

> (eq? (hash-ref-key table "hello") key-copy)

#f

If a mutable hash is updated multiple times using keys that are +not eq?-equivalent but are equivalent according to the +hash’s key-comparison procedure, the hash retains the first one:

Examples:
> (define original-key "hello")
> (define key-copy (string-copy original-key))
> (define table (make-hash))
> (hash-set! table original-key 'one)
> (hash-set! table key-copy 'two)
> (eq? (hash-ref-key table "hello") original-key)

#t

> (eq? (hash-ref-key table "hello") key-copy)

#f

Conversely, an immutable hash retains the key that was most-recently +used to update it: +

Examples:
> (define original-key "hello")
> (define key-copy (string-copy original-key))
> (define table0 (hash))
> (define table1 (hash-set table0 original-key 'one))
> (define table2 (hash-set table1 key-copy 'two))
> (eq? (hash-ref-key table2 "hello") original-key)

#f

> (eq? (hash-ref-key table2 "hello") key-copy)

#t

If hash is an impersonator, then the returned key +will be determined as described in the documentation to +impersonate-hash.

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

Added in version 7.4.0.3 of package base.

procedure

(hash-ref! hash key to-set)  any

  hash : hash?
  key : any/c
  to-set : failure-result/c
Returns the value for key in hash. If no value is +found for key, then to-set determines the result as +in hash-ref (i.e., it is either a thunk that computes a value +or a plain value), and this result is stored in hash for the +key. (Note that if to-set is a thunk, it is not +invoked in tail position.)

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

procedure

(hash-has-key? hash key)  boolean?

  hash : hash?
  key : any/c
Returns #t if hash contains a value for the given +key, #f otherwise.

procedure

(hash-update! hash    
  key    
  updater    
  [failure-result])  void?
  hash : (and/c hash? (not/c immutable?))
  key : any/c
  updater : (any/c . -> . any/c)
  failure-result : failure-result/c
   = 
(lambda ()
  (raise (make-exn:fail:contract ....)))
Updates the value mapped by key in hash by applying updater to the value. +The value returned by updater becomes the new mapping for key, overwriting the +original value in hash.

Examples:
(define h (make-hash))
(hash-set! h 'a 5)

 

> (hash-update! h 'a add1)
> h

'#hash((a . 6))

The optional failure-result argument is used when no mapping exists for key +already, in the same manner as in hash-ref.

Examples:
(define h (make-hash))

 

> (hash-update! h 'b add1)

hash-update!: no value found for key: 'b

> (hash-update! h 'b add1 0)
> h

'#hash((b . 1))

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

procedure

(hash-update hash key updater [failure-result])

  (and/c hash? immutable?)
  hash : (and/c hash? immutable?)
  key : any/c
  updater : (any/c . -> . any/c)
  failure-result : failure-result/c
   = 
(lambda ()
  (raise (make-exn:fail:contract ....)))
Functionally updates the value mapped by key in hash by applying updater +to the value and returning a new hash table. The value returned by updater becomes the new +mapping for key in the returned hash table.

Examples:
(define h (hash 'a 5))

 

> (hash-update h 'a add1)

'#hash((a . 6))

The optional failure-result argument is used when no mapping exists for key +already, in the same manner as in hash-ref.

Examples:
(define h (hash))

 

> (hash-update h 'b add1)

hash-update: no value found for key: 'b

> (hash-update h 'b add1 0)

'#hash((b . 1))

See also the caveat concerning mutable keys above.

procedure

(hash-remove! hash key)  void?

  hash : (and/c hash? (not/c immutable?))
  key : any/c
Removes any existing mapping for key in hash.

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

procedure

(hash-remove hash key)  (and/c hash? immutable?)

  hash : (and/c hash? immutable?)
  key : any/c
Functionally removes any existing mapping for key in +hash, returning the fresh hash table.

See also the caveat concerning mutable keys above.

procedure

(hash-clear! hash)  void?

  hash : (and/c hash? (not/c immutable?))
Removes all mappings from hash.

If hash is not an impersonator, then all mappings are +removed in constant time. If hash is an impersonator, +then each key is removed one-by-one using hash-remove!.

See also the caveats concerning concurrent modification and the caveat concerning mutable keys above.

procedure

(hash-clear hash)  (and/c hash? immutable?)

  hash : (and/c hash? immutable?)
Functionally removes all mappings from hash.

If hash is not a chaperone, then clearing is +equivalent to creating a new hash table, and the operation is +performed in constant time. If hash is a chaperone, +then each key is removed one-by-one using hash-remove.

procedure

(hash-copy-clear hash [#:kind kind])  hash?

  hash : hash?
  kind : (or/c #f 'immutable 'mutable 'weak 'ephemeron) = #f
Produces an empty hash table with the same key-comparison +procedure as hash, with either the given kind +or the same kind as the given hash.

If kind is not supplied or #f, produces a hash +table of the same kind and mutability as the given hash. +If kind is 'immutable, 'mutable, +'weak, or 'ephemeron, produces a table that’s +immutable, mutable with strongly-held keys, mutable with +weakly-held keys, or mutable with ephemeron-held keys +respectively.

Changed in version 8.5.0.2 of package base: Added the kind argument.

procedure

(hash-map hash proc [try-order?])  (listof any/c)

  hash : hash?
  proc : (any/c any/c . -> . any/c)
  try-order? : any/c = #f
Applies the procedure proc to each element in +hash in an unspecified order, accumulating the results +into a list. The procedure proc is called each time with a +key and its value, and the procedure’s individual results appear in +order in the result list.

If a hash table is extended with new keys (either through +proc or by another thread) while a hash-map or +hash-for-each traversal is in process, arbitrary key–value +pairs can be dropped or duplicated in the traversal. Key mappings can +be deleted or remapped (by any thread) with no adverse affects; the +change does not affect a traversal if the key has been seen already, +otherwise the traversal skips a deleted key or uses the remapped key’s +new value.

See also the caveats concerning concurrent modification above.

If try-order? is true, then the order of keys and values +passed to proc is normalized under certain +circumstances—including when every key is one of the following and +with the following order (earlier bullets before later):

Changed in version 6.3 of package base: Added the try-order? argument.
Changed in version 7.1.0.7: Added guarantees for try-order?.

procedure

(hash-map/copy hash proc [#:kind kind])  hash?

  hash : hash?
  proc : (any/c any/c . -> . (values any/c any/c))
  kind : (or/c #f 'immutable 'mutable 'weak 'ephemeron) = #f
Applies the procedure proc to each element in +hash in an unspecified order, accumulating the results +into a new hash with the same key-comparison procedure as +hash, with either the given kind or the same +kind as the given hash.

If kind is not supplied or #f, produces a hash +table of the same kind and mutability as the given hash. +If kind is 'immutable, 'mutable, +'weak, or 'ephemeron, produces a table that’s +immutable, mutable with strongly-held keys, mutable with +weakly-held keys, or mutable with ephemeron-held keys +respectively.

Examples:
> (hash-map/copy #hash((a . "apple") (b . "banana"))
                 (lambda (k v) (values k (string-upcase v))))

'#hash((a . "APPLE") (b . "BANANA"))

> (define frozen-capital
    (hash-map/copy (make-hash '((a . "apple") (b . "banana")))
                   (lambda (k v) (values k (string-upcase v)))
                   #:kind 'immutable))
> frozen-capital

'#hash((a . "APPLE") (b . "BANANA"))

> (immutable? frozen-capital)

#t

Added in version 8.5.0.2 of package base.

procedure

(hash-keys hash [try-order?])  (listof any/c)

  hash : hash?
  try-order? : any/c = #f
Returns a list of the keys of hash in an unspecified order.

If try-order? is true, then the order of keys is normalized under +certain circumstances. See hash-map for further explanations on +try-order? and on information about modifying hash during +hash-keys.

Changed in version 8.3.0.11 of package base: Added the try-order? argument.

procedure

(hash-values hash [try-order?])  (listof any/c)

  hash : hash?
  try-order? : any/c = #f
Returns a list of the values of hash in an unspecified order.

If try-order? is true, then the order of values is normalized under +certain circumstances, based on the ordering of the associated keys. +See hash-map for further explanations on try-order? and on +information about modifying hash during +hash-values.

Changed in version 8.3.0.11 of package base: Added the try-order? argument.

procedure

(hash->list hash [try-order?])  (listof (cons/c any/c any/c))

  hash : hash?
  try-order? : any/c = #f
Returns a list of the key–value pairs of hash in an unspecified order.

If try-order? is true, then the order of keys and values is normalized +under certain circumstances. See hash-map for further explanations on +try-order? and on information about modifying hash during +hash->list.

Changed in version 8.3.0.11 of package base: Added the try-order? argument.

procedure

(hash-keys-subset? hash1 hash2)  boolean?

  hash1 : hash?
  hash2 : hash?
Returns #t if the keys of hash1 are a subset of or +the same as the keys of hash2. The hash tables must both use +the same key-comparison function (equal?, +equal-always?, eqv?, or eq?), otherwise the +exn:fail:contract exception is raised.

Using hash-keys-subset? on immutable hash tables can be much +faster than iterating through the keys of hash1 to make sure +that each is in hash2.

Added in version 6.5.0.8 of package base.

procedure

(hash-for-each hash proc [try-order?])  void?

  hash : hash?
  proc : (any/c any/c . -> . any)
  try-order? : any/c = #f
Applies proc to each element in hash (for the +side-effects of proc) in an unspecified order. The procedure +proc is called each time with a key and its value.

See hash-map for information about try-order? and +about modifying hash within proc. +

Changed in version 6.3 of package base: Added the try-order? argument.
Changed in version 7.1.0.7: Added guarantees for try-order?.

procedure

(hash-count hash)  exact-nonnegative-integer?

  hash : hash?
Returns the number of keys mapped by hash.

For the CS implementation of Racket, the result is always +computed in constant time and atomically. For the BC implementation +of Racket, the result is computed in constant time and atomically only if +hash does not retain keys weakly or like an ephemeron, +otherwise, a traversal is required to count the keys.

procedure

(hash-empty? hash)  boolean?

  hash : hash?
Equivalent to (zero? (hash-count hash)).

procedure

(hash-iterate-first hash)

  (or/c #f exact-nonnegative-integer?)
  hash : hash?
Returns #f if hash contains no elements, otherwise +it returns an integer that is an index to the first element in the hash +table; “first” refers to an unspecified ordering of the table +elements, and the index values are not necessarily consecutive +integers.

For a mutable hash, this index is guaranteed to refer to the +first item only as long as no items are added to or removed from +hash. More generally, an index is guaranteed to be a +valid hash index for a given hash table only as long it +comes from hash-iterate-first or hash-iterate-next, +and only as long as the hash table is not modified. In the case of a +hash table with weakly held keys or keys held like ephemerons, +the hash table can be implicitly modified by the garbage collector +(see Garbage Collection) when it discovers that the key is not +reachable.

procedure

(hash-iterate-next hash pos)

  (or/c #f exact-nonnegative-integer?)
  hash : hash?
  pos : exact-nonnegative-integer?
Returns either an integer that is an index to the element in +hash after the element indexed by pos (which is not +necessarily one more than pos) or #f if pos +refers to the last element in hash.

If pos is not a valid hash index of hash, +then the result may be #f or it may be the next later index +that remains valid. The latter result is guaranteed if a hash table +has been modified only by the removal of keys.

Changed in version 7.0.0.10 of package base: Handle an invalid index by returning #f +instead of raising exn:fail:contract.

procedure

(hash-iterate-key hash pos)  any/c

  hash : hash?
  pos : exact-nonnegative-integer?

procedure

(hash-iterate-key hash pos bad-index-v)  any/c

  hash : hash?
  pos : exact-nonnegative-integer?
  bad-index-v : any/c
Returns the key for the element in hash at index +pos.

If pos is not a valid hash index for hash, +the result is bad-index-v if provided, otherwise the +exn:fail:contract exception is raised.

Changed in version 7.0.0.10 of package base: Added the optional bad-index-v argument.

procedure

(hash-iterate-value hash pos)  any

  hash : hash?
  pos : exact-nonnegative-integer?

procedure

(hash-iterate-value hash pos bad-index-v)  any

  hash : hash?
  pos : exact-nonnegative-integer?
  bad-index-v : any/c
Returns the value for the element in hash at index +pos.

If pos is not a valid hash index for hash, +the result is bad-index-v if provided, otherwise the +exn:fail:contract exception is raised.

Changed in version 7.0.0.10 of package base: Added the optional bad-index-v argument.

procedure

(hash-iterate-pair hash pos)  (cons any/c any/c)

  hash : hash?
  pos : exact-nonnegative-integer?

procedure

(hash-iterate-pair hash pos bad-index-v)  (cons any/c any/c)

  hash : hash?
  pos : exact-nonnegative-integer?
  bad-index-v : any/c
Returns a pair containing the key and value for the element +in hash at index pos.

If pos is not a valid hash index for hash, +the result is (cons bad-index-v bad-index-v) if +bad-index-v is provided, otherwise the +exn:fail:contract exception is raised.

Added in version 6.4.0.5 of package base.
Changed in version 7.0.0.10: Added the optional bad-index-v argument.

procedure

(hash-iterate-key+value hash pos)  
any/c any/c
  hash : hash?
  pos : exact-nonnegative-integer?

procedure

(hash-iterate-key+value hash    
  pos    
  bad-index-v)  
any/c any/c
  hash : hash?
  pos : exact-nonnegative-integer?
  bad-index-v : any/c
Returns the key and value for the element in hash at index +pos.

If pos is not a valid hash index for hash, +the result is (values bad-index-v bad-index-v) if +bad-index-v is provided, otherwise the +exn:fail:contract exception is raised.

Added in version 6.4.0.5 of package base.
Changed in version 7.0.0.10: Added the optional bad-index-v argument.

procedure

(hash-copy hash)  (and/c hash? (not/c immutable?))

  hash : hash?
Returns a mutable hash table with the same mappings, same +key-comparison mode, and same key-holding strength as hash.

4.15.1 Additional Hash Table Functions

 (require racket/hash) package: base
The bindings documented in this section are provided by the racket/hash library, not racket/base or racket.

procedure

(hash-union h0 
  h ... 
  [#:combine combine 
  #:combine/key combine/key]) 
  (and/c hash? immutable?)
  h0 : (and/c hash? immutable?)
  h : hash?
  combine : (-> any/c any/c any/c)
   = (lambda _ (error 'hash-union ....))
  combine/key : (-> any/c any/c any/c any/c)
   = (lambda (k a b) (combine a b))
Computes the union of h0 with each hash table h by functional +update, adding each element of each h to h0 in turn. For each +key k and value v, if a mapping from k to some value +v0 already exists, it is replaced with a mapping from k to +(combine/key k v0 v).

Examples:
> (hash-union (make-immutable-hash '([1 . one]))
              (make-immutable-hash '([2 . two]))
              (make-immutable-hash '([3 . three])))

'#hash((1 . one) (2 . two) (3 . three))

> (hash-union (make-immutable-hash '([1    one uno]  [2    two dos]))
              (make-immutable-hash '([1    eins un]  [2    zwei deux]))
              #:combine/key (lambda (k v1 v2) (append v1 v2)))

'#hash((1 . (one uno eins un)) (2 . (two dos zwei deux)))

procedure

(hash-union! h0    
  h ...    
  [#:combine combine    
  #:combine/key combine/key])  void?
  h0 : (and/c hash? (not/c immutable?))
  h : hash?
  combine : (-> any/c any/c any/c)
   = (lambda _ (error 'hash-union ....))
  combine/key : (-> any/c any/c any/c any/c)
   = (lambda (k a b) (combine a b))
Computes the union of h0 with each hash table h by mutable +update, adding each element of each h to h0 in turn. For each +key k and value v, if a mapping from k to some value +v0 already exists, it is replaced with a mapping from k to +(combine/key k v0 v).

Examples:
> (define h (make-hash))
> h

'#hash()

> (hash-union! h (make-immutable-hash '([1    one uno]  [2    two dos])))
> h

'#hash((1 . (one uno)) (2 . (two dos)))

> (hash-union! h
               (make-immutable-hash '([1    eins un]  [2    zwei deux]))
               #:combine/key (lambda (k v1 v2) (append v1 v2)))
> h

'#hash((1 . (one uno eins un)) (2 . (two dos zwei deux)))

procedure

(hash-intersect h0 
  h ... 
  [#:combine combine 
  #:combine/key combine/key]) 
  (and/c hash? immutable?)
  h0 : (and/c hash? immutable?)
  h : hash?
  combine : (-> any/c any/c any/c)
   = (lambda _ (error 'hash-intersect ...))
  combine/key : (-> any/c any/c any/c any/c)
   = (lambda (k a b) (combine a b))
Constructs the hash table which is the intersection of h0 +with every hash table h. In the resulting hash table, a key +k is mapped to a combination of the values to which +k is mapped in each of the hash tables. The final values are +computed by stepwise combination of the values appearing in each of +the hash tables by applying (combine/key k v vi) or +(combine v vi), where vi is the value to which +k is mapped in the i-th hash table h, and +v is the accumulation of the values from the previous steps. +The comparison predicate of the first argument (eq?, +eqv?, equal-always?, equal?) determines the +one for the result.

Examples:
> (hash-intersect (make-immutable-hash '((a . 1) (b . 2) (c . 3)))
                  (make-immutable-hash '((a . 4) (b . 5)))
                  #:combine +)

'#hash((a . 5) (b . 7))

> (hash-intersect (make-immutable-hash '((a . 1) (b . 2) (c . 3)))
                  (make-immutable-hash '((a . 4) (b . 5)))
                  #:combine/key
                  (lambda (k v1 v2) (if (eq? k 'a) (+ v1 v2) (- v1 v2))))

'#hash((a . 5) (b . -3))

Added in version 7.9.0.1 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/icons.css b/clones/docs.racket-lang.org/reference/icons.css new file mode 100644 index 00000000..4923ee0f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/icons.css @@ -0,0 +1,8 @@ +.imageleft { + float: left; + margin-right: 0.3em; +} + +.imageleft img { + width: 1.5em; +} diff --git a/clones/docs.racket-lang.org/reference/if.html b/clones/docs.racket-lang.org/reference/if.html new file mode 100644 index 00000000..da59e635 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/if.html @@ -0,0 +1,42 @@ + +3.12 Conditionals: if, cond, and, and or
On this page:
if
cond
else
=>
and
or

3.12 Conditionals: if, cond, and, and or

+Conditionals in The Racket Guide introduces conditionals.

syntax

(if test-expr then-expr else-expr)

Evaluates test-expr. If it produces any value other than +#f, then then-expr is evaluated, and its results are +the result for the if form. Otherwise, else-expr is +evaluated, and its results are the result for the if +form. The then-expr and else-expr are in tail +position with respect to the if form.

Examples:
> (if (positive? -5) (error "doesn't get here") 2)

2

> (if (positive? 5) 1 (error "doesn't get here"))

1

> (if 'we-have-no-bananas "yes" "no")

"yes"

syntax

(cond cond-clause ...)

 
cond-clause = [test-expr then-body ...+]
  | [else then-body ...+]
  | [test-expr => proc-expr]
  | [test-expr]

A cond-clause that starts with else must be the last +cond-clause.

If no cond-clauses are present, the result is #<void>.

If only a [else then-body ...+] is present, then the +then-bodys are evaluated. The results from all but the last +then-body are ignored. The results of the last +then-body, which is in tail position with respect to the +cond form, are the results for the whole cond +form.

Otherwise, the first test-expr is evaluated. If it produces +#f, then the result is the same as a cond form with +the remaining cond-clauses, in tail position with respect to +the original cond form. Otherwise, evaluation depends on the +form of the cond-clause:

[test-expr then-body ...+]

The then-bodys are +evaluated in order, and the results from all but the last +then-body are ignored. The results of the last +then-body, which is in tail position with respect to the +cond form, provides the result for the whole cond +form.

[test-expr => proc-expr]

The proc-expr is +evaluated, and it must produce a procedure that accepts one argument, +otherwise the exn:fail:contract exception is raised. The procedure is applied +to the result of test-expr in tail position with respect to +the cond expression.

[test-expr]

The result of the test-expr is +returned as the result of the cond form. The +test-expr is not in tail position.

Examples:
> (cond)
> (cond
    [else 5])

5

> (cond
   [(positive? -5) (error "doesn't get here")]
   [(zero? -5) (error "doesn't get here, either")]
   [(positive? 5) 'here])

'here

> (cond
   [(member 2 '(1 2 3)) => (lambda (l) (map - l))])

'(-2 -3)

> (cond
   [(member 2 '(1 2 3))])

'(2 3)

syntax

else

Recognized specially within forms like cond. An +else form as an expression is a syntax error.

syntax

=>

Recognized specially within forms like cond. A +=> form as an expression is a syntax error.

syntax

(and expr ...)

If no exprs are provided, then result is #t.

If a single expr is provided, then it is in tail position, so +the results of the and expression are the results of the +expr.

Otherwise, the first expr is evaluated. If it produces +#f, the result of the and expression is +#f. Otherwise, the result is the same as an and +expression with the remaining exprs in tail position with +respect to the original and form.

Examples:
> (and)

#t

> (and 1)

1

> (and (values 1 2))

1

2

> (and #f (error "doesn't get here"))

#f

> (and #t 5)

5

syntax

(or expr ...)

If no exprs are provided, then result is #f.

If a single expr is provided, then it is in tail position, so +the results of the or expression are the results of the +expr.

Otherwise, the first expr is evaluated. If it produces a +value other than #f, that result is the result of the +or expression. Otherwise, the result is the same as an +or expression with the remaining exprs in tail +position with respect to the original or form.

Examples:
> (or)

#f

> (or 1)

1

> (or (values 1 2))

1

2

> (or 5 (error "doesn't get here"))

5

> (or #f 5)

5

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/implementations.html b/clones/docs.racket-lang.org/reference/implementations.html new file mode 100644 index 00000000..9316fb4e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/implementations.html @@ -0,0 +1,26 @@ + +1.5 Implementations

1.5 Implementations

The definition of Racket aims for determinism and independence from +its implementation. Nevertheless, some details inevitably vary with +the implementation. Racket currently has two main implementations:

  • The CS implementation is the default implementation +as of Racket version 8.0. This variant is called “CS” because +it uses Chez Scheme as its core compiler and runtime system.

    The CS implementation typically provides the best performance +for Racket programs. Compiled Racket CS code in a +".zo" file normally contains machine code that is +specific to an operating system and architecture.

  • The BC implementation was the default implementation +up until version 7.9. The “BC” label stands for “before +Chez” or “bytecode.”

    Compiled Racket BC code in a ".zo" file normally +contains platform-independent bytecode that is further compiled +to machine code “just in time” as the code is loaded.

    Racket BC has two variants: 3m and CGC. +The difference is the garbage collection implementation, +where 3m uses a garbage collector that moves objects in memory +(an effect that is visible to foreign libraries, for example) +and keeps precise track of allocated objects, while CGC uses a +“conservative” collector that requires less cooperation from +an embedding foreign environment. The 3m subvariant tends to +perform much better than CGC, and it became the default +variant in version 370 (which would be v3.7 in the current +versioning convention).

Most Racket programs run the same in all implementation variants, but some Racket +features are available only on some implementation variants, and the +interaction of Racket and foreign functions is significantly different +across the variants. Use system-type to get information about +the current running implementation.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/include.html b/clones/docs.racket-lang.org/reference/include.html new file mode 100644 index 00000000..4827e340 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/include.html @@ -0,0 +1,28 @@ + +12.11 File Inclusion

12.11 File Inclusion

The bindings documented in this section are provided by the racket/include and racket libraries, but not racket/base.

syntax

(include path-spec)

 
path-spec = string
  | (file string)
  | (lib string ...+)
Inlines the syntax in the file designated by path-spec in +place of the include expression.

A path-spec resembles a subset of the mod-path +forms for require, but it specifies a file whose content need +not be a module. That is, string refers to a file using a +platform-independent relative path, (file string) refers to a +file using platform-specific notation, and (lib string ...) +refers to a file within a collection.

If path-spec specifies a relative path, the path is resolved +relative to the source for the include expression, if that +source is a complete path string. If the source is not a complete path +string, then path-spec is resolved relative to +(current-load-relative-directory) if it is not #f, +or relative to (current-directory) otherwise.

The included syntax is given the lexical context of the +include expression, while the included syntax’s source +location refers to its actual source.

syntax

(include-at/relative-to context source path-spec)

Like include, except that the lexical context of +context is used for the included syntax, and a relative +path-spec is resolved with respect to the source of +source. The context and source elements are +otherwise discarded by expansion.

syntax

(include/reader path-spec reader-expr)

Like include, except that the procedure produced by the +expression reader-expr is used to read the included file, +instead of read-syntax.

The reader-expr is evaluated at expansion time in the +transformer environment. Since it serves as a replacement for +read-syntax, the expression’s value should be a procedure +that consumes two inputs—a string representing the source and an +input port—and produces a syntax object or eof. The +procedure will be called repeatedly until it produces eof.

The syntax objects returned by the procedure should have source +location information, but usually no lexical context; any lexical +context in the syntax objects will be ignored.

syntax

(include-at/relative-to/reader context source path-spec reader-expr)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/index.html b/clones/docs.racket-lang.org/reference/index.html new file mode 100644 index 00000000..6aa9d2db --- /dev/null +++ b/clones/docs.racket-lang.org/reference/index.html @@ -0,0 +1,10 @@ + +The Racket Reference
8.6

The Racket Reference

Matthew Flatt
and PLT

This manual defines the core Racket language and describes its +most prominent libraries. The companion manual The Racket Guide provides a +friendlier (though less precise and less complete) overview of the +language.

The source of this manual is available on +GitHub.

Unless otherwise noted, the bindings defined in this manual are +exported by the racket/base and racket +languages.

The racket/base library is much smaller than +the racket library and will typically load faster.

The racket library combines +racket/base, racket/bool, racket/bytes, racket/class, racket/cmdline, racket/contract, racket/dict, racket/file, racket/format, racket/function, racket/future, racket/include, racket/keyword, racket/list, racket/local, racket/match, racket/math, racket/path, racket/place, racket/port, racket/pretty, racket/promise, racket/sequence, racket/set, racket/shared, racket/stream, racket/string, racket/symbol, racket/system, racket/tcp, racket/udp, racket/unit, and racket/vector.

    1 Language Model

      1.1 Evaluation Model

        1.1.1 Sub-expression Evaluation and Continuations

        1.1.2 Tail Position

        1.1.3 Multiple Return Values

        1.1.4 Top-Level Variables

        1.1.5 Objects and Imperative Update

        1.1.6 Garbage Collection

        1.1.7 Procedure Applications and Local Variables

        1.1.8 Variables and Locations

        1.1.9 Modules and Module-Level Variables

          1.1.9.1 Phases

          1.1.9.2 The Separate Compilation Guarantee

          1.1.9.3 Cross-Phase Persistent Modules

          1.1.9.4 Module Redeclarations

          1.1.9.5 Submodules

        1.1.10 Continuation Frames and Marks

        1.1.11 Prompts, Delimited Continuations, and Barriers

        1.1.12 Threads

        1.1.13 Parameters

        1.1.14 Exceptions

        1.1.15 Custodians

      1.2 Syntax Model

        1.2.1 Identifiers, Binding, and Scopes

        1.2.2 Syntax Objects

        1.2.3 Expansion (Parsing)

          1.2.3.1 Fully Expanded Programs

          1.2.3.2 Expansion Steps

          1.2.3.3 Expansion Context

          1.2.3.4 Introducing Bindings

          1.2.3.5 Transformer Bindings

          1.2.3.6 Local Binding Context

          1.2.3.7 Partial Expansion

          1.2.3.8 Internal Definitions

          1.2.3.9 Module Expansion, Phases, and Visits

          1.2.3.10 Macro-Introduced Bindings

        1.2.4 Compilation

        1.2.5 Namespaces

        1.2.6 Inferred Value Names

        1.2.7 Cross-Phase Persistent Module Declarations

      1.3 The Reader

      1.4 The Printer

      1.5 Implementations

    2 Notation for Documentation

      2.1 Notation for Module Documentation

      2.2 Notation for Syntactic Form Documentation

      2.3 Notation for Function Documentation

      2.4 Notation for Structure Type Documentation

      2.5 Notation for Parameter Documentation

      2.6 Notation for Other Documentation

    3 Syntactic Forms

      3.1 Modules: module, module*, ...

      3.2 Importing and Exporting: require and provide

        3.2.1 Additional require Forms

        3.2.2 Additional provide Forms

      3.3 Literals: quote and #%datum

      3.4 Expression Wrapper: #%expression

      3.5 Variable References and #%top

      3.6 Locations: #%variable-reference

      3.7 Procedure Applications and #%app

      3.8 Procedure Expressions: lambda and case-lambda

      3.9 Local Binding: let, let*, letrec, ...

      3.10 Local Definitions: local

      3.11 Constructing Graphs: shared

      3.12 Conditionals: if, cond, and, and or

      3.13 Dispatch: case

      3.14 Definitions: define, define-syntax, ...

        3.14.1 require Macros

        3.14.2 provide Macros

      3.15 Sequencing: begin, begin0, and begin-for-syntax

      3.16 Guarded Evaluation: when and unless

      3.17 Assignment: set! and set!-values

      3.18 Iterations and Comprehensions: for, for/list, ...

        3.18.1 Iteration and Comprehension Forms

        3.18.2 Deriving New Iteration Forms

        3.18.3 Do Loops

      3.19 Continuation Marks: with-continuation-mark

      3.20 Quasiquoting: quasiquote, unquote, and unquote-splicing

      3.21 Syntax Quoting: quote-syntax

      3.22 Interaction Wrapper: #%top-interaction

      3.23 Blocks: block

      3.24 Internal-Definition Limiting: #%stratified-body

      3.25 Performance Hints: begin-encourage-inline

      3.26 Importing Modules Lazily: lazy-require

    4 Datatypes

      4.1 Equality

        4.1.1 Object Identity and Comparisons

        4.1.2 Equality and Hashing

        4.1.3 Implementing Equality for Custom Types

        4.1.4 Honest Custom Equality

      4.2 Booleans

        4.2.1 Boolean Aliases

      4.3 Numbers

        4.3.1 Number Types

        4.3.2 Generic Numerics

          4.3.2.1 Arithmetic

          4.3.2.2 Number Comparison

          4.3.2.3 Powers and Roots

          4.3.2.4 Trigonometric Functions

          4.3.2.5 Complex Numbers

          4.3.2.6 Bitwise Operations

          4.3.2.7 Random Numbers

          4.3.2.8 Other Randomness Utilities

          4.3.2.9 Number–String Conversions

          4.3.2.10 Extra Constants and Functions

        4.3.3 Flonums

          4.3.3.1 Flonum Arithmetic

          4.3.3.2 Flonum Vectors

        4.3.4 Fixnums

          4.3.4.1 Fixnum Arithmetic

          4.3.4.2 Fixnum Vectors

          4.3.4.3 Fixnum Range

        4.3.5 Extflonums

          4.3.5.1 Extflonum Arithmetic

          4.3.5.2 Extflonum Constants

          4.3.5.3 Extflonum Vectors

          4.3.5.4 Extflonum Byte Strings

      4.4 Strings

        4.4.1 String Constructors, Selectors, and Mutators

        4.4.2 String Comparisons

        4.4.3 String Conversions

        4.4.4 Locale-Specific String Operations

        4.4.5 Additional String Functions

        4.4.6 Converting Values to Strings

      4.5 Byte Strings

        4.5.1 Byte String Constructors, Selectors, and Mutators

        4.5.2 Byte String Comparisons

        4.5.3 Bytes to/from Characters, Decoding and Encoding

        4.5.4 Bytes to Bytes Encoding Conversion

        4.5.5 Additional Byte String Functions

      4.6 Characters

        4.6.1 Characters and Scalar Values

        4.6.2 Character Comparisons

        4.6.3 Classifications

        4.6.4 Character Conversions

      4.7 Symbols

        4.7.1 Additional Symbol Functions

      4.8 Regular Expressions

        4.8.1 Regexp Syntax

        4.8.2 Additional Syntactic Constraints

        4.8.3 Regexp Constructors

        4.8.4 Regexp Matching

        4.8.5 Regexp Splitting

        4.8.6 Regexp Substitution

      4.9 Keywords

        4.9.1 Additional Keyword Functions

      4.10 Pairs and Lists

        4.10.1 Pair Constructors and Selectors

        4.10.2 List Operations

        4.10.3 List Iteration

        4.10.4 List Filtering

        4.10.5 List Searching

        4.10.6 Pair Accessor Shorthands

        4.10.7 Additional List Functions and Synonyms

        4.10.8 Immutable Cyclic Data

      4.11 Mutable Pairs and Lists

        4.11.1 Mutable Pair Constructors and Selectors

      4.12 Vectors

        4.12.1 Additional Vector Functions

      4.13 Stencil Vectors

      4.14 Boxes

      4.15 Hash Tables

        4.15.1 Additional Hash Table Functions

      4.16 Sequences and Streams

        4.16.1 Sequences

          4.16.1.1 Sequence Predicate and Constructors

          4.16.1.2 Sequence Conversion

          4.16.1.3 Additional Sequence Operations

            4.16.1.3.1 Additional Sequence Constructors

        4.16.2 Streams

        4.16.3 Generators

      4.17 Dictionaries

        4.17.1 Dictionary Predicates and Contracts

        4.17.2 Generic Dictionary Interface

          4.17.2.1 Primitive Dictionary Methods

          4.17.2.2 Derived Dictionary Methods

        4.17.3 Dictionary Sequences

        4.17.4 Contracted Dictionaries

        4.17.5 Custom Hash Tables

        4.17.6 Passing keyword arguments in dictionaries

      4.18 Sets

        4.18.1 Hash Sets

        4.18.2 Set Predicates and Contracts

        4.18.3 Generic Set Interface

          4.18.3.1 Set Methods

        4.18.4 Custom Hash Sets

      4.19 Procedures

        4.19.1 Keywords and Arity

        4.19.2 Reflecting on Primitives

        4.19.3 Additional Higher-Order Functions

      4.20 Void

      4.21 Undefined

    5 Structures

      5.1 Defining Structure Types: struct

      5.2 Creating Structure Types

      5.3 Structure Type Properties

      5.4 Generic Interfaces

      5.5 Copying and Updating Structures

      5.6 Structure Utilities

        5.6.1 Additional Structure Utilities

      5.7 Structure Type Transformer Binding

    6 Classes and Objects

      6.1 Creating Interfaces

      6.2 Creating Classes

        6.2.1 Initialization Variables

        6.2.2 Fields

        6.2.3 Methods

          6.2.3.1 Method Definitions

          6.2.3.2 Inherited and Superclass Methods

          6.2.3.3 Internal and External Names

      6.3 Creating Objects

      6.4 Field and Method Access

        6.4.1 Methods

        6.4.2 Fields

        6.4.3 Generics

      6.5 Mixins

      6.6 Traits

      6.7 Object and Class Contracts

      6.8 Object Equality and Hashing

      6.9 Object Serialization

      6.10 Object Printing

      6.11 Object, Class, and Interface Utilities

      6.12 Surrogates

    7 Units

      7.1 Creating Units

      7.2 Invoking Units

      7.3 Linking Units and Creating Compound Units

      7.4 Inferred Linking

      7.5 Generating A Unit from Context

      7.6 Structural Matching

      7.7 Extending the Syntax of Signatures

      7.8 Unit Utilities

      7.9 Unit Contracts

      7.10 Single-Unit Modules

      7.11 Single-Signature Modules

      7.12 Transformer Helpers

    8 Contracts

      8.1 Data-structure Contracts

      8.2 Function Contracts

      8.3 Parametric Contracts

      8.4 Lazy Data-structure Contracts

      8.5 Structure Type Property Contracts

      8.6 Attaching Contracts to Values

        8.6.1 Nested Contract Boundaries

        8.6.2 Low-level Contract Boundaries

      8.7 Building New Contract Combinators

        8.7.1 Blame Objects

        8.7.2 Contracts as structs

        8.7.3 Obligation Information in Check Syntax

        8.7.4 Utilities for Building New Combinators

      8.8 Contract Utilities

      8.9 racket/contract/base

      8.10 Collapsible Contracts

      8.11 Legacy Contracts

      8.12 Random generation

    9 Pattern Matching

      9.1 Additional Matching Forms

      9.2 Extending match

      9.3 Library Extensions

    10 Control Flow

      10.1 Multiple Values

      10.2 Exceptions

        10.2.1 Error Message Conventions

        10.2.2 Raising Exceptions

        10.2.3 Handling Exceptions

        10.2.4 Configuring Default Handling

        10.2.5 Built-in Exception Types

        10.2.6 Additional Exception Functions

        10.2.7 Realms and Error Message Adjusters

      10.3 Delayed Evaluation

        10.3.1 Additional Promise Kinds

      10.4 Continuations

        10.4.1 Additional Control Operators

      10.5 Continuation Marks

      10.6 Breaks

      10.7 Exiting

      10.8 Unreachable Expressions

        10.8.1 Customized Unreachable Reporting

    11 Concurrency and Parallelism

      11.1 Threads

        11.1.1 Creating Threads

        11.1.2 Suspending, Resuming, and Killing Threads

        11.1.3 Synchronizing Thread State

        11.1.4 Thread Mailboxes

      11.2 Synchronization

        11.2.1 Events

        11.2.2 Channels

        11.2.3 Semaphores

        11.2.4 Buffered Asynchronous Channels

          11.2.4.1 Creating and Using Asynchronous Channels

          11.2.4.2 Contracts and Impersonators on Asynchronous Channels

      11.3 Thread-Local Storage

        11.3.1 Thread Cells

        11.3.2 Parameters

      11.4 Futures

        11.4.1 Creating and Touching Futures

        11.4.2 Future Semaphores

        11.4.3 Future Performance Logging

      11.5 Places

        11.5.1 Using Places

        11.5.2 Syntactic Support for Using Places

        11.5.3 Places Logging

      11.6 Engines

      11.7 Machine Memory Order

    12 Macros

      12.1 Pattern-Based Syntax Matching

      12.2 Syntax Object Content

        12.2.1 Syntax Object Source Locations

      12.3 Syntax Object Bindings

      12.4 Syntax Transformers

        12.4.1 require Transformers

        12.4.2 provide Transformers

        12.4.3 Keyword-Argument Conversion Introspection

        12.4.4 Portal Syntax Bindings

      12.5 Syntax Parameters

        12.5.1 Syntax Parameter Inspection

      12.6 Local Binding with Splicing Body

      12.7 Syntax Object Properties

      12.8 Syntax Taints

      12.9 Expanding Top-Level Forms

        12.9.1 Information on Expanded Modules

      12.10 Serializing Syntax

      12.11 File Inclusion

      12.12 Syntax Utilities

        12.12.1 Creating formatted identifiers

        12.12.2 Pattern variables

        12.12.3 Error reporting

        12.12.4 Recording disappeared uses

        12.12.5 Miscellaneous utilities

      12.13 Phase and Space Utilities

    13 Input and Output

      13.1 Ports

        13.1.1 Encodings and Locales

        13.1.2 Managing Ports

        13.1.3 Port Buffers and Positions

        13.1.4 Counting Positions, Lines, and Columns

        13.1.5 File Ports

        13.1.6 String Ports

        13.1.7 Pipes

        13.1.8 Structures as Ports

        13.1.9 Custom Ports

        13.1.10 More Port Constructors, Procedures, and Events

          13.1.10.1 Port String and List Conversions

          13.1.10.2 Creating Ports

          13.1.10.3 Port Events

          13.1.10.4 Copying Streams

      13.2 Byte and String Input

      13.3 Byte and String Output

      13.4 Reading

      13.5 Writing

      13.6 Pretty Printing

        13.6.1 Basic Pretty-Print Options

        13.6.2 Per-Symbol Special Printing

        13.6.3 Line-Output Hook

        13.6.4 Value Output Hook

        13.6.5 Additional Custom-Output Support

      13.7 Reader Extension

        13.7.1 Readtables

        13.7.2 Reader-Extension Procedures

        13.7.3 Special Comments

      13.8 Printer Extension

      13.9 Serialization

      13.10 Fast-Load Serialization

      13.11 Cryptographic Hashing

    14 Reflection and Security

      14.1 Namespaces

      14.2 Evaluation and Compilation

      14.3 The racket/load Language

      14.4 Module Names and Loading

        14.4.1 Resolving Module Names

        14.4.2 Compiled Modules and References

        14.4.3 Dynamic Module Access

        14.4.4 Module Cache

      14.5 Impersonators and Chaperones

        14.5.1 Impersonator Constructors

        14.5.2 Chaperone Constructors

        14.5.3 Impersonator Properties

      14.6 Security Guards

      14.7 Custodians

      14.8 Thread Groups

      14.9 Structure Inspectors

      14.10 Code Inspectors

      14.11 Plumbers

      14.12 Sandboxed Evaluation

        14.12.1 Security Considerations

        14.12.2 Customizing Evaluators

        14.12.3 Interacting with Evaluators

        14.12.4 Miscellaneous

      14.13 The racket/repl Library

      14.14 Linklets and the Core Compiler

    15 Operating System

      15.1 Paths

        15.1.1 Manipulating Paths

        15.1.2 More Path Utilities

        15.1.3 Unix and Mac OS Paths

          15.1.3.1 Unix Path Representation

        15.1.4 Windows Paths

          15.1.4.1 Windows Path Representation

      15.2 Filesystem

        15.2.1 Locating Paths

        15.2.2 Files

        15.2.3 Directories

        15.2.4 Detecting Filesystem Changes

        15.2.5 Declaring Paths Needed at Run Time

        15.2.6 More File and Directory Utilities

      15.3 Networking

        15.3.1 TCP

        15.3.2 UDP

      15.4 Processes

        15.4.1 Simple Subprocesses

      15.5 Logging

        15.5.1 Creating Loggers

        15.5.2 Logging Events

        15.5.3 Receiving Logged Events

        15.5.4 Additional Logging Functions

      15.6 Time

        15.6.1 Date Utilities

      15.7 Environment Variables

      15.8 Environment and Runtime Information

      15.9 Command-Line Parsing

      15.10 Additional Operating System Functions

    16 Memory Management

      16.1 Weak Boxes

      16.2 Ephemerons

      16.3 Wills and Executors

      16.4 Garbage Collection

      16.5 Phantom Byte Strings

    17 Unsafe Operations

      17.1 Unsafe Numeric Operations

      17.2 Unsafe Character Operations

      17.3 Unsafe Compound-Data Operations

      17.4 Unsafe Extflonum Operations

      17.5 Unsafe Impersonators and Chaperones

      17.6 Unsafe Assertions

      17.7 Unsafe Undefined

    18 Running Racket

      18.1 Running Racket or GRacket

        18.1.1 Initialization

        18.1.2 Exit Status

        18.1.3 Init Libraries

        18.1.4 Command Line

        18.1.5 Language Run-Time Configuration

      18.2 Libraries and Collections

        18.2.1 Collection Search Configuration

        18.2.2 Collection Links

        18.2.3 Collection Paths and Parameters

      18.3 Interactive Help

      18.4 Interaction Configuration

      18.5 Interactive Module Loading

        18.5.1 Entering Modules

        18.5.2 Loading and Reloading Modules

      18.6 Debugging

        18.6.1 Tracing

      18.7 Controlling and Inspecting Compilation

        18.7.1 Compilation Modes

          18.7.1.1 BC Compilation Modes

          18.7.1.2 CS Compilation Modes

        18.7.2 Inspecting Compiler Passes

      18.8 Kernel Forms and Functions

    Bibliography

    Index

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/input-and-output.html b/clones/docs.racket-lang.org/reference/input-and-output.html new file mode 100644 index 00000000..6ee3b1f6 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/input-and-output.html @@ -0,0 +1,2 @@ + +13 Input and Output
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/inspectors.html b/clones/docs.racket-lang.org/reference/inspectors.html new file mode 100644 index 00000000..db6e4d96 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/inspectors.html @@ -0,0 +1,90 @@ + +14.9 Structure Inspectors

14.9 Structure Inspectors

An inspector provides access to structure fields and +structure type information without the normal field accessors and +mutators. (Inspectors are also used to control access to module +bindings; see Code Inspectors.) Inspectors are primarily +intended for use by debuggers.

When a structure type is created, an inspector can be supplied. The +given inspector is not the one that will control the new structure +type; instead, the given inspector’s parent will control the type. By +using the parent of the given inspector, the structure type remains +opaque to “peer” code that cannot access the parent inspector.

The current-inspector parameter determines a default +inspector argument for new structure types. An alternate inspector can +be provided though the #:inspector option of the +struct form (see Defining Structure Types: struct), or +through an optional inspector argument to +make-struct-type.

procedure

(inspector? v)  boolean?

  v : any/c
Returns #t if +v is an inspector, #f otherwise.

procedure

(make-inspector [inspector])  inspector?

  inspector : inspector? = (current-inspector)
Returns a new inspector that is a subinspector of +inspector. Any structure type controlled by the new inspector +is also controlled by its ancestor inspectors, but no other +inspectors.

procedure

(make-sibling-inspector [inspector])  inspector?

  inspector : inspector? = (current-inspector)
Returns a new inspector that is a subinspector of the same inspector +as inspector. That is, inspector and the result +inspector control mutually disjoint sets of structure types.

procedure

(inspector-superior? inspector    
  maybe-subinspector)  boolean?
  inspector : inspector?
  maybe-subinspector : inspector?
Returns #t if inspector is an ancestor of +maybe-subinspector (and not equal to +maybe-subinspector), #f otherwise.

Added in version 6.5.0.6 of package base.

parameter

(current-inspector)  inspector?

(current-inspector insp)  void?
  insp : inspector?
A parameter that determines the default inspector for newly created +structure types.

procedure

(struct-info v)  
(or/c struct-type? #f) boolean?
  v : any/c
Returns two values:

  • struct-type: a structure type descriptor or #f; +the result is a structure type descriptor of the most specific type +for which v is an instance, and for which the current +inspector has control, or the result is #f if the current +inspector does not control any structure type for which the +struct is an instance.

  • skipped?: #f if the first result corresponds to +the most specific structure type of v, #t otherwise.

Returns eight values that provide information about the structure type + descriptor struct-type, assuming that the type is controlled + by the current inspector:

  • name: the structure type’s name as a symbol;

  • init-field-cnt: the number of fields defined by the +structure type provided to the constructor procedure (not counting +fields created by its ancestor types);

  • auto-field-cnt: the number of fields defined by the +structure type without a counterpart in the constructor procedure +(not counting fields created by its ancestor types);

  • accessor-proc: an accessor procedure for the structure +type, like the one returned by make-struct-type;

  • mutator-proc: a mutator procedure for the structure +type, like the one returned by make-struct-type;

  • immutable-k-list: an immutable list of exact +non-negative integers that correspond to immutable fields for the +structure type;

  • super-type: a structure type descriptor for the +most specific ancestor of the type that is controlled by the +current inspector, or #f if no ancestor is controlled by +the current inspector;

  • skipped?: #f if the seventh result is the +most specific ancestor type or if the type has no supertype, +#t otherwise.

If the type for struct-type is not controlled by the current inspector, +the exn:fail:contract exception is raised.

procedure

(struct-type-sealed? struct-type)  boolean?

  struct-type : struct-type?
Reports whether struct-type has the prop:sealed +structure type property.

Added in version 8.0.0.7 of package base.

procedure

(struct-type-authentic? struct-type)  boolean?

  struct-type : struct-type?
Reports whether struct-type has the prop:authentic +structure type property.

Added in version 8.0.0.7 of package base.

procedure

(struct-type-make-constructor struct-type 
  [constructor-name]) 
  struct-constructor-procedure?
  struct-type : struct-type?
  constructor-name : (or/c symbol? #f) = #f
Returns a constructor procedure to create instances of the type +for struct-type. If constructor-name is not #f, +it is used as the name of the generated constructor procedure. +If the type for struct-type is not +controlled by the current inspector, the +exn:fail:contract exception is raised.

procedure

(struct-type-make-predicate struct-type)  any

  struct-type : any/c
Returns a predicate procedure to recognize instances of the +type for struct-type. If the type for struct-type +is not controlled by the current inspector, the +exn:fail:contract exception is raised.

procedure

(object-name v)  any

  v : any/c
Returns a value for the name of v if v has a name, +#f otherwise. The argument v can be any value, but +only (some) procedures, structures, structure types, +structure type properties, regexp values, +ports, loggers, and prompt tags have names. +See also Inferred Value Names.

If a structure’s type implements the prop:object-name property, +and the value of the prop:object-name property is an integer, then the +corresponding field of the structure is the name of the structure. +Otherwise, the property value must be a procedure, which is called with the +structure as argument, and the result is the name of the structure. +If a structure is a procedure as implemented by one of its +fields (i.e., the prop:procedure property value for the structure’s +type is an integer), then its name is the implementing procedure’s name. +Otherwise, its name matches the name of the structure type that it +instantiates.

The name (if any) of a procedure is a symbol, unless the procedure is +also a structure whose type has the prop:object-name +property, in which case prop:object-name takes precedence. +The procedure-rename function creates a procedure with a +specific name.

The name of a regexp value is a string or byte string. Passing +the string or byte string to regexp, byte-regexp, +pregexp, or byte-pregexp (depending on the kind of +regexp whose name was extracted) produces a value that matches the +same inputs.

The name of a port can be any value, but many tools use a path or +string name as the port’s for (to report source locations, for +example).

The name of a logger is either a symbol or #f.

The name of a prompt tag is either the optional symbol +given to make-continuation-prompt-tag or #f.

Changed in version 7.9.0.13 of package base: Recognize the name of +continuation prompt tags.

A structure type property that allows structure types to customize + the result of object-name applied to their instances. The property value can + be any of the following:

  • A procedure proc of one argument: In this case, +procedure proc receives the structure as an argument, and the result +of proc is the object-name of the structure.

  • An exact, non-negative integer between 0 (inclusive) and the +number of non-automatic fields in the structure type (exclusive, not counting +supertype fields): The integer identifies a field in the structure, and the +field must be designated as immutable. The value of the field is used as the +object-name of the structure.

Added in version 6.2 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/interaction-info.html b/clones/docs.racket-lang.org/reference/interaction-info.html new file mode 100644 index 00000000..30754c05 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/interaction-info.html @@ -0,0 +1,16 @@ + +18.4 Interaction Configuration

18.4 Interaction Configuration

The bindings documented in this section are provided by the racket/interaction-info library, not racket/base or racket.

The racket/interaction-info library provides a way to +register a langauge’s configuration for a +read-eval-print loop and editor.

parameter

(current-interaction-info)

  (or/c #f (vector/c module-path? symbol? any/c))
(current-interaction-info info)  void?
  info : (or/c #f (vector/c module-path? symbol? any/c))
A parameter that provides configuration for a language for use +by interactive development tools, such as a command-line evaluation +prompt with syntax coloring and indentation support. This parameter is +typically set by a configure-runtime module; see also +Language Run-Time Configuration.

Instead of providing configuration information directly, the the +current-interaction-info parameter specifies a module to +load, a exported function to call, and data to pass as an argument to +the exported function. The result of that function should be another +one that accepts two arguments: a symbol a symbol indicating the kind +of information requested (as defined by external tools), and a default +value that normally should be returned if the symbol is not +recognized.

For information on defining a new #lang language, see +syntax/module-reader.

Added in version 8.3.0.2 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/interactive.html b/clones/docs.racket-lang.org/reference/interactive.html new file mode 100644 index 00000000..3041a5d8 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/interactive.html @@ -0,0 +1,38 @@ + +18.5 Interactive Module Loading

18.5 Interactive Module Loading

The racket/rerequire and racket/enter +libraries provide support for loading, reloading, and using modules.

18.5.1 Entering Modules

 (require racket/enter) package: base
The bindings documented in this section are provided by the racket/enter and racket/init libraries, which means that they are available when the Racket executable is started with no command-line arguments. They are not provided by racket/base or racket.

syntax

(enter! module-path)

(enter! #f)
(enter! module-path flag ...+)
 
flag = #:quiet
  | #:verbose-reload
  | #:verbose
  | #:dont-re-require-enter
Intended for use in a REPL, such as when racket is +started in interactive mode. When a module-path is provided +(in the same sense as for require), the corresponding module +is loaded or invoked via dynamic-rerequire, and the current namespace is changed to +the body of the module via module->namespace. When +#f is provided, then the current namespace is restored +to the original one.

Additional flags can customize aspects of enter!: +
  • The #:verbose, #:verbose-reload, and +#:quiet flags correspond to 'all, +'reload, and 'none verbosity for +dynamic-rerequire. The default corresponds to +#:verbose-reload.

  • After switching namespaces to the designated module, +enter! automatically requires racket/enter into the +namespace, so that enter! can be used to switch namespaces +again. In some cases, requiring racket/enter +might not be desirable (e.g., in a tool +that uses racket/enter); use the +#:dont-re-require-enter flag to disable the require.

procedure

(dynamic-enter! mod    
  [#:verbosity verbosity    
  #:re-require-enter? re-require-enter?])  void?
  mod : (or/c module-path? #f)
  verbosity : (or/c 'all 'reload 'none) = 'reload
  re-require-enter? : any/c = #t
Procedure variant of enter!, where verbosity is +passed along to dynamic-rerequire and +re-require-enter? determines whether dynamic-enter! +requires racket/enter in a newly entered namespace.

Added in version 6.0.0.1 of package base.

18.5.2 Loading and Reloading Modules

The bindings documented in this section are provided by the racket/rerequire library, not racket/base or racket.

procedure

(dynamic-rerequire module-path    
  [#:verbosity verbosity])  (listof path?)
  module-path : module-path?
  verbosity : (or/c 'all 'reload 'none) = 'reload
Like (dynamic-require module-path 0), but with reloading +support. The dynamic-rerequire function is intended for use +in an interactive environment, especially via enter!.

If invoking module-path requires loading any files, then +modification dates of the files are recorded. If the file is modified, +then a later dynamic-rerequire re-loads the module from source; see also +Module Redeclarations. Similarly if a later dynamic-rerequire +transitively requires a modified module, then the required +module is re-loaded. Re-loading support works only for modules that +are first loaded (either directly or indirectly through transitive +requires) via dynamic-rerequire.

The returned list contains the absolute paths to the modules that were +reloaded on this call to dynamic-rerequire. If the returned +list is empty, no modules were changed or loaded.

When enter! loads or re-loads a module from a file, it can +print a message to (current-error-port), depending on +verbosity: 'all prints a message for all loads and +re-loads, 'reload prints a message only for +re-loaded modules, and 'none disables printouts.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/invokingunits.html b/clones/docs.racket-lang.org/reference/invokingunits.html new file mode 100644 index 00000000..56b5ceec --- /dev/null +++ b/clones/docs.racket-lang.org/reference/invokingunits.html @@ -0,0 +1,26 @@ + +7.2 Invoking Units

7.2 Invoking Units

syntax

(invoke-unit unit-expr)

(invoke-unit unit-expr (import tagged-sig-spec ...))
Invokes the unit produced by unit-expr. For each of the +unit’s imports, the invoke-unit expression must contain a +tagged-sig-spec in the import clause; see +unit for the grammar of tagged-sig-spec. If the unit +has no imports, the import clause can be omitted.

When no tagged-sig-specs are provided, unit-expr +must produce a unit that expects no imports. To invoke the unit, all +bindings are first initialized to the #<undefined> value. Next, +the unit’s body definitions and expressions are evaluated in order; in +the case of a definition, evaluation sets the value of the +corresponding variable(s). Finally, the result of the last expression +in the unit is the result of the invoke-unit expression.

Each supplied tagged-sig-spec takes bindings from the +surrounding context and turns them into imports for the invoked unit. +The unit need not declare an import for every provided +tagged-sig-spec, but one tagged-sig-spec must be +provided for each declared import of the unit. For each variable +identifier in each provided tagged-sig-spec, the value of the +identifier’s binding in the surrounding context is used for the +corresponding import in the invoked unit.

syntax

(define-values/invoke-unit unit-expr
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...))
Like invoke-unit, but the values of the unit’s exports are +copied to new bindings.

The unit produced by unit-expr is linked and invoked as for +invoke-unit. In addition, the export clause is +treated as a kind of import into the local definition context. That +is, for every binding that would be available in a unit that used the +export clause’s tagged-sig-spec as an import, a +definition is generated for the context of the +define-values/invoke-unit form.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/ivaraccess.html b/clones/docs.racket-lang.org/reference/ivaraccess.html new file mode 100644 index 00000000..52e8ce56 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/ivaraccess.html @@ -0,0 +1,69 @@ + +6.4 Field and Method Access

6.4 Field and Method Access

In expressions within a class definition, the initialization +variables, fields, and methods of the class are all part of the +environment. Within a method body, only the fields and other methods +of the class can be referenced; a reference to any other +class-introduced identifier is a syntax error. Elsewhere within the +class, all class-introduced identifiers are available, and fields and +initialization variables can be mutated with set!.

6.4.1 Methods

Method names used within a class can only be used in the procedure position +of an application expression; any other use is a syntax error.

To allow methods to be applied to lists of arguments, a method +application can have the following form:

(method-id arg ... . arg-list-expr)

This form calls the method in a way analogous to (apply method-id arg ... arg-list-expr). The arg-list-expr +must not be a parenthesized expression.

Methods are called from outside a class with the send, +send/apply, and send/keyword-apply forms.

syntax

(send obj-expr method-id arg ...)

(send obj-expr method-id arg ... . arg-list-expr)
Evaluates obj-expr to obtain an object, and calls the method +with (external) name method-id on the object, providing the +arg results as arguments. Each arg is as for +#%app: either arg-expr or keyword arg-expr. In the second form, arg-list-expr cannot be a +parenthesized expression.

If obj-expr does not produce an object, the +exn:fail:contract exception is raised. If the object has no public method named +method-id, the exn:fail:object exception is raised.

syntax

(send/apply obj-expr method-id arg ... arg-list-expr)

Like the dotted form of send, but arg-list-expr can +be any expression.

syntax

(send/keyword-apply obj-expr method-id
                    keyword-list-expr value-list-expr
                    arg ... arg-list-expr)
Like send/apply, but with expressions for keyword and +argument lists like keyword-apply.

procedure

(dynamic-send obj    
  method-name    
  v ...    
  #:<kw> kw-arg ...)  any
  obj : object?
  method-name : symbol?
  v : any/c
  kw-arg : any/c
Calls the method on obj whose name matches +method-name, passing along all given vs and +kw-args.

syntax

(send* obj-expr msg ...+)

 
msg = (method-id arg ...)
  | (method-id arg ... . arg-list-expr)
Calls multiple methods (in order) of the same object. Each +msg corresponds to a use of send.

For example,

(send* edit (begin-edit-sequence)
            (insert "Hello")
            (insert #\newline)
            (end-edit-sequence))

is the same as

(let ([o edit])
  (send o begin-edit-sequence)
  (send o insert "Hello")
  (send o insert #\newline)
  (send o end-edit-sequence))

syntax

(send+ obj-expr msg ...)

 
msg = (method-id arg ...)
  | (method-id arg ... . arg-list-expr)
Calls methods (in order) starting with the object produced by +obj-expr. Each method call will be invoked on the result of +the last method call, which is expected to be an object. Each +msg corresponds to a use of send.

This is the functional analogue of send*.

Examples:
(define point%
  (class object%
    (super-new)
    (init-field [x 0] [y 0])
    (define/public (move-x dx)
      (new this% [x (+ x dx)]))
    (define/public (move-y dy)
      (new this% [y (+ y dy)]))))

 

> (send+ (new point%)
         (move-x 5)
         (move-y 7)
         (move-x 12))

(object:point% ...)

syntax

(with-method ((id (obj-expr method-id)) ...)
  body ...+)
Extracts methods from an object and binds a local name that can be +applied directly (in the same way as declared methods within a class) +for each method. Each obj-expr must produce an object, +which must have a public method named by the corresponding +method-id. The corresponding id is bound so that it +can be applied directly (see Methods).

Example:

(let ([s (new stack%)])
  (with-method ([push (s push!)]
                [pop (s pop!)])
    (push 10)
    (push 9)
    (pop)))

is the same as

(let ([s (new stack%)])
  (send s push! 10)
  (send s push! 9)
  (send s pop!))
6.4.2 Fields

syntax

(get-field id obj-expr)

Extracts the field with (external) name id from the value of +obj-expr.

If obj-expr does not produce an object, the +exn:fail:contract exception is raised. If the object has no id field, +the exn:fail:object exception is raised.

procedure

(dynamic-get-field field-name obj)  any/c

  field-name : symbol?
  obj : object?
Extracts the field from obj with the (external) name that +matches field-name. If the object has no field matching field-name, +the exn:fail:object exception is raised.

syntax

(set-field! id obj-expr expr)

Sets the field with (external) name id from the value of +obj-expr to the value of expr.

If obj-expr does not produce an object, the +exn:fail:contract exception is raised. If the object has no id field, +the exn:fail:object exception is raised.

procedure

(dynamic-set-field! field-name obj v)  void?

  field-name : symbol?
  obj : object?
  v : any/c
Sets the field from obj with the (external) name that +matches field-name to v. If the object has no field matching field-name, +the exn:fail:object exception is raised.

syntax

(field-bound? id obj-expr)

Produces #t if the object result of obj-expr has a +field with (external) name id, #f otherwise.

If obj-expr does not produce an object, the +exn:fail:contract exception is raised.

syntax

(class-field-accessor class-expr field-id)

Returns an accessor procedure that takes an instance of the class +produced by class-expr and returns the value of the object’s +field with (external) name field-id.

If class-expr does not produce a class, the +exn:fail:contract exception is raised. If the class has no field-id +field, the exn:fail:object exception is raised.

syntax

(class-field-mutator class-expr field-id)

Returns a mutator procedure that takes an instance of the class +produced by class-expr and a value, and sets the value of the +object’s field with (external) name field-id to the given +value. The result is #<void>.

If class-expr does not produce a class, the +exn:fail:contract exception is raised. If the class has no field-id +field, the exn:fail:object exception is raised.

6.4.3 Generics

A generic can be used instead of a method name to avoid the +cost of relocating a method by name within a class.

syntax

(generic class-or-interface-expr id)

Produces a generic that works on instances of the class or interface +produced by class-or-interface-expr (or an instance of a +class/interface derived from class-or-interface) to call the +method with (external) name id.

If class-or-interface-expr does not produce a class or +interface, the exn:fail:contract exception is raised. If the resulting class or +interface does not contain a method named id, the +exn:fail:object exception is raised.

syntax

(send-generic obj-expr generic-expr arg ...)

(send-generic obj-expr generic-expr arg ... . arg-list-expr)
Calls a method of the object produced by obj-expr as +indicated by the generic produced by generic-expr. Each +arg is as for #%app: either arg-expr or +keyword arg-expr. The second form is analogous to calling a +procedure with apply, where arg-list-expr is not a +parenthesized expression.

If obj-expr does not produce an object, or if +generic-expr does not produce a generic, the +exn:fail:contract exception is raised. If the result of obj-expr is +not an instance of the class or interface encapsulated by the result +of generic-expr, the exn:fail:object exception is raised.

procedure

(make-generic type method-name)  generic?

  type : (or/c class? interface?)
  method-name : symbol?
Like the generic form, but as a procedure that accepts a +symbolic method name.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/keywords.html b/clones/docs.racket-lang.org/reference/keywords.html new file mode 100644 index 00000000..b34dfa0e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/keywords.html @@ -0,0 +1,18 @@ + +4.9 Keywords

4.9 Keywords

+Keywords in The Racket Guide introduces keywords.

A keyword is like an interned symbol, but its printed +form starts with #:, and a keyword cannot be used as an +identifier. Furthermore, a keyword by itself is not a valid +expression, though a keyword can be quoted to form an +expression that produces the symbol.

Two keywords are eq? if and only if they print the same +(i.e., keywords are always interned).

Like symbols, keywords are only weakly held by the internal keyword +table; see Symbols for more information.

See Reading Keywords + for information on reading + keywords and Printing Keywords + for information on printing keywords.

procedure

(keyword? v)  boolean?

  v : any/c
Returns #t if v is a keyword, #f otherwise.

Examples:
> (keyword? '#:apple)

#t

> (keyword? 'define)

#f

> (keyword? '#:define)

#t

procedure

(keyword->string keyword)  string?

  keyword : keyword?
Returns a string for the displayed form of keyword, +not including the leading #:.

See also keyword->immutable-string from +racket/keyword.

Example:
> (keyword->string '#:apple)

"apple"

procedure

(string->keyword str)  keyword?

  str : string?
Returns a keyword whose displayed form is the same as that of +str, but with a leading #:.

Example:
> (string->keyword "apple")

'#:apple

procedure

(keyword<? a-keyword b-keyword ...)  boolean?

  a-keyword : keyword?
  b-keyword : keyword?
Returns #t if the arguments are sorted, where the comparison +for each pair of keywords is the same as using +keyword->string with string->bytes/utf-8 and +bytes<?.

Example:
> (keyword<? '#:apple '#:banana)

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.9.1 Additional Keyword Functions

The bindings documented in this section are provided by the racket/keyword and racket libraries, but not racket/base.

Added in version 7.6 of package base.

procedure

(keyword->immutable-string sym)  (and/c string? immutable?)

  sym : keyword?
Like keyword->string, but the result is an immutable string, +not necessarily freshly allocated.

Examples:
> (keyword->immutable-string '#:apple)

"apple"

> (immutable? (keyword->immutable-string '#:apple))

#t

Added in version 7.6 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/lambda.html b/clones/docs.racket-lang.org/reference/lambda.html new file mode 100644 index 00000000..fc57ab77 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/lambda.html @@ -0,0 +1,94 @@ + +3.8 Procedure Expressions: lambda and case-lambda

3.8 Procedure Expressions: lambda and case-lambda

+Functions: lambda in The Racket Guide introduces procedure expressions.

syntax

(lambda kw-formals body ...+)

syntax

(λ kw-formals body ...+)

 
kw-formals = (arg ...)
  | (arg ...+ . rest-id)
  | rest-id
     
arg = id
  | [id default-expr]
  | keyword id
  | keyword [id default-expr]
Produces a procedure. The kw-formals determines the number of +arguments and which keyword arguments that the procedure accepts.

Considering only the first arg case, a simple +kw-formals has one of the following three forms:

(id ...)

The procedure accepts as many non-keyword +argument values as the number of ids. Each id +is associated with an argument value by position.

(id ...+ . rest-id)

The procedure accepts any number of +non-keyword arguments greater or equal to the number of +ids. When the procedure is applied, the ids +are associated with argument values by position, and all +leftover arguments are placed into a list that is associated to +rest-id.

rest-id

The procedure accepts any number of non-keyword +arguments. All arguments are placed into a list that is +associated with rest-id.

More generally, an arg can include a keyword and/or default +value. Thus, the first two cases above are more completely specified +as follows:

(arg ...)

Each arg has the following + four forms:

id

Adds one to both the minimum and maximum +number of non-keyword arguments accepted by the procedure. The +id is associated with an actual argument by +position.

[id default-expr]

Adds one to the maximum number +of non-keyword arguments accepted by the procedure. The +id is associated with an actual argument by position, +and if no such argument is provided, the default-expr +is evaluated to produce a value associated with id. +No arg with a default-expr can appear +before an id without a default-expr and +without a keyword.

keyword id

The procedure requires a +keyword-based argument using keyword. The id +is associated with a keyword-based actual argument using +keyword.

keyword [id default-expr]

The +procedure accepts a keyword-based argument using keyword. The +id is associated with a keyword-based actual argument +using keyword, if supplied in an application; +otherwise, the default-expr is evaluated to obtain a +value to associate with id.

The position of a keyword arg in +kw-formals does not matter, but each specified +keyword must be distinct.

(arg ...+ . rest-id)

Like the previous case, but +the procedure accepts any number of non-keyword arguments +beyond its minimum number of arguments. When more arguments are +provided than non-keyword arguments among the +args, the extra arguments are placed into a +list that is associated to rest-id.

In other words, argument bindings with +default-value expressions are evaluated analogous to let*.

The kw-formals identifiers are bound in the +bodys. When the procedure is applied, a new location +is created for each identifier, and the location is filled with the +associated argument value. The locations are created and filled +in order, with default-exprs evaluated as needed to fill +locations.

If any identifier appears in the bodys that is not one of the +identifiers in kw-formals, then it refers to the same +location that it would if it appeared in place of the lambda +expression. (In other words, variable reference is lexically scoped.)

When multiple identifiers appear in a kw-formals, they must +be distinct according to bound-identifier=?.

If the procedure produced by lambda is applied to fewer or +more by-position or by-keyword arguments than it accepts, to by-keyword arguments +that it does not accept, or without required by-keyword arguments, then +the exn:fail:contract exception is raised.

The last body expression is in tail position with respect to +the procedure body.

Examples:
> ((lambda (x) x) 10)

10

> ((lambda (x y) (list y x)) 1 2)

'(2 1)

> ((lambda (x [y 5]) (list y x)) 1 2)

'(2 1)

> (let ([f (lambda (x #:arg y) (list y x))])
   (list (f 1 #:arg 2)
         (f #:arg 2 1)))

'((2 1) (2 1))

When compiling a lambda or case-lambda expression, +Racket looks for a 'method-arity-error property +attached to the expression (see Syntax Object Properties). If it is +present with a true value, and if no case of the procedure accepts +zero arguments, then the procedure is marked so that an +exn:fail:contract:arity exception involving the procedure +will hide the first argument, if one was provided. (Hiding the first +argument is useful when the procedure implements a method, where the +first argument is implicit in the original source). The property +affects only the format of exn:fail:contract:arity +exceptions, not the result of procedure-arity.

When a keyword-accepting procedure is bound to an identifier in +certain ways, and when the identifier is used in the function position +of an application form, then the application form may be expanded in +such a way that the original binding is obscured as the target of the +application. To help expose the connection between the function +application and function declaration, an identifier in the expansion +of the function application is tagged with a syntax property +accessible via syntax-procedure-alias-property if it is effectively an alias +for the original identifier. An identifier in the expansion is tagged with a +syntax property accessible via syntax-procedure-converted-arguments-property if it +is like the original identifier except that the arguments are converted to a +flattened form: keyword arguments, required by-position arguments, +by-position optional arguments, and rest arguments—all as required, +by-position arguments; the keyword arguments are sorted by keyword +name, each optional keyword argument is followed by a boolean to +indicate whether a value is provided, and #f is used for an +optional keyword argument whose value is not provided; optional +by-position arguments include #f for each non-provided +argument, and then the sequence of optional-argument values is +followed by a parallel sequence of booleans to indicate whether each +optional-argument value was provided.

syntax

(case-lambda [formals body ...+] ...)

 
formals = (id ...)
  | (id ...+ . rest-id)
  | rest-id
Produces a procedure. Each [formals body ...+] +clause is analogous to a single lambda procedure; applying +the case-lambda-generated procedure is the same as applying a +procedure that corresponds to one of the clauses—the first procedure +that accepts the given number of arguments. If no corresponding +procedure accepts the given number of arguments, the +exn:fail:contract exception is raised.

Note that a case-lambda clause supports only +formals, not the more general kw-formals of +lambda. That is, case-lambda does not directly +support keyword and optional arguments.

Example:
> (let ([f (case-lambda
            [() 10]
            [(x) x]
            [(x y) (list y x)]
            [r r])])
    (list (f)
          (f 1)
          (f 1 2)
          (f 1 2 3)))

'(10 1 (2 1) (1 2 3))

syntax

(#%plain-lambda formals body ...+)

Like lambda, but without support for keyword or optional arguments.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/lazy-require.html b/clones/docs.racket-lang.org/reference/lazy-require.html new file mode 100644 index 00000000..15c0a3ab --- /dev/null +++ b/clones/docs.racket-lang.org/reference/lazy-require.html @@ -0,0 +1,44 @@ + +3.26 Importing Modules Lazily: lazy-require

3.26 Importing Modules Lazily: lazy-require

The bindings documented in this section are provided by the racket/lazy-require library, not racket/base or racket.

syntax

(lazy-require [module-path (fun-import ...)] ...)

 
fun-import = fun-id
  | (orig-fun-id fun-id)
Defines each fun-id as a function that, when called, +dynamically requires the export named orig-fun-id from the +module specified by module-path and calls it with the same +arguments. If orig-fun-id is not given, it defaults to +fun-id.

If the enclosing relative phase level is not 0, then +module-path is also placed in a submodule (with a use of +define-runtime-module-path-index at phase level 0 within the +submodule). Introduced submodules have the names +lazy-require-auxn-m, where +n is a phase-level number and m is a number.

When the use of a lazily-required function triggers module loading, it +also triggers a use of register-external-module to declare an +indirect compilation dependency (in case the function is used in the +process of compiling a module).

Examples:
> (lazy-require
    [racket/list (partition)])
> (partition even? '(1 2 3 4 5))

'(2 4)

'(1 3 5)

> (module hello racket/base
    (provide hello)
    (printf "starting hello server\n")
    (define (hello) (printf "hello!\n")))
> (lazy-require
    ['hello ([hello greet])])
> (greet)

starting hello server

hello!

syntax

(lazy-require-syntax [module-path (macro-import ...)] ...)

 
macro-import = macro-id
  | (orig-macro-id macro-id)
Like lazy-require but for macros. That is, it defines each +macro-id as a macro that, when used, dynamically loads the +macro’s implementation from the given module-path. If +orig-macro-id is not given, it defaults to macro-id.

Use lazy-require-syntax in the implementation of a library +with large, complicated macros to avoid a dependence from clients of +the library on the macro “compilers.” Note that only macros with +exceptionally large compile-time components (such as Typed Racket, +which includes a type checker and optimizer) benefit from +lazy-require-syntax; typical macros do not.

Warning: lazy-require-syntax breaks the invariants +that Racket’s module loader and linker rely on; these invariants +normally ensure that the references in code produced by a macro are +loaded before the code runs. Safe use of lazy-require-syntax +requires a particular structure in the macro implementation. (In +particular, lazy-require-syntax cannot simply be introduced +in the client code.) The macro implementation must follow these rules: +
  1. the interface module must require the runtime-support module

  2. the compiler module must require the runtime-support module via +an absolute module path rather than a relative path

To explain the concepts of “interface, compiler, and runtime-support +modules”, here is an example module that exports a macro: +
(module original racket/base
  (define (ntimes-proc n thunk)
    (for ([i (in-range n)]) (thunk)))
  (define-syntax-rule (ntimes n expr)
    (ntimes-proc n (lambda () expr)))
  (provide ntimes))
Suppose we want to use lazy-require-syntax to lazily load the +implementation of the ntimes macro transformer. The original +module must be split into three parts: +
(module runtime-support racket/base
  (define (ntimes-proc n thunk)
    (for ([i (in-range n)]) (thunk)))
  (provide ntimes-proc))
(module compiler racket/base
  (require 'runtime-support)
  (define-syntax-rule (ntimes n expr)
    (ntimes-proc n (lambda () expr)))
  (provide ntimes))
(module interface racket/base
  (require racket/lazy-require)
  (require 'runtime-support)
  (lazy-require-syntax ['compiler (ntimes)])
  (provide ntimes))
The runtime support module contains the function and value definitions +that the macro refers to. The compiler module contains the macro +definition(s) themselves—the part of the code that “disappears” +after compile time. The interface module lazily loads the macro +transformer, but it makes sure the runtime support module is defined at +run time by requiring it normally. In a larger example, of course, the +runtime support and compiler may both consist of multiple modules.

Here what happens when we don’t separate the runtime support into a +separate module: +
> (module bad-no-runtime racket/base
    (define (ntimes-proc n thunk)
      (for ([i (in-range n)]) (thunk)))
    (define-syntax-rule (ntimes n expr)
      (ntimes-proc n (lambda () expr)))
    (provide ntimes))
> (module bad-client racket/base
    (require racket/lazy-require)
    (lazy-require-syntax ['bad-no-runtime (ntimes)])
    (ntimes 3 (printf "hello?\n")))
> (require 'bad-client)

require: namespace mismatch;

 reference to a module that is not instantiated

  module: 'bad-no-runtime

  phase: 0

A similar error occurs when the interface module doesn’t introduce a +dependency on the runtime support module.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/let.html b/clones/docs.racket-lang.org/reference/let.html new file mode 100644 index 00000000..62efd90c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/let.html @@ -0,0 +1,78 @@ + +3.9 Local Binding: let, let*, letrec, ...

3.9 Local Binding: let, let*, letrec, ...

+Local Binding in The Racket Guide introduces local binding.

syntax

(let ([id val-expr] ...) body ...+)

(let proc-id ([id init-expr] ...) body ...+)
The first form evaluates the val-exprs left-to-right, creates +a new location for each id, and places the values into the +locations. It then evaluates the bodys, in which the +ids are bound. The last body expression is in +tail position with respect to the let form. The ids +must be distinct according to bound-identifier=?.

Examples:
> (let ([x 5]) x)

5

> (let ([x 5])
    (let ([x 2]
          [y x])
      (list y x)))

'(5 2)

The second form, usually known as named let, evaluates the init-exprs; the resulting +values become arguments in an application of a procedure +(lambda (id ...) body ...+), where proc-id is bound +within the bodys to the procedure itself.

Example:
> (let fac ([n 10])
    (if (zero? n)
        1
        (* n (fac (sub1 n)))))

3628800

syntax

(let* ([id val-expr] ...) body ...+)

Like let, but evaluates the val-exprs one by +one, creating a location for each id as soon as the value is +available. The ids are bound in the remaining val-exprs +as well as the bodys, and the ids need not be +distinct; later bindings shadow earlier bindings.

Example:
> (let* ([x 1]
         [y (+ x 1)])
    (list y x))

'(2 1)

syntax

(letrec ([id val-expr] ...) body ...+)

Like let, including left-to-right evaluation of the val-exprs, +but the locations for all ids are +created first, all +ids are bound in all val-exprs as well as the +bodys, and each id is initialized immediately after the +corresponding val-expr is evaluated. The ids must be distinct according to +bound-identifier=?.

Referencing or assigning to an id before its initialization +raises exn:fail:contract:variable. If an id (i.e., +the binding instance or id) has an +'undefined-error-name syntax property whose +value is a symbol, the symbol is used as the name of the variable for +error reporting, instead of the symbolic form of id.

Example:
> (letrec ([is-even? (lambda (n)
                       (or (zero? n)
                           (is-odd? (sub1 n))))]
           [is-odd? (lambda (n)
                      (and (not (zero? n))
                           (is-even? (sub1 n))))])
    (is-odd? 11))

#t

Changed in version 6.0.1.2 of package base: Changed reference or assignment of an uninitialized id to an error.

syntax

(let-values ([(id ...) val-expr] ...) body ...+)

Like +let, except that each val-expr must produce as many +values as corresponding ids, otherwise the +exn:fail:contract exception is raised. A separate location is created for each +id, all of which are bound in the bodys.

Example:
> (let-values ([(x y) (quotient/remainder 10 3)])
    (list y x))

'(1 3)

syntax

(let*-values ([(id ...) val-expr] ...) body ...+)

Like +let*, except that each val-expr must produce as many +values as corresponding ids. A separate location is created +for each id, all of which are bound in the later +val-exprs and in the bodys.

Example:
> (let*-values ([(x y) (quotient/remainder 10 3)]
                [(z) (list y x)])
    z)

'(1 3)

syntax

(letrec-values ([(id ...) val-expr] ...) body ...+)

Like +letrec, except that each val-expr must produce as +many values as corresponding ids. A separate location is +created for each id, all of which are bound in all val-exprs +and in the bodys.

Example:
> (letrec-values ([(is-even? is-odd?)
                   (values
                     (lambda (n)
                       (or (zero? n)
                           (is-odd? (sub1 n))))
                     (lambda (n)
                       (or (= n 1)
                           (is-even? (sub1 n)))))])
    (is-odd? 11))

#t

syntax

(let-syntax ([id trans-expr] ...) body ...+)

Creates a transformer binding (see +Transformer Bindings) of each id with the value of +trans-expr, which is an expression at phase level 1 +relative to the surrounding context. (See Identifiers, Binding, and Scopes for +information on phase levels.)

The evaluation of each trans-expr is parameterized +to set current-namespace to a namespace that shares +bindings and variables with the namespace being used to +expand the let-syntax form, except that its base phase +is one greater.

Each id is bound in the bodys, and not in other +trans-exprs.

syntax

(letrec-syntax ([id trans-expr] ...) body ...+)

Like let-syntax, except that each id is also bound +within all trans-exprs.

syntax

(let-syntaxes ([(id ...) trans-expr] ...) body ...+)

Like let-syntax, but each trans-expr must produce as +many values as corresponding ids, each of which is bound to +the corresponding value.

syntax

(letrec-syntaxes ([(id ...) trans-expr] ...) body ...+)

Like let-syntax, except that each id is also bound +within all trans-exprs.

syntax

(letrec-syntaxes+values ([(trans-id ...) trans-expr] ...)
                        ([(val-id ...) val-expr] ...)
   body ...+)
Combines letrec-syntaxes with a variant of +letrec-values: each trans-id and val-id is +bound in all trans-exprs and val-exprs.

The letrec-syntaxes+values form is the core form for local +compile-time bindings, since forms like letrec-syntax and +internal-definition contexts expand to it. In a fully expanded +expression (see Fully Expanded Programs), the trans-id +bindings are discarded and the form reduces to a combination of +letrec-values or let-values.

For variables bound by letrec-syntaxes+values, the +location-creation rules differ slightly from +letrec-values. The [(val-id ...) val-expr] binding +clauses are partitioned into minimal sets of clauses that satisfy the +following rule: if a clause has a val-id binding that is +referenced (in a full expansion) by the val-expr of an +earlier clause, the two clauses and all in between are in the same +set. If a set consists of a single clause whose val-expr does +not refer to any of the clause’s val-ids, then +locations for the val-ids are created after the +val-expr is evaluated. Otherwise, locations for all +val-ids in a set are created just before the first +val-expr in the set is evaluated. For the purposes +of forming sets, a (quote-syntax datum #:local) form counts +as a reference to all bindings in the letrec-syntaxes+values +form

The end result of the location-creation rules is that scoping +and evaluation order are the same as for letrec-values, but +the compiler has more freedom to optimize away location +creation. The rules also correspond to a nesting of +let-values and letrec-values, which is how +letrec-syntaxes+values for a fully-expanded expression.

See also local, which supports local bindings with +define, define-syntax, and more.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/linecol.html b/clones/docs.racket-lang.org/reference/linecol.html new file mode 100644 index 00000000..90fe245c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/linecol.html @@ -0,0 +1,60 @@ + +13.1.4 Counting Positions, Lines, and Columns
13.1.4 Counting Positions, Lines, and Columns

By default, Racket keeps track of the position in a port as +the number of bytes that have been read from or written to any port +(independent of the read/write position, which is accessed or changed +with file-position). Optionally, however, Racket can track +the position in terms of characters (after UTF-8 decoding), instead of +bytes, and it can track line locations and column +locations; this optional tracking must be specifically enabled for a +port via port-count-lines! or the +port-count-lines-enabled parameter. Position, line, and +column locations for a port are used by read-syntax. +Position and line locations are numbered +from 1; column locations are numbered from 0.

When counting lines, Racket treats linefeed, return, and +return-linefeed combinations as a line terminator and as a single +position (on all platforms). Each tab advances the column count to one +before the next multiple of 8. When a sequence of bytes in the +range 128 to 253 forms a UTF-8 encoding of a character, the +position/column is incremented once for each byte, and +then decremented appropriately when a complete encoding sequence is +discovered. See also Ports for more information on UTF-8 +decoding for ports.

A position is known for any port as long as its value can be expressed +as a fixnum (which is more than enough tracking for realistic +applications in, say, syntax-error reporting). If the position for a +port exceeds the value of the largest fixnum, then the position for +the port becomes unknown, and line and column tacking is disabled. +Return-linefeed combinations are treated as a single character +position only when line and column counting is enabled.

Custom ports can define their own counting functions, which are +not subject to the rules above, except that the counting functions are +invoked only when tracking is specifically enabled with +port-count-lines!.

procedure

(port-count-lines! port)  void?

  port : port?
Turns on line location and column location counting +for a port. Counting can be turned +on at any time, though generally it is turned on before any data is +read from or written to a port. At the point that line counting is +turned on, port-next-location typically starts reporting as +its last result (one more than) the number of characters read since +line counting was enabled, instead of (one more than) bytes read since +the port was opened.

When a port is created, if the value of the +port-count-lines-enabled parameter is true, then line +counting is automatically enabled for the port. Line counting cannot +be disabled for a port after it is enabled.

procedure

(port-counts-lines? port)  boolean?

  port : port?
Returns #t if line location and column location +counting has been enabled for +port, #f otherwise.

Returns three values: an integer or #f for the line number of +the next read/written item, an integer or #f for the next +item’s column, and an integer or #f for the next item’s +position. The next column and position normally increase as bytes are +read from or written to the port, but if line/character counting is +enabled for port, the column and position results can +decrease after reading or writing a byte that ends a UTF-8 encoding +sequence.

If line counting is not enabled for a port, than the first two results +are #f, and the last result is one more than the number of +bytes read so far. At the point when line counting is enabled, the +first two results typically become non-#f, and last result +starts reporting characters instead of bytes, typically starting from +the point when line counting is enabled.

Even with line counting enabled, a port may return #f values +if it somehow cannot keep track of lines, columns, or positions.

procedure

(set-port-next-location! port    
  line    
  column    
  position)  void?
  port : port?
  line : (or/c exact-positive-integer? #f)
  column : (or/c exact-nonnegative-integer? #f)
  position : (or/c exact-positive-integer? #f)
Sets the next line, column, and position for port. If line +counting has not been enabled for port or if port is +a custom port that defines its own counting function, then +set-port-next-location! has no effect.

parameter

(port-count-lines-enabled)  boolean?

(port-count-lines-enabled on?)  void?
  on? : any/c
A parameter that determines whether line counting is enabled +automatically for newly created ports. The default value is +#f.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/linkinference.html b/clones/docs.racket-lang.org/reference/linkinference.html new file mode 100644 index 00000000..39371448 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/linkinference.html @@ -0,0 +1,70 @@ + +7.4 Inferred Linking

7.4 Inferred Linking

syntax

(define-unit unit-id
  (import tagged-sig-spec ...)
  (export tagged-sig-spec ...)
  init-depends-decl
  unit-body-expr-or-defn
  ...)
Binds unit-id to both a unit and static information about the +unit.

Evaluating a reference to a unit-id bound by +define-unit produces a unit, just like evaluating an +id bound by (define id (unit ...)). In addition, +however, unit-id can be used in compound-unit/infer. +See unit for information on tagged-sig-spec, +init-depends-decl, and unit-body-expr-or-defn.

syntax

(compound-unit/infer
  (import tagged-infer-link-import ...)
  (export tagged-infer-link-export ...)
  (link infer-linkage-decl ...))
 
tagged-infer-link-import = tagged-sig-id
  | (link-id : tagged-sig-id)
     
tagged-infer-link-export = (tag id infer-link-export)
  | infer-link-export
     
infer-link-export = link-id
  | sig-id
     
infer-linkage-decl = 
((link-binding ...) unit-id
                    tagged-link-id ...)
  | unit-id
Like compound-unit. Syntactically, the difference between +compound-unit and compound-unit/infer is that the +unit-expr for a linked unit is replaced with a +unit-id, where a unit-id is bound by +define-unit (or one of the other unit-binding forms that we +introduce later in this section). Furthermore, an import can name just +a sig-id without locally binding a link-id, and an +export can be based on a sig-id instead of a +link-id, and a declaration in the link clause can be +simply a unit-id with no specified exports or imports.

The compound-unit/infer form expands to +compound-unit by adding sig-ids as needed to +the import clause, by replacing sig-ids in the +export clause by link-ids, and by completing +the declarations of the link clause. This completion is based +on static information associated with each +unit-id. Links and exports can be inferred when all +signatures exported by the linked units are distinct from each other +and from all imported signatures, and when all imported signatures are +distinct. Two signatures are distinct only if they +share no ancestor through extends.

The long form of a link declaration can be used to resolve +ambiguity by giving names to some of a unit’s exports and supplying +specific bindings for some of a unit’s imports. The long form need not +name all of a unit’s exports or supply all of a unit’s imports if the +remaining parts can be inferred.

When a unit declares initialization dependencies, +compound-unit/infer checks that the link declaration +is consistent with those dependencies, and it reports a syntax error if +not.

Like compound-unit, the compound-unit/infer form +produces a (compound) unit without statically binding information +about the result unit’s imports and exports. That is, +compound-unit/infer consumes static information, but it does +not generate it. Two additional forms, +define-compound-unit and +define-compound-unit/infer, generate static information +(where the former does not consume static information).

Changed in version 6.1.1.8 of package base: Added static checking of the link +clause with respect to declared +initialization dependencies.

syntax

(define-compound-unit id
  (import link-binding ...)
  (export tagged-link-id ...)
  (link linkage-decl ...))
Like compound-unit, but binds static information about the +compound unit like define-unit, including the propagation of +initialization-dependency information (on remaining inports) from the +linked units.

syntax

(define-compound-unit/infer id
  (import link-binding ...)
  (export tagged-infer-link-export ...)
  (link infer-linkage-decl ...))
Like compound-unit/infer, but binds static information about +the compound unit like define-compound-unit.

syntax

(define-unit-binding unit-id
  unit-expr
  (import tagged-sig-spec ...+)
  (export tagged-sig-spec ...+)
  init-depends-decl)
Like define-unit, but the unit implementation is determined +from an existing unit produced by unit-expr. The imports and +exports of the unit produced by unit-expr must be consistent +with the declared imports and exports, otherwise the +exn:fail:contract exception is raised when the define-unit-binding +form is evaluated.

syntax

(invoke-unit/infer unit-spec)

 
unit-spec = unit-id
  | (link link-unit-id ...)
Like invoke-unit, but uses static information associated with +unit-id to infer which imports must be assembled from the +current context. If given a link form containing multiple +link-unit-ids, then the units are first linked via +define-compound-unit/infer.

When assembling imports from the current context, the lexical +information of a unit-id is used for constructing the lexical +information of the signatures for the unit’s imports (i.e., the lexical +information that would normally be derived from the signature reference). +See define-signature for more information.

syntax

(define-values/invoke-unit/infer maybe-exports unit-spec)

 
maybe-exports = 
  | (export tagged-sig-spec ...)
     
unit-spec = unit-id
  | (link link-unit-id ...)
Like define-values/invoke-unit, but uses static information +associated with unit-id to infer which imports must be +assembled from the current context and, if no export clause +is present, which exports should be bound by the definition. If given +a link form containing multiple link-unit-ids, then the units +are first linked via define-compound-unit/infer.

Similar to invoke-unit/infer, the lexical information +of a unit-id is used for constructing the lexical information +of the signatures for the unit’s inferred imports and inferred exports +(i.e., the lexical information that would normally be derived from a +signature reference). See define-signature for more +information.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/linklets.html b/clones/docs.racket-lang.org/reference/linklets.html new file mode 100644 index 00000000..f71ca9c5 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/linklets.html @@ -0,0 +1,247 @@ + +14.14 Linklets and the Core Compiler

14.14 Linklets and the Core Compiler

 (require racket/linklet) package: base

A linklet is a primitive element of compilation, bytecode +marshaling, and evaluation. Racket’s implementations of modules, +macros, and top-level evaluation are all built on linklets. Racket +programmers generally do not encounter linklets directly, but the +racket/linklet library provides access to linklet +facilities.

A single Racket module (or collection of top-level forms) is typically +implemented by multiple linklets. For example, each phase of +evaluation that exists in a module is implemented in a separate +linklet. A linklet is also used for metadata such as the module +path indexes for a module’s requires. These linklets, plus +some other metadata, are combined to form a linklet bundle. +Information in a linklet bundle is keyed by either a symbol or +a fixnum. A linklet bundle containing +linklets can be marshaled to and from a byte stream by +write and (with read-accept-compiled is enabled) +read.

When a Racket module has submodules, the linklet bundles for +the module and the submodules are grouped together in a +linklet directory. A linklet directory can have +nested linklet directories. Information in a linklet directory is +keyed by #f or a symbol, where #f must be mapped to +a linklet bundle (if anything) and each symbol must be mapped +to a linklet directory. A linklet directory can be +equivalently viewed as a mapping from a lists of symbols to a +linklet bundle. Like linklet bundles, a linklet +directory can be marshaled to and from a byte stream by +write and read; the marshaled form allows individual +linklet bundles to be loaded independently.

A linklet consists of a set of variable definitions and expressions, +an exported subset of the defined variable names, a set of variables to export +from the linklet despite having no corresponding definition, and a set +of imports that provide other variables for the linklet to use. To run +a linklet, it is instantiated as as linklet instance (or +just instance, for short). When a linklet is instantiated, +it receives other linklet instances for its imports, and it +extracts a specified set of variables that are exported from each of +the given instances. The newly created linklet instance +provides its exported variables for use by other linklets or for +direct access via instance-variable-value. A linklet +instance can be synthesized directly with make-instance.

A linklet is created by compiling an enriched S-expression +representation of its source. Since linklets exist below the layer of +macros and syntax objects, linklet compilation does not use +syntax objects. Instead, linklet compilation uses +correlated objects, which are like syntax objects +without lexical-context information and without the constraint that +content is coerced to correlated objects. Using an S-expression or +correlated object, the grammar of a linklet as recognized by +compile-linklet is

(linklet [[imported-id/renamed ...] ...]
         [exported-id/renamed ...]
  defn-or-expr ...)
 
imported-id/renamed = imported-id
  | (external-imported-id internal-imported-id)
     
exported-id/renamed = exported-id
  | (internal-exported-id external-exported-id)

Each import set [imported-id/renamed ...] refers to a single +imported instance, and each import-id/renamed corresponds to +a variable from that instance. If separate +external-imported-id and internal-imported-id are +specified, then external-imported-id is the name of the +variable as exported by the instance, and +internal-imported-id is the name used to refer to the +variable in the defn-or-exprs. For exports, separate +internal-exported-id and external-exported-id +names corresponds to the variable name as exported as referenced +in the defn-or-exprs, respectively.

The grammar of an defn-or-expr is similar to the expander’s +grammar of fully expanded expressions (see Fully Expanded Programs) +with some exceptions: quote-syntax and #%top are not allowed; +#%plain-lambda is spelled lambda; +#%plain-app is omitted (i.e., application is implicit); +lambda, case-lambda, let-values, and +letrec-values can have only a single body expression; and +numbers, booleans, strings, and byte strings are self-quoting. +Primitives are accessed directly by name, and shadowing is not allowed +within a linklet form for primitive names (see +linklet-body-reserved-symbol?), imported variables, defined +variables, or local variables.

When an exported-id/renamed has no corresponding definition +among the defn-or-exprs, then the variable is effectively +defined as uninitialized; referencing the variable will trigger +exn:fail:contract:variable, the same as referencing a +variable before it is defined. When a target instance is provided to +instantiate-linklet, any existing variable with the same name +will be left as-is, instead of set to undefined. This treatment of +uninitialized variables provides core support for top-level evaluation +where variables may be referenced and then defined in a separate +element of compilation.

Added in version 6.90.0.1 of package base.

procedure

(linklet? v)  boolean?

  v : any/c
Returns #t if v is a linklet, #f +otherwise.

procedure

(compile-linklet form    
  [name    
  import-keys    
  get-import    
  options])  linklet?
  form : (or/c correlated? any/c)
  name : any/c = #f
  import-keys : #f = #f
  get-import : #f = #f
  options : 
(listof (or/c 'serializable 'unsafe 'static 'quick
               'use-prompt 'uninterned-literal))
   = '(serializable)
(compile-linklet form    
  name    
  import-keys    
  [get-import    
  options])  
linklet? vector?
  form : (or/c correlated? any/c)
  name : any/c
  import-keys : vector?
  get-import : 
(or/c #f (any/c . -> . (values (or/c linklet? instance? #f)
                               (or/c vector? #f))))
   = #f
  options : 
(listof (or/c 'serializable 'unsafe 'static 'quick
              'use-prompt 'uninterned-literal))
   = '(serializable)
Takes an S-expression or correlated object for a +linklet form and produces a linklet. +As long as 'serializable included in options, the +resulting linklet can be marshaled to and from a byte stream when it is +part of a linklet bundle (possibly in a linklet directory).

The optional name is associated to the linklet for debugging +purposes and as the default name of the linklet’s instance.

The optional import-keys and get-import arguments +support cross-linklet optimization. If import-keys is a +vector, it must have as many elements as sets of imports in +form. If the compiler becomes interested in optimizing a +reference to an imported variable, it passes back to +get-import (if non-#f) the element of import-keys that +corresponds to the variable’s import set. The get-import +function can then return a linklet or instance that represents an instance to be +provided to the compiled linklet when it is eventually instantiated; +ensuring consistency between reported linklet or instance and the eventual +instance is up to the caller of compile-linklet. If +get-import returns #f as its first value, the +compiler will be prevented from making any assumptions about the +imported instance. The second result from get-import is an +optional vector of keys to provide transitive information on a +returned linklet’s imports (and is not allowed for a returned instance); +the returned vector must have the same +number of elements as the linklet has imports. When vector elements +are eq? and non-#f, the compiler can assume that +they correspond to the same run-time instance. A #f +value for get-import is equivalent to a function that +always returns two #f results.

When import-keys is not #f, then the compiler is +allowed to grow or shrink the set of imported instances for the +linklet. The result vector specifies the keys of the imports for the +returned linklet. Any key that is #f or a linklet instance +must be preserved intact, however.

If 'unsafe is included in options, then the linklet +is compiled in unsafe mode: uses of safe operations within +the linklet can be converted to unsafe operations on the assumption +that the relevant contracts are satisfied. For example, car +is converted to unsafe-car. Some substituted unsafe +operations may not have directly accessible names, such as the unsafe +variant of in-list that can be substituted in unsafe +mode. An unsafe operation is substituted only if its (unchecked) +contract is subsumed by the safe operation’s contract. The fact that +the linklet is compiled in unsafe mode can be exposed through +variable-reference-from-unsafe? using a variable reference +produced by a #%variable-reference form within the module +body.

If 'static is included in options, then the linklet +must be instantiated only once; if the linklet is serialized, then any +individual instance read from the serialized form must be instantiated +at most once. Compilation with 'static is intended to improve +the performance of references within the linklet to defined and +imported variables.

If 'quick is included in options, then linklet +compilation may trade run-time performance for compile-time +performance—that is, spend less time compiling the linklet, but the +resulting linklet may run more slowly.

If 'use-prompt is included in options, then +instantiating resulting linklet always wraps a prompt around each +definition and immediate expression in the linklet. Otherwise, +supplying #t as the use-prompt? argument to +instantiate-linklet may only wrap a prompt around the entire +instantiation.

If 'uninterned-literal is included in options, then +literals in form will not necessarily be interned via +datum-intern-literal when compiling or loading the linklet. +Disabling the use of datum-intern-literal can be especially +useful of the linklet includes a large string or byte string constant +that is not meant to be shared.

The symbols in options must be distinct, otherwise +exn:fail:contract exception is raised.

Changed in version 7.1.0.8 of package base: Added the 'use-prompt option.
Changed in version 7.1.0.10: Added the 'uninterned-literal option.
Changed in version 7.5.0.14: Added the 'quick option.

procedure

(recompile-linklet linklet    
  [name    
  import-keys    
  get-import    
  options])  linklet?
  linklet : linklet?
  name : any/c = #f
  import-keys : #f = #f
  get-import : #f = #f
  options : 
(listof (or/c 'serializable 'unsafe 'static 'quick
              'use-prompt 'uninterned-literal))
   = '(serializable)
(recompile-linklet linklet    
  name    
  import-keys    
  [get-import    
  options])  
linklet? vector?
  linklet : linklet?
  name : any/c
  import-keys : vector?
  get-import : 
(or/c (any/c . -> . (values (or/c linklet? #f)
                            (or/c vector? #f)))
      #f)
   = (lambda (import-key) (values #f #f))
  options : 
(listof (or/c 'serializable 'unsafe 'static 'quick
              'use-prompt 'uninterned-literal))
   = '(serializable)
Like compile-linklet, but takes an already-compiled linklet +and potentially optimizes it further.

Changed in version 7.1.0.6 of package base: Added the options argument.
Changed in version 7.1.0.8: Added the 'use-prompt option.
Changed in version 7.1.0.10: Added the 'uninterned-literal option.
Changed in version 7.5.0.14: Added the 'quick option.

procedure

(eval-linklet linklet)  linklet?

  linklet : linklet?
Returns a variant of a linklet that is prepared for JIT +compilation such that every later use of the result linklet with +instantiate-linklet shares the JIT-generated code. However, +the result of eval-linklet cannot be marshaled to a byte +stream as part of a linklet bundle, and it cannot be used with +recompile-linklet.

procedure

(instantiate-linklet linklet    
  import-instances    
  [target-instance?    
  use-prompt?])  instance?
  linklet : linklet?
  import-instances : (listof instance?)
  target-instance? : #f = #f
  use-prompt? : any/c = #t
(instantiate-linklet linklet    
  import-instances    
  target-instance    
  [use-prompt?])  any
  linklet : linklet?
  import-instances : (listof instance?)
  target-instance : instance?
  use-prompt? : any/c = #t
Instantiates linklet by running its definitions and +expressions, using the given import-instances for its +imports. The number of instances in import-instances must +match the number of import sets in linklet.

If target-instance is #f or not provided, the result +is a fresh instance for the linklet. If target-instance is an +instance, then the instance is used and modified for the linklet +definitions and expressions, and the result is the value of the last +expression in the linklet.

The linklet’s exported variables are accessible in the result instance +or in target-instance using the linklet’s external name for +each export. If target-instance is provided as +non-#f, its existing variables remain intact if they are not +modified by a linklet definition.

If use-prompt? is true, then a a prompt is wrapped +around the linklet instantiation in same ways as an expression in a +module body. If the linklet contains multiple definitions or immediate +expressions, then a prompt may or may not be wrapped around each +definition or expression; supply 'use-prompt to +compile-linklet to ensure that a prompt is used around each +definition and expression.

procedure

(linklet-import-variables linklet)  (listof (listof symbol?))

  linklet : linklet?
Returns a description of a linklet’s imports. Each element of the +result list corresponds to an import set as satisfied by a single +instance on instantiation, and each member of the set is a variable +name that is used from the corresponding imported instance.

procedure

(linklet-export-variables linklet)  (listof symbol?)

  linklet : linklet?
Returns a description of a linklet’s exports. Each element of the list +corresponds to a variable that is made available by the linklet in its +instance.

procedure

(linklet-directory? v)  boolean?

  v : any/c
Returns #t if v is a linklet directory, +#f otherwise.

Constructs a linklet directory given mappings in the form of a +hash table. Each key of content must be either a +symbol or #f, each symbol must be mapped to a linklet +directory, and #f must be mapped to a linklet bundle +or not mapped.

procedure

(linklet-directory->hash linklet-directory)

  (and/c hash? hash-eq? immutable? (not/c impersonator?))
  linklet-directory : linklet-directory?
Extracts the content of a linklet directory into a hash +table.

procedure

(linklet-bundle? v)  boolean?

  v : any/c
Returns #t if v is a linklet bundle, +#f otherwise.

procedure

(hash->linklet-bundle content)  linklet-bundle?

  content : (and/c hash? hash-eq? immutable? (not/c impersonator?))
Constructs a linklet bundle given mappings in the form of a +hash table. Each key of content must be either a +symbol or a fixnum. Values in the hash table are unconstrained, +but the intent is that they are all linklets or values that can +be recovered from write output by read.

procedure

(linklet-bundle->hash linklet-bundle)

  (and/c hash? hash-eq? immutable? (not/c impersonator?))
  linklet-bundle : linklet-bundle?
Extracts the content of a linklet bundle into a hash +table.

procedure

(linklet-body-reserved-symbol? sym)  boolean?

  sym : symbol?
Return #t if sym is a primitive name or other +identifier that is not allowed as a binding within a linklet, +#f otherwise.

Added in version 8.2.0.1 of package base.

procedure

(instance? v)  boolean?

  v : any/c
Returns #t if v is a linklet instance, +#f otherwise.

procedure

(make-instance name    
  [data    
  mode]    
  variable-name    
  variable-value ...    
  ...)  instance?
  name : any/c
  data : any/c = #f
  mode : (or/c #f 'constant 'consistent) = #f
  variable-name : symbol?
  variable-value : any/c
Constructs a linklet instance directly. Besides associating an +arbitrary name and data value to the instance, the +instance is populated with variables as specified by +variable-name and variable-value.

The optional data and mode arguments must be +provided if any variable-name and variable-value +arguments are provided. The mode argument is used as in +instance-set-variable-value! for every +variable-name.

procedure

(instance-name instance)  any/c

  instance : instance?
Returns the value associated to instance as its name—either +the first value provided to make-instance or the name of a +linklet that was instantiated to create the instance.

procedure

(instance-data instance)  any/c

  instance : instance?
Returns the value associated to instance as its data—either +the second value provided to make-instance or the default +#f.

procedure

(instance-variable-names instance)  (list symbol?)

  instance : instance?
Returns a list of all names for all variables accessible from +instance.

procedure

(instance-variable-value instance    
  name    
  [fail-k])  any
  instance : instance?
  name : symbol?
  fail-k : any/c = (lambda () (error ....))
Returns the value of the variable exported as name from +instance. If no such variable is exported, then +fail-k is used in the same way as by hash-ref.

procedure

(instance-set-variable-value! instance    
  name    
  v    
  [mode])  void?
  instance : instance?
  name : symbol?
  v : any/c
  mode : (or/c #f 'constant 'consistent) = #f
Sets or creates the variable exported as name in +instance so that its value is v, as long as the +variable does not exist already as constant. If a variable for +name exists as constant, the exn:fail:contract exception is raised.

If mode is 'constant or 'consistent, then +the variable is created or changed to be constant. Furthermore, when +the instance is reported for a linklet’s import though a +get-import callback to compile-linklet, the +compiler can assume that the variable will be constant in all future +instances that are used to satisfy a linklet’s imports.

If mode is 'consistent, when the instance is +reported though a callback to compile-linklet, the compiler +can further assume that the variable’s value will be the same for +future instances. For compilation purposes, “the same” can mean that +a procedure value will have the same arity and implementation details, +a structure type value will have the same configuration, a +marshalable constant will be equal? to the current value, and +so on.

procedure

(instance-unset-variable! instance name)  void?

  instance : instance?
  name : symbol?
Changes instance so that it does not export a variable as +name, as long as name does not exist as a constant +variable. If a variable for name exists as constant, the +exn:fail:contract exception is raised.

procedure

(instance-describe-variable! instance    
  name    
  desc-v)  void?
  instance : instance?
  name : symbol?
  desc-v : any/c
Registers information about name in instance that +may be useful for compiling linklets where the instance is return via +the get-import callback to compile-linklet. The +desc-v description can be any value; the recognized +descriptions depend on virtual machine, but may include the following:

  • `(procedure ,arity-mask) the value is always a +procedure that is not impersonated and not a structure, and its +arity in the style of procedure-arity-mask is +arity-mask.

  • `(procedure/succeeds ,arity-mask) like +`(procedure ,arity-mask), but for a procedure that +never raises an exception of otherwise captures or escapes the +calling context.

  • `(procedure/pure ,arity-mask) like +`(procedure/succeeds ,arity-mask), but with no +observable side effects, so a call to the procedure can be +reordered.

Added in version 7.1.0.8 of package base.

procedure

(variable-reference->instance varref 
  [ref-site?]) 
  (if ref-site? (or/c instance? #f symbol?) instance?)
  varref : variable-reference?
  ref-site? : any/c = #f
Extracts the instance where the variable of varref is defined +if ref-site? is #f, and returns the instance where +varref itself resides if ref-site? is true. This +notion of variable reference is the same as at the module level +and can reflect the linklet instance that implements a particular +phase of a module instance.

When ref-site? is #f, the result is #f when +varref is from (#%variable-reference) with no +identifier. The result is a symbol if varref refers to a +primitive.

procedure

(correlated? v)  boolean?

  v : any/c

procedure

(correlated-source crlt)  any

  crlt : correlated?

procedure

(correlated-line crlt)  (or/c exact-positive-integer? #f)

  crlt : correlated?

procedure

(correlated-column crlt)  (or/c exact-nonnegative-integer? #f)

  crlt : correlated?

procedure

(correlated-position crlt)  (or/c exact-positive-integer? #f)

  crlt : correlated?

procedure

(correlated-span crlt)  (or/c exact-nonnegative-integer? #f)

  crlt : correlated?

procedure

(correlated-e crlt)  any

  crlt : correlated?

procedure

(correlated->datum crlt)  any

  crlt : (or/c correlated? any/c)

procedure

(datum->correlated v [srcloc prop])  correlated?

  v : any/c
  srcloc : 
(or/c correlated? #f
      (list/c any/c
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f)
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f))
      (vector/c any/c
               (or/c exact-positive-integer? #f)
               (or/c exact-nonnegative-integer? #f)
               (or/c exact-positive-integer? #f)
               (or/c exact-nonnegative-integer? #f)))
   = #f
  prop : (or/c correlated? #f) = #f

procedure

(correlated-property crlt key val)  correlated?

  crlt : correlated?
  key : any/c
  val : any/c
(correlated-property crlt key)  any/c
  crlt : correlated?
  key : any/c

procedure

(correlated-property-symbol-keys crlt)  list?

  crlt : correlated?

Unlike datum->syntax, datum->correlated does not +recur through the given S-expression and convert pieces to +correlated objects. Instead, a correlated object is +simply wrapped around the immediate value. In contrast, +correlated->datum recurs through its argument (which is not +necessarily a correlated object) to discover any +correlated objects and convert them to plain S-expressions.

Changed in version 7.6.0.6 of package base: Added the prop argument +to datum->correlated.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/load-lang.html b/clones/docs.racket-lang.org/reference/load-lang.html new file mode 100644 index 00000000..9a1df51c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/load-lang.html @@ -0,0 +1,24 @@ + +14.3 The racket/load Language

14.3 The racket/load Language

 #lang racket/load package: base

The racket/load language supports evaluation where +each top-level form in the module body is separately passed to +eval in the same way as for load.

The namespace for evaluation shares the module registry with +the racket/load module instance, but it has a separate +top-level environment, and it is initialized with the bindings of +racket. A single namespace is created for each +instance of the racket/load module (i.e., multiple +modules using the racket/load language share a +namespace). The racket/load library exports only +#%module-begin and #%top-interaction +forms that effectively swap in the evaluation namespace and call +eval.

For example, the body of a module using racket/load can +include module forms, so that running the following module +prints 5:

#lang racket/load
 
(module m racket/base
  (provide x)
  (define x 5))
 
(module n racket/base
  (require 'm)
  (display x))
 
(require 'n)

Definitions in a module using racket/load are evaluated in +the current namespace, which means that load and +eval can see the definitions. For example, running the +following module prints 6:

#lang racket/load
 
(define x 6)
(display (eval 'x))

Since all forms within a racket/load module are +evaluated in the top level, bindings cannot be exported from the +module using provide. Similarly, since evaluation of the +module-body forms is inherently dynamic, compilation of the module +provides essentially no benefit. For these reasons, use +racket/load for interactive exploration of top-level +forms only, and not for constructing larger programs.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/local.html b/clones/docs.racket-lang.org/reference/local.html new file mode 100644 index 00000000..411b0886 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/local.html @@ -0,0 +1,9 @@ + +3.10 Local Definitions: local
On this page:
local

3.10 Local Definitions: local

 (require racket/local) package: base
The bindings documented in this section are provided by the racket/local and racket libraries, but not racket/base.

syntax

(local [definition ...] body ...+)

Like letrec-syntaxes+values, except that the bindings are +expressed in the same way as in the top-level or in a module body: +using define, define-values, define-syntax, +struct, etc. Definitions are distinguished from +non-definitions by partially expanding definition forms (see +Partial Expansion). As in the top-level or in a module +body, a begin-wrapped sequence is spliced into the sequence +of definitions.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/logging.html b/clones/docs.racket-lang.org/reference/logging.html new file mode 100644 index 00000000..514a4c02 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/logging.html @@ -0,0 +1,155 @@ + +15.5 Logging

15.5 Logging

A logger accepts events that contain information to be +logged for interested parties. A log receiver represents an +interested party that receives logged events asynchronously. Each +event has a topic and level of detail, and a log receiver subscribes to +logging events at a certain level of detail (and lower) for a specific topic or for all topics. The +levels, in increasing order of detail, are 'none, 'fatal, +'error, 'warning, 'info, and +'debug.

To help organize logged events, a logger can have a default topic and/or +a parent logger. Every event reported to a logger is propagated to +its parent (if any), and the event message is prefixed with the logger’s topic (if +any) if the message doesn’t already have a topic. Furthermore, events that are propagated +from a logger to its parent can be filtered by level and topic.

On start-up, Racket creates an initial logger that is used to +record events from the core run-time system. For example, a +'debug event is reported for each garbage collection (see +Garbage Collection). For this initial logger, two log receivers are +also created: one that writes events to the process’s original error +output port, and one that writes events to the system log. The level +of written events in each case is system-specific, and the default can +be changed through command-line flags (see Command Line) or +through environment variables:

  • If the PLTSTDERR environment variable is +defined and is not overridden by a command-line flag, it +determines the level of the log receiver that propagates +events to the original error port.

    The environment variable’s value can be a level: +none, fatal, error, +warning, info, or debug (from low detail +to high detail); all +events at the corresponding level of detail or lower are printed. After an +initial level, the value can contain +whitespace-separated specifications of the form +level@topic, which prints +events whose topics match topic only at the given +level or higher (where a topic contains any +character other than whitespace or @). Leading and +trailing whitespace is ignored. For example, the value +"error debug@GC" prints all events at the +'error level and higher, but prints events for the +topic 'GC at the 'debug level and higher +(which includes all levels).

    The default is "error".

  • If the PLTSTDOUT environment variable is +defined and is not overridden by a command-line flag, it +determines the level of the log receiver that propagates +events to the original output port. The possible values are the +same as for PLTSTDERR.

    The default is "none".

  • If the PLTSYSLOG environment variable is +defined and is not overridden by a command-line flag, it +determines the level of the log receiver that propagates +events to the system log. The possible values are the +same as for PLTSTDERR.

    The default is "none" for Unix or "error" for +Windows and Mac OS.

The current-logger parameter determines the +current logger that is used by forms such as +log-warning. On start-up, the initial value of this parameter +is the initial logger. The run-time system sometimes uses the current +logger to report events. For example, the bytecode compiler sometimes +reports 'warning events when it detects an expression that +would produce a run-time error if evaluated.

Changed in version 6.6.0.2 of package base: Prior to version 6.6.0.2, parsing +of PLTSTDERR and PLTSYSLOG was very strict. +Leading and trailing whitespace was forbidden, and anything other +than exactly one space character separating two specifications was +rejected.
Changed in version 6.90.0.17: Added PLTSTDOUT.

15.5.1 Creating Loggers

procedure

(logger? v)  boolean?

  v : any/c
Returns #t if v is a logger, #f +otherwise.

procedure

(make-logger [topic    
  parent    
  propagate-level    
  propagate-topic ...]    
  ...)  logger?
  topic : (or/c symbol? #f) = #f
  parent : (or/c logger? #f) = #f
  propagate-level : log-level/c = 'debug
  propagate-topic : (or/c #f symbol?) = #f
Creates a new logger with an optional topic and parent.

The optional propagate-level and propagate-topic +arguments constrain the events that are propagated from the new logger +to parent (when parent is not #f) in the +same way that events are described for a log receiver in +make-log-receiver. By default, all events are propagated to +parent.

Changed in version 6.1.1.3 of package base: Removed an optional argument to +specify a notification callback, +and added propagate-level and +propagate-topic constraints for +events to propagate.

procedure

(logger-name logger)  (or/c symbol? #f)

  logger : logger?
Reports logger’s default topic, if any.

parameter

(current-logger)  logger?

(current-logger logger)  void?
  logger : logger?
A parameter that determines the current logger.

syntax

(define-logger id maybe-parent)

 
maybe-parent = 
  | #:parent parent-expr
 
  parent-expr : (or/c logger? #f)
Defines log-id-fatal, +log-id-error, +log-id-warning, +log-id-info, and +log-id-debug as forms +like log-fatal, log-error,log-warning, +log-info, and log-debug. The define-logger +form also defines id-logger, which is a logger with +default topic 'id that is a child of the result of +parent-expr (if parent-expr does not produce #f), +or of (current-logger) if parent-expr not provided; the +log-id-fatal, etc. forms +use this new logger. The new logger is created when define-logger +is evaluated.

Changed in version 7.1.0.9 of package base: Added the #:parent option.

15.5.2 Logging Events

procedure

(log-message logger    
  level    
  [topic]    
  message    
  [data    
  prefix-message?])  void?
  logger : logger?
  level : log-level/c
  topic : (or/c symbol? #f) = (logger-name logger)
  message : string?
  data : any/c = #f
  prefix-message? : any/c = #t
Reports an event to logger, which in turn distributes the +information to any log receivers attached to logger or +its ancestors that are interested in events at level or +higher.

Log receivers can filter events based on topic. In +addition, if topic and prefix-message? are not +#f, then message is prefixed with the topic followed +by ": " before it is sent to receivers.

Changed in version 6.0.1.10 of package base: Added the prefix-message? argument.
Changed in version 7.2.0.7: Made the data argument optional.

procedure

(log-level? logger level [topic])  boolean?

  logger : logger?
  level : log-level/c
  topic : (or/c symbol? #f) = #f
Reports whether any log receiver attached to logger or +one of its ancestors is interested in level events (or +potentially lower) for topic. If topic is #f, +the result indicates whether a log receiver is interested in +events at level for any topic.

Use this function to avoid work generating an +event for log-message if no receiver is interested in the +information; this shortcut is built into log-fatal, +log-error, log-warning, log-info, +log-debug, and forms bound by define-logger, +however, so it should not be used with those forms.

The result of this function can change if a garbage collection +determines that a log receiver is no longer accessible (and therefore +that any event information it receives will never become accessible).

Changed in version 6.1.1.3 of package base: Added the topic argument.

procedure

(log-max-level logger [topic])  (or/c log-level/c #f)

  logger : logger?
  topic : (or/c symbol? #f) = #f
Similar to log-level?, but reports the maximum-detail level of logging for +which log-level? on logger and topic returns #t. The +result is #f if log-level? with logger and topic +currently returns #f for all levels.

Changed in version 6.1.1.3 of package base: Added the topic argument.

procedure

(log-all-levels logger)  
(list/c (or/c #f log-level/c)
        (or/c #f symbol?)
        ... ...)
  logger : logger?
Summarizes the possible results of log-max-level on all +possible interned symbols. The result list contains a sequence +of symbols and #f, where the first, third, etc., list element +corresponds to a level, and the second, fourth, etc., list element +indicates a corresponding topic. The level is the result that +log-max-level would produce for the topic, where the level for +the #f topic (which is always present in the result list) +indicates the result for any interned-symbol topic that does not +appear in the list.

The result is suitable as a sequence of arguments to +make-log-receiver (after a logger argument) to create +a new receiver for events that currently have receivers in logger.

Added in version 6.1.1.4 of package base.

procedure

(log-level-evt logger)  evt?

  logger : logger?
Creates a synchronizable event that is ready for +synchronization when the result of log-level?, +log-max-level, or log-all-levels can be different +than before log-level-evt was called. The event’s +synchronization result is the event itself.

The condition reported by the event is a conservative approximation: +the event can become ready for synchronization even if the +results of log-level?, log-max-level, and +log-all-levels are unchanged. Nevertheless, the expectation +is that events produced by log-level-evt become ready infrequently, +because they are triggered by the creation of a log receiver.

Added in version 6.1.1.4 of package base.

syntax

(log-fatal string-expr)

(log-fatal format-string-expr v ...)

syntax

(log-error string-expr)

(log-error format-string-expr v ...)

syntax

(log-warning string-expr)

(log-warning format-string-expr v ...)

syntax

(log-info string-expr)

(log-info format-string-expr v ...)

syntax

(log-debug string-expr)

(log-debug format-string-expr v ...)
Log an event with the current logger, evaluating +string-expr or (format format-string-expr v ...) +only if the logger has receivers that are interested in the event. In +addition, the current continuation’s continuation marks are +sent to the logger with the message string.

These form are convenient for using the current logger, but libraries +should generally use a logger for a specific topic—typically through +similar convenience forms generated by define-logger.

For each log-level,

(log-level string-expr)

is equivalent to

(let ([l (current-logger)])
  (when (log-level? l 'level)
    (log-message l 'level string-expr
                 (current-continuation-marks))))

while

(log-level format-string-expr v ...)

is equivalent to

(log-level (format format-string-expr v ...))

15.5.3 Receiving Logged Events

procedure

(log-receiver? v)  boolean?

  v : any/c
Returns #t if v is a log receiver, #f +otherwise.

procedure

(make-log-receiver logger level [topic ...] ...)  log-receiver?

  logger : logger?
  level : log-level/c
  topic : (or/c #f symbol?) = #f
Creates a log receiver to receive events of detail +level and lower as reported to logger and its +descendants, as long as either topic is #f or the +event’s topic matches topic.

A log receiver is a synchronizable event. It becomes +ready for synchronization when a logging event is +received, so use sync to receive a logged event. The +log receiver’s synchronization result is an immutable vector containing +four values: the level of the event as a symbol, an immutable string +for the event message, an arbitrary value that was supplied as the +last argument to log-message when the event was logged, and a +symbol or #f for the event topic.

Multiple pairs of level and topic can be provided to +indicate different specific levels for different +topics (where topic defaults to #f only for +the last given level). A level for a #f +topic applies only to events whose topic does not match any other +provided topic. If the same topic is provided multiple +times, the level provided with the last instance in the +argument list takes precedence.

15.5.4 Additional Logging Functions

The bindings documented in this section are provided by the racket/logging library, not racket/base or racket.

procedure

(log-level/c v)  boolean?

  v : any/c
Returns #t if v is a valid logging level ('none, +'fatal, 'error, 'warning, 'info, or +'debug), #f otherwise.

Added in version 6.3 of package base.

procedure

(with-intercepted-logging interceptor    
  proc    
  [#:logger logger]    
  level    
  [topic ...]    
  ...)  any
  interceptor : 
(-> (vector/c
      log-level/c
      string?
      any/c
      (or/c symbol? #f))
     any)
  proc : (-> any)
  logger : logger? = #f
  level : log-level/c
  topic : (or/c #f symbol?) = #f
Runs proc, calling interceptor on any log event that the +execution of proc emits to current-logger at the specified +levels and topics. +If #:logger is specified, intercepts events sent to that logger, +otherwise uses a new child logger of the current logger. +Returns whatever proc returns.

Example:
> (let ([warning-counter 0])
    (with-intercepted-logging
      (lambda (l)
        (when (eq? (vector-ref l 0)
                   'warning)
          (set! warning-counter (add1 warning-counter))))
      (lambda ()
        (log-warning "Warning!")
        (log-warning "Warning again!")
        (+ 2 2))
      'warning)
    warning-counter)

2

Added in version 6.3 of package base.
Changed in version 6.7.0.1: Added #:logger argument.

procedure

(with-logging-to-port port    
  proc    
  [#:logger logger]    
  level    
  [topic ...]    
  ...)  any
  port : output-port?
  proc : (-> any)
  logger : logger? = #f
  level : log-level/c
  topic : (or/c #f symbol?) = #f
Runs proc, outputting any logging that the execution of proc +emits to current-logger at the specified levels and topics. +If #:logger is specified, intercepts events sent to that logger, +otherwise uses a new child logger of the current logger. +Returns whatever proc returns.

Example:
> (let ([my-log (open-output-string)])
    (with-logging-to-port my-log
      (lambda ()
        (log-warning "Warning World!")
        (+ 2 2))
      'warning)
    (get-output-string my-log))

"Warning World!\n"

Added in version 6.3 of package base.
Changed in version 6.7.0.1: Added #:logger argument.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/magnify.png b/clones/docs.racket-lang.org/reference/magnify.png new file mode 100644 index 0000000000000000000000000000000000000000..8556e407323719a5099dd6518622cfeb86a2bf4f GIT binary patch literal 323 zcmV-J0lfZ+P)*&n3&CLE8Ne1^0)+#CL^Wwri-Lq8NEXq%q-k0@ zJAi1yKN&H1&zy6UxwEW0jm&dx^iafpgj>AK3pX>&2e`ow-qFH7F0hTe49_plQKGZp zTL +9 Pattern Matching

9 Pattern Matching

+Pattern Matching in The Racket Guide introduces pattern matching.

The match form and related forms support general pattern +matching on Racket values. See also Regular Expressions for information +on regular-expression matching on strings, bytes, and streams.

 (require racket/match) package: base
The bindings documented in this section are provided by the racket/match and racket libraries, but not racket/base.

syntax

(match val-expr clause ...)

 
clause = [pat body ...+]
  | [pat (=> id) body ...+]
  | [pat #:when cond-expr body ...+]
Finds the first pat that matches the result of +val-expr, and evaluates the corresponding bodys with +bindings introduced by pat (if any). Bindings introduced by +pat are not available in other parts of pat. +The last body +in the matching clause is evaluated in tail position with respect to +the match expression.

To find a match, the clauses are tried in order. If no +clause matches, then the exn:misc:match? exception is raised.

An optional #:when cond-expr specifies that the pattern +should only match if cond-expr produces a true value. +cond-expr is in the scope of all of the variables bound in +pat. cond-expr must not mutate the object being +matched before calling the failure procedure, otherwise the behavior +of matching is unpredictable. See also failure-cont, which is +a lower-level mechanism achieving the same ends.

Examples:
> (define (m x)
    (match x
      [(list a b c)
       #:when (= 6 (+ a b c))
       'sum-is-six]
      [(list a b c) 'sum-is-not-six]))
> (m '(1 2 3))

'sum-is-six

> (m '(2 3 4))

'sum-is-not-six

An optional (=> id) between a pat and the +bodys is bound to a failure procedure of zero +arguments. If this procedure is invoked, it escapes back to the +pattern matching expression, and resumes the matching process as if +the pattern had failed to match. The bodys must not mutate +the object being matched before calling the failure procedure, +otherwise the behavior of matching is unpredictable.

Examples:
> (define (m x)
    (match x
      [(list a b c)
       (=> exit)
       (f x exit)]
      [(list a b c) 'sum-is-not-six]))
> (define (f x exit)
    (if (= 6 (apply + x))
        'sum-is-six
        (exit)))
> (m '(1 2 3))

'sum-is-six

> (m '(2 3 4))

'sum-is-not-six

The grammar of pat is as follows, where non-italicized +identifiers are recognized symbolically (i.e., not by binding).

pat

 

::=

 

id

 

match anything, bind identifier

 

 

 |

 

(var id)

 

match anything, bind identifier

 

 

 |

 

_

 

match anything

 

 

 |

 

literal

 

match literal

 

 

 |

 

(quote datum)

 

match equal? value

 

 

 |

 

(list lvp ...)

 

match sequence of lvps

 

 

 |

 

(list-rest lvp ... pat)

 

match lvps consed onto a pat

 

 

 |

 

(list* lvp ... pat)

 

match lvps consed onto a pat

 

 

 |

 

(list-no-order pat ...)

 

match pats in any order

 

 

 |

 

(list-no-order pat ... lvp)

 

match pats in any order

 

 

 |

 

(vector lvp ...)

 

match vector of pats

 

 

 |

 

(hash-table (pat pat) ...)

 

match hash table

 

 

 |

 

(hash-table (pat pat) ...+ ooo)

 

match hash table

 

 

 |

 

(cons pat pat)

 

match pair of pats

 

 

 |

 

(mcons pat pat)

 

match mutable pair of pats

 

 

 |

 

(box pat)

 

match boxed pat

 

 

 |

 

(struct-id pat ...)

 

match struct-id instance

 

 

 |

 

(struct struct-id (pat ...))

 

match struct-id instance

 

 

 |

 

(regexp rx-expr)

 

match string

 

 

 |

 

(regexp rx-expr pat)

 

match string, result with pat

 

 

 |

 

(pregexp px-expr)

 

match string

 

 

 |

 

(pregexp px-expr pat)

 

match string, result with pat

 

 

 |

 

(and pat ...)

 

match when all pats match

 

 

 |

 

(or pat ...)

 

match when any pat match

 

 

 |

 

(not pat ...)

 

match when no pat matches

 

 

 |

 

(app expr pats ...)

 

match (expr value) output values to pats

 

 

 |

 

(? expr pat ...)

 

match if (expr value) and pats

 

 

 |

 

(quasiquote qp)

 

match a quasipattern

 

 

 |

 

derived-pattern

 

match using extension

literal

 

::=

 

#t

 

match true

 

 

 |

 

#f

 

match false

 

 

 |

 

string

 

match equal? string

 

 

 |

 

bytes

 

match equal? byte string

 

 

 |

 

number

 

match equal? number

 

 

 |

 

char

 

match equal? character

 

 

 |

 

keyword

 

match equal? keyword

 

 

 |

 

regexp

 

match equal? regexp literal

 

 

 |

 

pregexp

 

match equal? pregexp literal

lvp

 

::=

 

pat ooo

 

greedily match pat instances

 

 

 |

 

pat

 

match pat

qp

 

::=

 

literal

 

match literal

 

 

 |

 

id

 

match symbol

 

 

 |

 

(qp ...)

 

match sequences of qps

 

 

 |

 

(qp ... . qp)

 

match qps ending qp

 

 

 |

 

(qp ooo . qp)

 

match qps beginning with repeated qp

 

 

 |

 

#(qp ...)

 

match vector of qps

 

 

 |

 

#&qp

 

match boxed qp

 

 

 |

 

#s(prefab-key qp ...)

 

match prefab struct with qp fields

 

 

 |

 

,pat

 

match pat

 

 

 |

 

,@(list lvp ...)

 

match lvps, spliced

 

 

 |

 

,@(list-rest lvp ... pat)

 

match lvps plus pat, spliced

 

 

 |

 

,@'qp

 

match list-matching qp, spliced

ooo

 

::=

 

...

 

zero or more; ... is literal

 

 

 |

 

___

 

zero or more

 

 

 |

 

..k

 

k or more

 

 

 |

 

__k

 

k or more

In more detail, patterns match as follows:

  • id (excluding the reserved names _, +..., ___, +..k, and +__k for non-negative integers +k)

    Unlike in cond and case, +else is not a keyword in match.

    or (var id) +— matches anything, and binds id to the +matching values. If an id is used multiple times +within a pattern, the corresponding matches must be the same +according to (match-equality-test), except that +instances of an id in different or and +not sub-patterns are independent. The binding for id is +not available in other parts of the same pattern.

    Examples:
    > (match '(1 2 3)
        [(list a b a) (list a b)]
        [(list a b c) (list c b a)])

    '(3 2 1)

    > (match '(1 (x y z) 1)
        [(list a b a) (list a b)]
        [(list a b c) (list c b a)])

    '(1 (x y z))

    > (match #f
        [else
         (cond
           [#f 'not-evaluated]
           [else 'also-not-evaluated])])

  • _ matches anything, without binding any +identifiers.

    Example:
    > (match '(1 2 3)
        [(list _ _ a) a])

    3

  • #t, #f, string, bytes, +number, char, or (quote datum) matches an equal? constant.

    Example:
    > (match "yes"
        ["no" #f]
        ["yes" #t])

    #t

  • (list lvp ...) matches a list +of elements. In the case of (list pat ...), the pattern matches a list with as many elements as +pats, and each element must match the corresponding +pat. In the more general case, each lvp +corresponds to a “spliced” list of greedy matches.

    For spliced lists, ... and ___ +are aliases for zero or more matches. The +..k and __k +forms are also aliases, specifying k or more +matches. Pattern variables that precede these splicing +operators are bound to lists of matching forms.

    Examples:
    > (match '(1 2 3)
        [(list a b c) (list c b a)])

    '(3 2 1)

    > (match '(1 2 3)
        [(list 1 a ...) a])

    '(2 3)

    > (match '(1 2 3)
        [(list 1 a ..3) a]
        [_ 'else])

    'else

    > (match '(1 2 3 4)
        [(list 1 a ..3) a]
        [_ 'else])

    '(2 3 4)

    > (match '(1 2 3 4 5)
        [(list 1 a ..3 5) a]
        [_ 'else])

    '(2 3 4)

    > (match '(1 (2) (2) (2) 5)
        [(list 1 (list a) ..3 5) a]
        [_ 'else])

    '(2 2 2)

  • (list-rest lvp ... pat) + or (list* lvp ... pat) + similar to a list pattern, but the final + pat matches the “rest” of the list after the last + lvp. In fact, the matched value can be a non-list + chain of pairs (i.e., an “improper list”) if pat + matches non-list values.

    Examples:
    > (match '(1 2 3 . 4)
        [(list-rest a b c d) d])

    4

    > (match '(1 2 3 . 4)
        [(list-rest a ... d) (list a d)])

    '((1 2 3) 4)

  • (list-no-order pat ...) +similar to a list pattern, but the elements to +match each pat can appear in the list in any order.

    Example:
    > (match '(1 2 3)
        [(list-no-order 3 2 x) x])

    1

    Unlike other patterns, list-no-order doesn’t +allow duplicate identifiers between subpatterns. For example +the patterns (list-no-order x 1 x) and +(list-no-order x 1 x ...) both produce syntax errors.

  • (list-no-order pat ... lvp) +generalizes list-no-order to allow a pattern +that matches multiple list elements that are interspersed in +any order with matches for the other patterns.

    Example:
    > (match '(1 2 3 4 5 6)
        [(list-no-order 6 2 y ...) y])

    '(1 3 4 5)

  • (vector lvp ...) like a +list pattern, but matching a vector.

    Example:
    > (match #(1 (2) (2) (2) 5)
        [(vector 1 (list a) ..3 5) a])

    '(2 2 2)

  • (hash-table (pat pat) ...) +similar to list-no-order, but matching against +hash table’s key–value pairs.

    Example:
    > (match #hash(("a" . 1) ("b" . 2))
        [(hash-table ("b" b) ("a" a)) (list b a)])

    '(2 1)

  • (hash-table (pat pat) ...+ ooo) +— Generalizes hash-table to support a final +repeating pattern.

    Example:
    > (match #hash(("a" . 1) ("b" . 2))
        [(hash-table (key val) ...) key])

    '("b" "a")

  • (cons pat1 pat2) matches a pair value.

    Example:
    > (match (cons 1 2)
        [(cons a b) (+ a b)])

    3

  • (mcons pat1 pat2) matches a mutable pair value.

    Example:
    > (match (mcons 1 2)
        [(cons a b) 'immutable]
        [(mcons a b) 'mutable])

    'mutable

  • (box pat) matches a boxed value.

    Example:
    > (match #&1
        [(box a) a])

    1

  • (struct-id pat ...) or +(struct struct-id (pat ...)) +matches an instance of a structure type named +struct-id, where each field in the instance matches +the corresponding pat. See also struct*.

    Usually, struct-id is defined with +struct. More generally, struct-id +must be bound to expansion-time information for a structure +type (see Structure Type Transformer Binding), where the information +includes at least a predicate binding and field accessor +bindings corresponding to the number of field +pats. In particular, a module import or a +unit import with a signature containing a +struct declaration can provide the structure type +information.

    Examples:
    (struct tree (val left right))

     

    > (match (tree 0 (tree 1 #f #f) #f)
        [(tree a (tree b  _ _) _) (list a b)])

    '(0 1)

  • (struct struct-id _) +matches any instance of struct-id, without regard to +contents of the fields of the instance.

  • (regexp rx-expr) matches a +string that matches the regexp pattern produced by +rx-expr; see Regular Expressions for more information +about regexps.

    Examples:
    > (match "apple"
        [(regexp #rx"p+") 'yes]
        [_ 'no])

    'yes

    > (match "banana"
        [(regexp #rx"p+") 'yes]
        [_ 'no])

    'no

  • (regexp rx-expr pat) extends +the regexp form to further constrain the match +where the result of regexp-match is matched against +pat.

    Examples:
    > (match "apple"
        [(regexp #rx"p+(.)" (list _ "l")) 'yes]
        [_ 'no])

    'yes

    > (match "append"
        [(regexp #rx"p+(.)" (list _ "l")) 'yes]
        [_ 'no])

    'no

  • (pregexp rx-expr) or +(pregexp rx-expr pat) like the +regexp patterns, but if rx-expr +produces a string, it is converted to a pattern using +pregexp instead of regexp.

  • (and pat ...) matches if all +of the pats match. This pattern is often used as +(and id pat) to bind id +to the entire value that matches pat. The pats are +matched in the order that they appear.

    Example:
    > (match '(1 (2 3) 4)
       [(list _ (and a (list _ ...)) _) a])

    '(2 3)

  • (or pat ...) matches if any of +the pats match. Each pat must bind the same set +of identifiers.

    Example:
    > (match '(1 2)
       [(or (list a 1) (list a 2)) a])

    1

  • (not pat ...) matches when +none of the pats match, and binds no identifiers.

    Examples:
    > (match '(1 2 3)
       [(list (not 4) ...) 'yes]
       [_ 'no])

    'yes

    > (match '(1 4 3)
       [(list (not 4) ...) 'yes]
       [_ 'no])

    'no

  • (app expr pats ...) applies +expr to the value to be matched; each result of the +application is matched against one of the pats, +respectively.

    Examples:
    > (match '(1 2)
       [(app length 2) 'yes])

    'yes

    > (match "3.14"
       [(app string->number (? number? pi))
        `(I got ,pi)])

    '(I got 3.14)

    > (match '(1 2)
       [(app (lambda (v) (split-at v 1)) '(1) '(2)) 'yes])

    'yes

    > (match '(1 2 3)
       [(app (λ (ls) (apply values ls)) x y (? odd? z))
        (list 'yes x y z)])

    '(yes 1 2 3)

  • (? expr pat ...) applies +expr to the value to be matched, and checks whether +the result is a true value; the additional pats must +also match; i.e., ? combines a predicate +application and an and pattern. However, +?, unlike and, guarantees that +expr is matched before any of the pats.

    The expr procedure may be called more than once +on identical input (although this happens only rarely), +and the order in which calls to expr are +made should not be relied upon.

    Example:
    > (match '(1 3 5)
       [(list (? odd?) ...) 'yes])

    'yes

  • (quasiquote qp) introduces a +quasipattern, in which identifiers match symbols. Like the +quasiquote expression form, unquote +and unquote-splicing escape back to normal +patterns.

    Example:
    > (match '(1 2 3)
        [`(1 ,a ,(? odd? b)) (list a b)])

    '(2 3)

  • derived-pattern matches a pattern defined by a +macro extension via define-match-expander.

Note that the matching process may destructure the input multiple times, and +may evaluate expressions embedded in patterns such as (app expr pat) in arbitrary order, or multiple times. Therefore, such +expressions must be safe to call multiple times, or in an order other than they +appear in the original program.

9.1 Additional Matching Forms

syntax

(match* (val-expr ...+) clause* ...)

 
clause* = [(pat ...+) body ...+]
  | [(pat ...+) (=> id) body ...+]
  | [(pat ...+) #:when cond-expr body ...+]
Matches a sequence of values against each clause in order, matching +only when all patterns in a clause match. Each clause must have the +same number of patterns as the number of val-exprs.

Examples:
> (match* (1 2 3)
   [(_ (? number?) x) (add1 x)])

4

> (match* (15 17)
   [((? number? a) (? number? b))
    #:when (= (+ a 2) b)
    'diff-by-two])

'diff-by-two

syntax

(match/values expr clause clause ...)

If expr evaluates to n values, then match all n +values against the patterns in clause .... Each clause must contain +exactly n patterns. At least one clause is required to determine how +many values to expect from expr.

syntax

(define/match (head args)
  match*-clause ...)
 
head = id
  | (head args)
     
args = arg ...
  | arg ... . rest-id
     
arg = arg-id
  | [arg-id default-expr]
  | keyword arg-id
  | keyword [arg-id default-expr]
     
match*-clause = [(pat ...+) body ...+]
  | [(pat ...+) (=> id) body ...+]
  | [(pat ...+) #:when cond-expr body ...+]
Binds id to a procedure that is defined by pattern matching +clauses using match*. Each clause takes a sequence of +patterns that correspond to the arguments in the function header. +The arguments are ordered as they appear in the function header for +matching purposes.

Examples:
(define/match (fact n)
  [(0) 1]
  [(n) (* n (fact (sub1 n)))])

 

> (fact 5)

120

The function header may also contain optional or keyword arguments, +may have curried arguments, and may also contain a rest argument.

Examples:
(define/match ((f x) #:y [y '(1 2 3)])
  [((regexp #rx"p+") `(,a 2 3)) a]
  [(_ _) #f])

 

> ((f "ape") #:y '(5 2 3))

5

> ((f "dog"))

#f

 

(define/match (g x y . rst)
  [(0 0 '()) #t]
  [(5 5 '(5 5)) #t]
  [(_ _ _) #f])

 

> (g 0 0)

#t

> (g 5 5 5 5)

#t

> (g 1 2)

#f

syntax

(match-lambda clause ...)

Equivalent to (lambda (id) (match id clause ...)).

syntax

(match-lambda* clause ...)

Equivalent to (lambda lst (match lst clause ...)).

syntax

(match-lambda** clause* ...)

Equivalent to (lambda (args ...) (match* (args ...) clause* ...)), +where the number of args ... is computed from the number of patterns +appearing in each of the clause*.

syntax

(match-let ([pat expr] ...) body ...+)

Generalizes let to support pattern bindings. Each +expr is matched against its corresponding pat (the +match must succeed), and the bindings that pat introduces are +visible in the bodys.

Example:
> (match-let ([(list a b) '(1 2)]
              [(vector x ...) #(1 2 3 4)])
    (list b a x))

'(2 1 (1 2 3 4))

syntax

(match-let* ([pat expr] ...) body ...+)

Like match-let, but generalizes let*, so that the +bindings of each pat are available in each subsequent +expr.

Example:
> (match-let* ([(list a b) '(#(1 2 3 4) 2)]
               [(vector x ...) a])
    x)

'(1 2 3 4)

syntax

(match-let-values ([(pat ...) expr] ...) body ...+)

Like match-let, but generalizes let-values.

syntax

(match-let*-values ([(pat ...) expr] ...) body ...+)

Like match-let*, but generalizes let*-values.

syntax

(match-letrec ([pat expr] ...) body ...+)

Like match-let, but generalizes letrec.

syntax

(match-letrec-values ([(pat ...) expr] ...) body ...+)

Like match-let, but generalizes letrec-values.

Added in version 6.1.1.8 of package base.

syntax

(match-define pat expr)

Defines the names bound by pat to the values produced by +matching against the result of expr.

Examples:
> (match-define (list a b) '(1 2))
> b

2

syntax

(match-define-values (pat pats ...) expr)

Like match-define but for when expr produces multiple values. +Like match/values, it requires at least one pattern to determine the +number of values to expect.

Examples:
> (match-define-values (a b) (values 1 2))
> b

2

procedure

(exn:misc:match? v)  boolean?

  v : any/c
A predicate for the exception raised in the case of a match failure.

syntax

(failure-cont)

Continues matching as if the current pattern failed. Note that unlike +use of the => form, this does not escape the current +context, and thus should only be used in tail position with respect to +the match form.

9.2 Extending match

syntax

(define-match-expander id proc-expr)

(define-match-expander id proc-expr proc-expr)
Binds id to a match expander.

The first proc-expr sub-expression must evaluate to a + transformer that produces a pat for match. + Whenever id appears as the beginning of a pattern, this + transformer is given, at expansion time, a syntax object + corresponding to the entire pattern (including id). The + pattern is replaced with the result of the transformer.

A transformer produced by a second proc-expr sub-expression is + used when id is used in an expression context. Using the + second proc-expr, id can be given meaning both + inside and outside patterns.

Match expanders are not invoked unless id appears in the first +position in a sequence. Instead, identifiers bound by define-match-expander +are used as binding identifiers (like any other identifier) when they appear +anywhere except the first position in a sequence.

For example, to extend the pattern matcher and destructure syntax lists, +
(define (syntax-list? x)
  (and (syntax? x)
       (list? (syntax->list x))))
(define-match-expander syntax-list
  (lambda (stx)
    (syntax-case stx ()
      [(_ elts ...)
       #'(? syntax-list?
            (app syntax->list (list elts ...)))])))
(define (make-keyword-predicate keyword)
  (lambda (stx)
    (and (identifier? stx)
         (free-identifier=? stx keyword))))
(define or-keyword? (make-keyword-predicate #'or))
(define and-keyword? (make-keyword-predicate #'and))

 

> (match #'(or 3 4)
    [(syntax-list (? or-keyword?) b c)
     (list "OOORRR!" b c)]
    [(syntax-list (? and-keyword?) b c)
     (list "AAANND!" b c)])

'("OOORRR!" #<syntax:eval:69:0 3> #<syntax:eval:69:0 4>)

> (match #'(and 5 6)
    [(syntax-list (? or-keyword?) b c)
     (list "OOORRR!" b c)]
    [(syntax-list (? and-keyword?) b c)
     (list "AAANND!" b c)])

'("AAANND!" #<syntax:eval:70:0 5> #<syntax:eval:70:0 6>)

And here is an example showing how +define-match-expander-bound identifiers are +not treated specially unless they appear +in the first position of pattern sequence. Consider +this (incorrect) definition of a length function: +
(define-match-expander nil
  (λ (stx) #''())
  (λ (stx) #''()))
(define (len l)
  (match l
    [nil 0]
    [(cons hd tl) (+ 1 (len tl))]))

Because there are no parenthesis around nil, +match treats the first case as an identifier +(which matches everything) instead of a use of the match +expander and len always returns 0.

> (len nil)

0

> (len (cons 1 nil))

0

> (len (cons 1 (cons 2 nil)))

0

Match expanders accept any syntax pair whose first element is an +identifier? bound to the expander. The following example +shows a match expander which can be called with an improper syntax +list of the form (expander a b . rest). +
(define-match-expander my-vector
  (λ (stx)
    (syntax-case stx ()
      [(_ pat ...)
       #'(vector pat ...)]
      [(_ pat ... . rest-pat)
       #'(app vector->list (list-rest pat ... rest-pat))])))

 

> (match #(1 2 3 4 5)
   [(my-vector a b . rest)
     (list->vector (append rest (list a b)))])

'#(3 4 5 1 2)

Changed in version 7.7.0.2 of package base: Match expanders now allowed any syntax pair whose first element is an +identifier? bound to the expander. The example above did not work +with previous versions.

A structure type property to identify structure types that act +as match expanders like the ones created by +define-match-expander.

The property value must be an exact non-negative integer or a +procedure of one or two arguments. In the former case, the integer +designates a field within the structure that should contain a +procedure; the integer must be between 0 (inclusive) and the +number of non-automatic fields in the structure type (exclusive, not +counting supertype fields), and the designated field must also be +specified as immutable.

If the property value is a procedure of one argument, then the +procedure serves as the transformer for match expansion. If the property value is a procedure of two +arguments, then the first argument is the structure whose type has +prop:match-expander property, and the second argument is a +syntax object as for a match expander..

If the property value is a assignment transformer, then the wrapped +procedure is extracted with +set!-transformer-procedure before it is called.

This binding is provided for-syntax.

Like prop:match-expander, but for the legacy match syntax.

This binding is provided for-syntax.

procedure

(match-expander? v)  boolean?

  v : any/c

procedure

(legacy-match-expander? v)  boolean?

  v : any/c
Predicates for values which implement the appropriate match expander +properties.

procedure

(syntax-local-match-introduce stx)  syntax?

  stx : syntax?
For backward compatibility only; equivalent to syntax-local-introduce.

Changed in version 6.90.0.29 of package base: Made equivalent to syntax-local-introduce.

parameter

(match-equality-test)  (any/c any/c . -> . any)

(match-equality-test comp-proc)  void?
  comp-proc : (any/c any/c . -> . any)
A parameter that determines the comparison procedure used to check +whether multiple uses of an identifier match the “same” value. The +default is equal?.

syntax

(match/derived val-expr original-datum clause ...)

syntax

(match*/derived (val-expr ...) original-datum clause* ...)

Like match and match* respectively, but includes a +sub-expression to be used as the source for all syntax errors within the form. +For example, match-lambda expands to match/derived so that +errors in the body of the form are reported in terms of match-lambda +instead of match.

9.3 Library Extensions

syntax

(== val comparator)

(== val)
A match expander +which checks if the matched value is the same as val when +compared by comparator. If comparator is +not provided, it defaults to equal?.

Examples:
> (match (list 1 2 3)
    [(== (list 1 2 3)) 'yes]
    [_ 'no])

'yes

> (match (list 1 2 3)
    [(== (list 1 2 3) eq?) 'yes]
    [_ 'no])

'no

> (match (list 1 2 3)
    [(list 1 2 (== 3 =)) 'yes]
    [_ 'no])

'yes

syntax

(struct* struct-id ([field pat] ...))

A match pattern form that matches an instance of a structure +type named struct-id, where the field field in the +instance matches the corresponding pat. +The fields do not include those from super types.

Any field of struct-id may be omitted, and such fields can +occur in any order.

Examples:
(struct tree (val left right))
(struct tree* tree (val))

 

> (match (tree 0 (tree 1 #f #f) #f)
    [(struct* tree ([val a]
                    [left (struct* tree ([right #f] [val b]))]))
     (list a b)])

'(0 1)

> (match (tree* 0 #f #f 42)
    [(and (struct* tree* ([val a]))
          (struct* tree ([val b])))
     (list a b)])

'(42 0)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/memory-order.html b/clones/docs.racket-lang.org/reference/memory-order.html new file mode 100644 index 00000000..0b14e4e2 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/memory-order.html @@ -0,0 +1,26 @@ + +11.7 Machine Memory Order

11.7 Machine Memory Order

Unlike Racket threads, futures and places can expose the +underlying machine’s memory model, including a weak memory ordering. +For example, when a future writes to multiple slots in a mutable +vector, it’s possible on some platforms for another future to observe +the writes in a different order or not at all, unless the futures are +explicitly synchronized. Similarly, shared byte strings or +fxvectors can expose the machine’s memory model across places.

Racket ensures that a machine’s memory model is not observed in a way +that unsafely exposes the implementation of primitive datatypes. For +example, it is not possible for one future to see a partially +constructed primitive value as a result of reading a vector that is +mutated by another future.

The box-cas!, vector-cas!, +unsafe-box*-cas!, unsafe-vector*-cas!, and +unsafe-struct*-cas! operations all provide a machine-level +compare-and-set, so they can be used in ways that are specifically +supported by the a machine’s memory model. The +(memory-order-acquire) and (memory-order-release) +operations similarly constrain machine-level stores and loads. +Synchronization operations such as place messages, future +touches, and future semaphores imply suitable +machine-level acquire and release ordering.

procedure

(memory-order-acquire)  void?

procedure

(memory-order-release)  void?

Those operations implement a machine-level memory fence on platforms +where one is needed for synchronization. The +memory-order-acquire operation ensures at least a load–load +and load–store fence at the machine level, and the +memory-order-release operation ensures at least a +store–store and store–load fence at the machine level.

Added in version 7.7.0.11 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/memory.html b/clones/docs.racket-lang.org/reference/memory.html new file mode 100644 index 00000000..c9e752e6 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/memory.html @@ -0,0 +1,2 @@ + +16 Memory Management
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/mixins.html b/clones/docs.racket-lang.org/reference/mixins.html new file mode 100644 index 00000000..4677bb3e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/mixins.html @@ -0,0 +1,12 @@ + +6.5 Mixins

6.5 Mixins

syntax

(mixin (interface-expr ...) (interface-expr ...)
  class-clause ...)
Produces a mixin, which is a procedure that encapsulates a +class extension, leaving the superclass unspecified. Each time that a +mixin is applied to a specific superclass, it produces a new derived +class using the encapsulated extension.

The given class must implement interfaces produced by the first set of +interface-exprs. The result of the procedure is a subclass +of the given class that implements the interfaces produced by the +second set of interface-exprs. The class-clauses are +as for class*, to define the class extension encapsulated by +the mixin.

Evaluation of a mixin form checks that the +class-clauses are consistent with both sets of +interface-exprs.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/model.html b/clones/docs.racket-lang.org/reference/model.html new file mode 100644 index 00000000..38ddfe4c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/model.html @@ -0,0 +1,2 @@ + +1 Language Model

1 Language Model

    1.1 Evaluation Model

      1.1.1 Sub-expression Evaluation and Continuations

      1.1.2 Tail Position

      1.1.3 Multiple Return Values

      1.1.4 Top-Level Variables

      1.1.5 Objects and Imperative Update

      1.1.6 Garbage Collection

      1.1.7 Procedure Applications and Local Variables

      1.1.8 Variables and Locations

      1.1.9 Modules and Module-Level Variables

        1.1.9.1 Phases

        1.1.9.2 The Separate Compilation Guarantee

        1.1.9.3 Cross-Phase Persistent Modules

        1.1.9.4 Module Redeclarations

        1.1.9.5 Submodules

      1.1.10 Continuation Frames and Marks

      1.1.11 Prompts, Delimited Continuations, and Barriers

      1.1.12 Threads

      1.1.13 Parameters

      1.1.14 Exceptions

      1.1.15 Custodians

    1.2 Syntax Model

      1.2.1 Identifiers, Binding, and Scopes

      1.2.2 Syntax Objects

      1.2.3 Expansion (Parsing)

        1.2.3.1 Fully Expanded Programs

        1.2.3.2 Expansion Steps

        1.2.3.3 Expansion Context

        1.2.3.4 Introducing Bindings

        1.2.3.5 Transformer Bindings

        1.2.3.6 Local Binding Context

        1.2.3.7 Partial Expansion

        1.2.3.8 Internal Definitions

        1.2.3.9 Module Expansion, Phases, and Visits

        1.2.3.10 Macro-Introduced Bindings

      1.2.4 Compilation

      1.2.5 Namespaces

      1.2.6 Inferred Value Names

      1.2.7 Cross-Phase Persistent Module Declarations

    1.3 The Reader

    1.4 The Printer

    1.5 Implementations

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/modprotect.html b/clones/docs.racket-lang.org/reference/modprotect.html new file mode 100644 index 00000000..fc1a209c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/modprotect.html @@ -0,0 +1,50 @@ + +14.10 Code Inspectors

14.10 Code Inspectors

In the same way that inspectors control access to structure fields +(see Structure Inspectors), inspectors also control access to +module bindings. Inspectors used this way are code +inspectors. The default code inspector for module +bindings is determined by the current-code-inspector +parameter, instead of the current-inspector parameter.

When a module declaration is evaluated, the value of the +current-code-inspector parameter is associated with the +module declaration. When the module is invoked via require or +dynamic-require, a sub-inspector of the module’s +declaration-time inspector is created, and this sub-inspector is +associated with the module invocation. Any inspector that controls the +sub-inspector (including the declaration-time inspector and its +superior) controls the module invocation. In particular, if the value +of current-code-inspector never changes, then no control is +lost for any module invocation, since the module’s invocation is +associated with a sub-inspector of current-code-inspector.

When an inspector that controls a module invocation is installed with +current-code-inspector, it enables using +module->namespace on the module, and it enables access to the +module’s protected exports (i.e., those identifiers exported from the +module with protect-out) via dynamic-require. A +module cannot require a module that has a weaker +declaration-time code inspector.

When a module form is expanded or a namespace is +created, the value of current-code-inspector is associated +with the module or namespace’s top-level lexical information. +Syntax objects with that lexical information gain access to the +protected and unexported bindings of any module that the inspector +controls. In the case of a module, the inspector sticks with +such syntax objects even the syntax object is used in the expansion of +code in a less powerful context; furthermore, if the syntax object is +an identifier that is compiled as a variable reference, the inspector +sticks with the variable reference even if it appears in a module form +that is evaluated (i.e., declared) with a weaker inspector. When a +syntax object or variable reference is within compiled code that is +printed (see Printing Compiled Code), the associated inspector is +not preserved.

When compiled code in printed form is read back in, no +inspectors are associated with the code. When the code is +evaluated, the instantiated syntax-object literals and +module-variable references acquire value of +current-code-inspector as their inspector.

When a module instantiation is attached to multiple namespaces, +each with its own module registry, the inspector for the module +invocation can be registry-specific. The invocation inspector in a +particular module registry can be changed via +namespace-unprotect-module (but changing the inspector +requires control over the old one).

Changed in version 8.1.0.8 of package base: Added constraint against + require of a module with + a weaker code inspector.

parameter

(current-code-inspector)  inspector?

(current-code-inspector insp)  void?
  insp : inspector?
A parameter that determines an inspector to control access to +module bindings and redefinitions.

If the code inspector is changed from its original value, then +bytecode loaded by the default compiled-load handler is marked +as non-runnable.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/module.html b/clones/docs.racket-lang.org/reference/module.html new file mode 100644 index 00000000..cc6ffb6a --- /dev/null +++ b/clones/docs.racket-lang.org/reference/module.html @@ -0,0 +1,196 @@ + +3.1 Modules: module, module*, ...

3.1 Modules: module, module*, ...

+The module Form in The Racket Guide introduces module.

syntax

(module id module-path form ...)

Declares a top-level module or a submodule. For a top-level +module, if the current-module-declare-name parameter is set, +the parameter value is used for the module name and id is +ignored, otherwise (quote id) is the name of the +declared module. For a submodule, id is the name of +the submodule to be used as an element within a submod module +path. A module form is not allowed in an expression context +or internal-definition context.

+For a module-like form that works in +definitions context other than the top level or a module body, see +define-package.

The module-path form must be as for require, and it +supplies the initial bindings for the body forms. That is, it +is treated like a (require module-path) prefix before the +forms, except that the bindings introduced by +module-path can be shadowed by definitions and +requires in the module body forms.

If a single form is provided, then it is partially expanded +in a module-begin context. If the expansion leads to +#%plain-module-begin, then the body of the +#%plain-module-begin is the body of the module. If partial +expansion leads to any other primitive form, then the form is wrapped +with #%module-begin using the lexical context of the +module body; this identifier must be bound by the initial +module-path import, and its expansion must produce a +#%plain-module-begin to supply the module body. Finally, if +multiple forms are provided, they are wrapped with +#%module-begin, as in the case where a single +form does not expand to #%plain-module-begin.

After such wrapping, if any, and before any expansion, an +'enclosing-module-name property is attached to the +#%module-begin syntax object (see +Syntax Object Properties); the property’s value is a symbol +corresponding to id.

Each form is partially expanded (see +Partial Expansion) in a module context. Further +action depends on the shape of the form:

  • If it is a begin form, the sub-forms are flattened +out into the module’s body and immediately processed in place of the +begin.

  • If it is a define-syntaxes form, then the right-hand side is +evaluated (in phase 1), and the binding is immediately +installed for further partial expansion within the +module. Evaluation of the right-hand side is parameterized +to set current-namespace as in let-syntax.

  • If it is a begin-for-syntax form, then the body is +expanded (in phase 1) and evaluated. Expansion within a +begin-for-syntax form proceeds with the same +partial-expansion process as for a module body, but in a +higher phase, and saving all #%provide forms for all +phases until the end of the module’s expansion. Evaluation +of the body is parameterized to set +current-namespace as in let-syntax.

  • If the form is a #%require form, bindings are introduced +immediately, and the imported modules are instantiated or +visited as appropriate.

  • If the form is a #%provide form, then it is recorded for +processing after the rest of the body.

  • If the form is a define-values form, then the binding +is installed immediately, but the right-hand expression is not +expanded further.

  • If the form is a module form, then it is immediately +expanded and declared for the extent of the current top-level +enclosing module’s expansion.

  • If the form is a module* form, then it is not +expanded further.

  • Similarly, if the form is an expression, it is +not expanded further.

After all forms have been partially expanded this way, then +the remaining expression forms (including those on the right-hand side +of a definition) are expanded in an expression context. After all +expression forms, #%provide forms are processed in the order +in which they appear (independent of phase) in the expanded +module. Finally, all module* forms are expanded in order, so +that each becomes available for use by subsequent module* +forms; the enclosing module itself is also available for use by +module* submodules.

The scope of all imported identifiers covers the entire module body, +except for nested module and module* forms (assuming +a non-#f module-path in the latter case). +The scope of any identifier defined within the module body similarly +covers the entire module body except for such nested module +and module* forms. +The ordering of syntax definitions does not affect the scope of the +syntax names; a transformer for A can produce expressions +containing B, while the transformer for B produces +expressions containing A, regardless of the order of +declarations for A and B. However, a syntactic form +that produces syntax definitions must be defined before it is used.

No identifier can be imported or defined more than once at any +phase level within a single module, except that a definition +via define-values or define-syntaxes can shadow a +preceding import via #%require. +Every exported identifier must be imported or +defined. No expression can refer to a top-level variable. +A module* form in which the enclosing module’s bindings are visible +(i.e., a nested module* with #f instead of a module-path) +can define or import bindings that shadow the enclosing module’s bindings.

The evaluation of a module form does not evaluate the +expressions in the body of the module (except sometimes for redeclarations; +see Module Redeclarations). Evaluation merely declares a +module, whose full name depends both on id or +(current-module-declare-name).

A module body is executed only when the module is explicitly +instantiated via require or +dynamic-require. On invocation, imported modules are +instantiated in the order in which they are required +into the module (although earlier instantiations or transitive +requires can trigger the instantiation of a module before +its order within a given module). Then, expressions and definitions +are evaluated in order as they appear within the module. Each +evaluation of an expression or definition is wrapped with a +continuation prompt (see call-with-continuation-prompt) for +the default prompt tag and using a prompt handler that re-aborts +and propagates its argument to the next enclosing prompt. Each evaluation +of a definition is followed, outside of the prompt, by a check that +each of the definition’s variables has a value; if the portion of the +prompt-delimited continuation that installs values is skipped, then +the exn:fail:contract:variable? exception is raised.

Portions of a module body at higher phase levels are delimited +similarly to run-time portions. For example, portions of a module +within begin-for-syntax are delimited by a continuation +prompt both as the module is expanded and when it is visited. The +evaluation of a define-syntaxes form is delimited, but unlike +define-values, there is no check that the syntax definition +completed.

Accessing a module-level variable before it is defined signals +a run-time error, just like accessing an undefined global variable. +If a module (in its fully expanded form) does not contain a +set! for an identifier that defined within the module, then +the identifier is a constant after it is defined; its value +cannot be changed afterward, not even through reflective +mechanisms. The compile-enforce-module-constants parameter, +however, can be used to disable enforcement of constants.

When a syntax object representing a module form has a +'module-language syntax property attached, and +when the property value is a vector of three elements where the first +is a module path (in the sense of module-path?) and the +second is a symbol, then the property value is preserved in the +corresponding compiled and/or declared module. The third component of +the vector should be printable and readable, so that it can +be preserved in marshaled bytecode. The racket/base +and racket languages attach +'#(racket/language-info get-info #f) to a module +form. See also module-compiled-language-info, +module->language-info, and +racket/language-info.

See also Modules and Module-Level Variables, Module Expansion, Phases, and Visits, and +Information on Expanded Modules.

Example:
> (module duck racket/base
    (provide num-eggs quack)
    (define num-eggs 2)
    (define (quack n)
      (unless (zero? n)
        (printf "quack\n")
        (quack (sub1 n)))))

Changed in version 6.3 of package base: Changed define-syntaxes +and define-values to +shadow any preceding import, and +dropped the use of 'submodule +syntax property values on nested +module or module* +forms.

syntax

(module* id module-path form ...)

(module* id #f form ...)

Like module, but only for declaring a submodule within +a module, and for submodules that may require the enclosing module.

Instead of a module-path after id, #f +indicates that all bindings from the enclosing module are visible in +the submodule. In that case, begin-for-syntax forms that wrap +the module* form shift the phase level of the +enclosing module’s bindings relative to the submodule. The macro +expander handles such nesting by shifting the phase level of +the module* form so that its body starts at phase +level 0, expanding, and then reverting the phase level shift; +beware that this process can leave syntax objects as +'origin syntax property values out-of-sync with the +expanded module.

When a module* form has a module-path, the submodule +expansion starts by removing the scopes of the enclosing +module, the same as the module form. No shifting compensates +for any begin-for-syntax forms that may wrap the submodule.

syntax

(module+ id form ...)

Declares and/or adds to a submodule named id.

Each addition for id is combined in order to form the entire +submodule using (module* id #f ....) at the end of the +enclosing module. If there is only one module+ for a given +id, then (module+ id form ...) is equivalent to +(module* id #f form ...), but still moved to the end of the +enclosing module.

When a module contains multiple submodules declared with +module+, then the relative order of the initial +module+ declarations for each submodule determines the +relative order of the module* declarations at the end of the +enclosing module.

A submodule must not be defined using module+ and +module or module*. That is, if a submodule is made +of module+ pieces, then it must be made only of +module+ pieces.

syntax

(#%module-begin form ...)

Legal only in a module begin context, and handled by the +module and module* forms.

The #%module-begin form of racket/base wraps +every top-level expression to print non-#<void> results using +current-print.

The #%module-begin form of racket/base also +declares a configure-runtime submodule (before any other +form), unless some form is either an immediate +module or module* form with the name +configure-runtime. If a configure-runtime submodule +is added, the submodule calls the configure function of +racket/runtime-config.

syntax

(#%printing-module-begin form ...)

Legal only in a module begin context.

Like #%module-begin, but without adding a +configure-runtime submodule.

syntax

(#%plain-module-begin form ...)

Legal only in a module begin context, and handled by the +module and module* forms.

syntax

(#%declare declaration-keyword ...)

 
declaration-keyword = #:cross-phase-persistent
  | #:empty-namespace
  | #:unsafe
  | #:realm identifier
Declarations that affect run-time or reflective properties of the +module:

  • #:cross-phase-persistent declares the +module as cross-phase persistent, and reports a syntax +error if the module does not meet the import or syntactic +constraints of a cross-phase persistent module.

  • #:empty-namespace declares that + module->namespace for this module should produce a + namespace with no bindings; limiting namespace support in this + way can reduce the lexical information that + otherwise must be preserved for the module.

  • #:unsafe declares that the module can be + compiled without checks that could trigger + exn:fail:contract, and the resulting behavior is + unspecified for an evaluation where exn:fail:contract + should have been raised; see also Unsafe Operations. For + example, a use of car can be compiled as a use of + unsafe-car, and the behavior is unspecified is + unsafe-car is applied to a non-pair. The + #:unsafe declaration keyword is allowed only when the + current code inspector is the initial one. Macros can + generate conditionally unsafe code, depending on the expansion + context, by expanding to a use of + (variable-reference-from-unsafe? (#%variable-reference)).

  • #:realm identifier declares that + the module and any procedures within the module are given a + realm that is the symbol form of identifier, effectively + overriding the value of current-compile-realm.

A #%declare form must appear in a module +context or a module-begin context. Each +declaration-keyword can be declared at most once within a +module body.

Changed in version 6.3 of package base: Added #:empty-namespace.
Changed in version 7.9.0.5: Added #:unsafe.
Changed in version 8.4.0.2: Added #:realm.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/mpairs.html b/clones/docs.racket-lang.org/reference/mpairs.html new file mode 100644 index 00000000..32a776fc --- /dev/null +++ b/clones/docs.racket-lang.org/reference/mpairs.html @@ -0,0 +1,20 @@ + +4.11 Mutable Pairs and Lists

4.11 Mutable Pairs and Lists

A mutable pair is like a pair created by cons, but +it supports set-mcar! and set-mcdr! mutation +operations to change the parts of the mutable pair (like traditional Lisp and +Scheme pairs).

A mutable list is analogous to a list created with pairs, but +instead created with mutable pairs.

A mutable pair is not a pair; they are completely +separate datatypes. Similarly, a mutable list is not a +list, except that the empty list is also the empty mutable +list. Instead of programming with mutable pairs and mutable lists, +data structures such as pairs, lists, and hash tables are practically +always better choices.

A mutable list can be used as a single-valued sequence (see +Sequences). The elements of the mutable list serve as elements +of the sequence. See also in-mlist.

4.11.1 Mutable Pair Constructors and Selectors

procedure

(mpair? v)  boolean?

  v : any/c
Returns #t if v is +a mutable pair, #f otherwise.

procedure

(mcons a d)  mpair?

  a : any/c
  d : any/c
Returns a newly allocated +mutable pair whose first +element is a and second element is d.

procedure

(mcar p)  any/c

  p : mpair?
Returns the first element of the +mutable pair p.

procedure

(mcdr p)  any/c

  p : mpair?
Returns the second element of the +mutable pair p.

procedure

(set-mcar! p v)  void?

  p : mpair?
  v : any/c
Changes the mutable pair p so that its first element is +v.

procedure

(set-mcdr! p v)  void?

  p : mpair?
  v : any/c
Changes the mutable pair p so that its second element is +v.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/mzlib_class.html b/clones/docs.racket-lang.org/reference/mzlib_class.html new file mode 100644 index 00000000..dcff48de --- /dev/null +++ b/clones/docs.racket-lang.org/reference/mzlib_class.html @@ -0,0 +1,29 @@ + +6 Classes and Objects

6 Classes and Objects

+Classes and Objects in The Racket Guide introduces classes and objects.

 (require racket/class) package: base
The bindings documented in this section are provided by the racket/class and racket libraries, but not racket/base.

A class specifies

  • a collection of fields;

  • a collection of methods;

  • initial value expressions for the fields; and

  • initialization variables that are bound to initialization +arguments.

In the context of the class system, an object is a +collection of bindings for fields that are instantiated according to a +class description.

The class system allows a program to define a new class (a +derived class) in terms of an existing class (the +superclass) using inheritance, overriding, and augmenting:

  • inheritance: An object of a derived class supports +methods and instantiates fields declared by the derived class’s +superclass, as well as methods and fields declared in the derived +class expression.

  • overriding: Some methods declared in a superclass can +be replaced in the derived class. References to the overridden method +in the superclass use the implementation in the derived class.

  • augmenting: Some methods declared in a superclass can +be merely extended in the derived class. The superclass method +specifically delegates to the augmenting method in the derived class.

An interface is a collection of method names to be +implemented by a class, combined with a derivation requirement. A +class implements an interface when it

  • declares (or inherits) a public method for each variable in the +interface;

  • is derived from the class required by the interface, if any; and

  • specifically declares its intention to implement the interface.

A class can implement any number of interfaces. A derived class +automatically implements any interface that its superclass +implements. Each class also implements an implicitly-defined interface +that is associated with the class. The implicitly-defined interface +contains all of the class’s public method names, and it requires that +all other implementations of the interface are derived from the class.

A new interface can extend one or more interfaces with +additional method names; each class that implements the extended +interface also implements the original interfaces. The derivation +requirements of the original interface must be consistent, and the +extended interface inherits the most specific derivation requirement +from the original interfaces.

Classes, objects, and interfaces are all values. However, a class or +interface is not an object (i.e., there are no “meta-classes” or +“meta-interfaces”).

    6.1 Creating Interfaces

    6.2 Creating Classes

      6.2.1 Initialization Variables

      6.2.2 Fields

      6.2.3 Methods

        6.2.3.1 Method Definitions

        6.2.3.2 Inherited and Superclass Methods

        6.2.3.3 Internal and External Names

    6.3 Creating Objects

    6.4 Field and Method Access

      6.4.1 Methods

      6.4.2 Fields

      6.4.3 Generics

    6.5 Mixins

    6.6 Traits

    6.7 Object and Class Contracts

    6.8 Object Equality and Hashing

    6.9 Object Serialization

    6.10 Object Printing

    6.11 Object, Class, and Interface Utilities

    6.12 Surrogates

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/mzlib_unit.html b/clones/docs.racket-lang.org/reference/mzlib_unit.html new file mode 100644 index 00000000..cfd8244e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/mzlib_unit.html @@ -0,0 +1,10 @@ + +7 Units

7 Units

+Units in The Racket Guide introduces units.

Units organize a program into separately compilable and +reusable components. The imports and exports of a unit are grouped +into a signature, which can include “static” information +(such as macros) in addition to placeholders for run-time values. +Units with suitably matching signatures can be linked +together to form a larger unit, and a unit with no imports can be +invoked to execute its body.

 (require racket/unit) package: base
The bindings documented in this section are provided by the racket/unit and racket libraries, but not racket/base. The +racket/unit module name can be used as a language name +with #lang; see Single-Unit Modules.

    7.1 Creating Units

    7.2 Invoking Units

    7.3 Linking Units and Creating Compound Units

    7.4 Inferred Linking

    7.5 Generating A Unit from Context

    7.6 Structural Matching

    7.7 Extending the Syntax of Signatures

    7.8 Unit Utilities

    7.9 Unit Contracts

    7.10 Single-Unit Modules

    7.11 Single-Signature Modules

    7.12 Transformer Helpers

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/networking.html b/clones/docs.racket-lang.org/reference/networking.html new file mode 100644 index 00000000..b0cb6197 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/networking.html @@ -0,0 +1,2 @@ + +15.3 Networking

15.3 Networking

    15.3.1 TCP

    15.3.2 UDP

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/notation.html b/clones/docs.racket-lang.org/reference/notation.html new file mode 100644 index 00000000..1ff3ade5 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/notation.html @@ -0,0 +1,113 @@ + +2 Notation for Documentation

2 Notation for Documentation

This chapter introduces essential terminology and notation that is +used throughout Racket documentation.

2.1 Notation for Module Documentation

Since Racket programs are organized into modules, documentation +reflects that organization with an annotation at the beginning of a +section or subsection that describes the bindings that a particular +module provides.

For example, the section that describes the functionality provided by +racket/list starts

 (require racket/list) package: base

Instead of require, some modules are introduced with +#lang:

 #lang racket/base package: base

Using #lang means that the module is normally used as the +language of a whole module—that is, by a module that starts +#lang followed by the language—instead of imported with +require. Unless otherwise specified, however, a module name +documented with #lang can also be used with require to +obtain the language’s bindings.

The module annotation also shows the +package +that the module belongs to on the right-hand side. For more details +about packages, see +Package Management in Racket.

Sometimes, a module specification appears at the beginning of a +document or at the start of a section that contains many subsections. +The document’s section or section’s subsections are meant to +“inherit” the module declaration of the enclosing document or +section. Thus, bindings documented in The Racket Reference are available from +racket and racket/base unless otherwise +specified in a section or subsection.

2.2 Notation for Syntactic Form Documentation

+Notation in The Racket Guide introduces this notation for syntactic forms.

Syntactic forms are specified with a grammar. Typically, the grammar +starts with an open parenthesis followed by the syntactic form’s name, +as in the grammar for if:

syntax

(if test-expr then-expr else-expr)

Since every form is expressed in terms of syntax +objects, parentheses in a grammar specification indicate a syntax +object wrapping a list, and the leading if is an identifier +that starts the list whose binding is the if binding +of the module being documented—in this case, +racket/base. Square brackets in the grammar indicate +a syntax-object list in the same way as parentheses, but in +places square brackets are normally used by convention in a program’s +source.

Italic identifiers in the grammar are metavariables +that correspond to other grammar productions. Certain metavariable +names have implicit grammar productions:

  • A metavariable that ends in id stands for an +identifier.

  • A metavariable that ends in keyword stands +for a syntax-object keyword.

  • A metavariable that ends with expr stands for any +form, and the form will be parsed as an expression.

  • A metavariable that ends with body stands for any +form; the form will be parsed as either a local definition or +an expression. A body can parse as a definition only +if it is not preceded by any expression, and the last +body must be an expression; see also +Internal Definitions.

  • A metavariable that ends with datum stands for any +form, and the form is normally uninterpreted (e.g., +quoted).

  • A metavariable that ends with number or +boolean stands for any syntax-object (i.e., +literal) number or boolean, respectively.

In a grammar, form ... stands for any number of forms +(possibly zero) matching form, while form ...+ +stands for one or more forms matching form.

Metavariables without an implicit grammar are defined by productions +alongside the syntactic form’s overall grammar. For example, in

syntax

(lambda formals body ...+)

 
formals = id
  | (id ...)
  | (id ...+ . rest-id)

the formals metavariable stands for either an +identifier, zero or more identifiers in a +syntax-object list, or a syntax object corresponding to +a chain of one or more pairs where the chain ends in an +identifier instead of an empty list.

Some syntactic forms have multiple top-level grammars, in which case +the documentation of the syntactic forms shows multiple grammars. For +example,

syntax

(init-rest id)

(init-rest)

indicates that init-rest can either be alone in its +syntax-object list or followed by a single identifier.

Finally, a grammar specification that includes expr +metavariables may be augmented with run-time contracts on some +of the metavariables, which indicate a predicate that the result of +the expression must satisfy at run time. For example,

syntax

(parameterize ([parameter-expr value-expr] ...)
  body ...+)
 
  parameter-expr : parameter?

indicates that the result of each parameter-expr must be a +value v for which (parameter? v) returns true.

2.3 Notation for Function Documentation

Procedures and other values are described using a notation based on +contracts. In essence, these contracts describe the interfaces of +the documented library using Racket predicates and expressions.

For example, the following is the header of the definition of a +typical procedure:

procedure

(char->integer char)  exact-integer?

  char : char?

The function being defined, char->integer, is typeset as if it +were being applied. The metavariables that come after the function name +stand in for arguments. The white text in the corner identifies the +kind of value that is being documented.

Each metavariable is described with a contract. In the preceding +example, the metavariable char has the contract +char?. This contract specifies that any argument +char that answers true to the char? predicate is +valid. The documented function may or may not actually check this +property, but the contract signals the intent of the implementer.

The contract on the right of the arrow, exact-integer? in this case, +specifies the expected result that is produced by the function.

Contract specifications can be more expressive than just names of +predicates. Consider the following header for argmax:

procedure

(argmax proc lst)  any

  proc : (-> any/c real?)
  lst : (and/c pair? list?)

The contract (-> any/c real?) denotes a function contract specifying +that proc’s argument can be any single value and the result should be +a real number. The contract (and/c pair? list?) for lst +specifies that lst should pass both pair? and list? +(i.e., that it is a non-empty list).

Both -> and and/c are examples of contract combinators. +Contract combinators such as or/c, cons/c, listof, +and others are used throughout the documentation. Clicking on the hyperlinked +combinator name will provide more information on its meaning.

A Racket function may be documented as having one or more optional arguments. +The read function is an example of such a function:

procedure

(read [in])  any

  in : input-port? = (current-input-port)

The brackets surrounding the in argument in the application +syntax indicates that it is an optional argument.

The header for read specifies a contract for the parameter +in as usual. To the right of the contract, it also specifies +a default value (current-input-port) that is used if +read is called with no arguments.

Functions may also be documented as accepting mandatory or optional +keyword-based arguments. For example, the sort function has +two optional, keyword-based arguments:

procedure

(sort lst    
  less-than?    
  [#:key extract-key    
  #:cache-keys? cache-keys?])  list?
  lst : list?
  less-than? : (any/c any/c . -> . any/c)
  extract-key : (any/c . -> . any/c) = (lambda (x) x)
  cache-keys? : boolean? = #f

The brackets around the extract-key and +cache-keys? arguments indicate that they are optional as +before. The contract section of the header shows the default values +that are provided for these keyword arguments.

2.4 Notation for Structure Type Documentation

A structure type is also documented using contract notation:

struct

(struct color (red green blue alpha))

  red : (and/c natural-number/c (<=/c 255))
  green : (and/c natural-number/c (<=/c 255))
  blue : (and/c natural-number/c (<=/c 255))
  alpha : (and/c natural-number/c (<=/c 255))

The structure type is typeset as it were declared in +the source code of a program using the struct form. +Each field of the structure is documented with a corresponding +contract that specifies the values that are accepted for that field.

In the example above, the structure type color has +four fields: red, green, blue, +and alpha. The constructor for the structure type +accepts field values that satisfy +(and/c natural-number/c (<=/c 255)), i.e., non-negative +exact integers up to 255.

Additional keywords may appear after the field names in the +documentation for a structure type:

struct

(struct data-source (connector args extensions)
    #:mutable)
  connector : (or/c 'postgresql 'mysql 'sqlite3 'odbc)
  args : list?
  extensions : (listof (list/c symbol? any/c))

Here, the #:mutable keyword indicates that the fields of +instances of the data-source structure type can be +mutated with their respective setter functions.

2.5 Notation for Parameter Documentation

A parameter is documented the same way as a function:

parameter

(current-command-line-arguments)  (vectorof string?)

(current-command-line-arguments argv)  void?
  argv : (vectorof (and/c string? immutable?))

Since parameters can be referenced or set, there are two entries in the +header above. Calling current-command-line-arguments with no +arguments accesses the parameter’s value, which must be a vector whose elements +pass both string? and immutable?. Calling +current-command-line-arguments with a single argument +sets the parameter’s value, where the value must be a vector whose +elements pass string? (and a guard on the parameter +coerces the strings to immutable form, if necessary).

2.6 Notation for Other Documentation

Some libraries provide bindings to constant values. These values are +documented with a separate header:

value

object% : class?

The racket/class library provides the object% +value, which is the root of the class hierarchy in Racket. Its +documentation header just indicates that it is a value that satisfies +the predicate class?.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/number-types.html b/clones/docs.racket-lang.org/reference/number-types.html new file mode 100644 index 00000000..b60023ca --- /dev/null +++ b/clones/docs.racket-lang.org/reference/number-types.html @@ -0,0 +1,28 @@ + +4.3.1 Number Types
4.3.1 Number Types

procedure

(number? v)  boolean?

  v : any/c
Returns #t if v + is a number, #f otherwise.

Examples:
> (number? 1)

#t

> (number? 2+3i)

#t

> (number? "hello")

#f

> (number? +nan.0)

#t

procedure

(complex? v)  boolean?

  v : any/c
Returns (number? v), +because all numbers are complex numbers.

procedure

(real? v)  boolean?

  v : any/c
Returns #t if v is + a real number, #f otherwise.

Examples:
> (real? 1)

#t

> (real? +inf.0)

#t

> (real? 2+3i)

#f

> (real? 2.0+0.0i)

#f

> (real? "hello")

#f

procedure

(rational? v)  boolean?

  v : any/c
Returns #t if + v is a rational number, #f otherwise.

Examples:
> (rational? 1)

#t

> (rational? +inf.0)

#f

> (rational? "hello")

#f

procedure

(integer? v)  boolean?

  v : any/c
Returns #t if v + is a number that is an integer, #f otherwise.

Examples:
> (integer? 1)

#t

> (integer? 2.3)

#f

> (integer? 4.0)

#t

> (integer? +inf.0)

#f

> (integer? 2+3i)

#f

> (integer? "hello")

#f

procedure

(exact-integer? v)  boolean?

  v : any/c
Returns (and (integer? v) (exact? v)).

Examples:
> (exact-integer? 1)

#t

> (exact-integer? 4.0)

#f

procedure

(exact-nonnegative-integer? v)  boolean?

  v : any/c
Returns (and (exact-integer? v) (not (negative? v))).

Examples:

procedure

(exact-positive-integer? v)  boolean?

  v : any/c
Returns (and (exact-integer? v) (positive? v)).

Examples:

procedure

(inexact-real? v)  boolean?

  v : any/c
Returns (and (real? v) (inexact? v)).

procedure

(fixnum? v)  boolean?

  v : any/c
Return #t if v is a fixnum, #f +otherwise.

Note: the result of this function is platform-dependent, so using it in +syntax transformers can lead to platform-dependent bytecode files. +See also fixnum-for-every-system?.

procedure

(flonum? v)  boolean?

  v : any/c
Return #t if v is a flonum, #f +otherwise.

procedure

(double-flonum? v)  boolean?

  v : any/c
Identical to flonum?.

procedure

(single-flonum? v)  boolean?

  v : any/c
Return #t if +v is a single-flonum (i.e., a single-precision +floating-point number), #f otherwise.

Returns #t if single-flonums are supported on +the current platform, #f otherwise.

Currently, single-flonum-available? produces #t when +(system-type 'vm) produces 'racket, and +single-flonum-available? produces #f otherwise.

If the result is #f, then single-flonum? also +produces #f for all arguments.

Added in version 7.3.0.5 of package base.

procedure

(zero? z)  boolean?

  z : number?
Returns (= 0 z).

Examples:
> (zero? 0)

#t

> (zero? -0.0)

#t

procedure

(positive? x)  boolean?

  x : real?
Returns (> x 0).

Examples:
> (positive? 10)

#t

> (positive? -10)

#f

> (positive? 0.0)

#f

procedure

(negative? x)  boolean?

  x : real?
Returns (< x 0).

Examples:
> (negative? 10)

#f

> (negative? -10)

#t

> (negative? -0.0)

#f

procedure

(even? n)  boolean?

  n : integer?
Returns (zero? (modulo n 2)).

Examples:
> (even? 10.0)

#t

> (even? 11)

#f

> (even? +inf.0)

even?: contract violation

  expected: integer?

  given: +inf.0

procedure

(odd? n)  boolean?

  n : integer?
Returns (not (even? n)).

Examples:
> (odd? 10.0)

#f

> (odd? 11)

#t

> (odd? +inf.0)

odd?: contract violation

  expected: integer?

  given: +inf.0

procedure

(exact? z)  boolean?

  z : number?
Returns #t if z + is an exact number, #f otherwise.

Examples:
> (exact? 1)

#t

> (exact? 1.0)

#f

procedure

(inexact? z)  boolean?

  z : number?
Returns #t if z + is an inexact number, #f otherwise.

Examples:
> (inexact? 1)

#f

> (inexact? 1.0)

#t

procedure

(inexact->exact z)  exact?

  z : number?
Coerces z to an + exact number. If z is already exact, it is returned. If z + is +inf.0, -inf.0, +nan.0, + +inf.f, -inf.f, or +nan.f, then the + exn:fail:contract exception is raised.

Examples:

procedure

(exact->inexact z)  inexact?

  z : number?
Coerces z to an + inexact number. If z is already inexact, it is returned.

Examples:
> (exact->inexact 1)

1.0

> (exact->inexact 1.0)

1.0

procedure

(real->single-flonum x)  single-flonum?

  x : real?
Coerces x +to a single-precision floating-point number. If x is already +a single-precision floating-point number, it is returned.

procedure

(real->double-flonum x)  flonum?

  x : real?
Coerces x +to a double-precision floating-point number. If x is already +a double-precision floating-point number, it is returned.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/numbers.html b/clones/docs.racket-lang.org/reference/numbers.html new file mode 100644 index 00000000..9e6d638f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/numbers.html @@ -0,0 +1,71 @@ + +4.3 Numbers

4.3 Numbers

+Numbers in The Racket Guide introduces numbers.

All numbers are complex numbers. Some of them are +real numbers, and all of the real numbers that can be +represented are also rational numbers, except for ++inf.0 (positive infinity), ++inf.f (single-precision variant, when +enabled via read-single-flonum), +-inf.0 (negative infinity), +-inf.f (single-precision variant, when +enabled), +nan.0 (not-a-number), and ++nan.f (single-precision variant, when +enabled). Among the rational numbers, some are integers, +because round applied to the number produces the same number.

+See Reading Numbers for information on the +syntax of number literals.

Orthogonal to those categories, each number is also either an +exact number or an inexact number. Unless +otherwise specified, computations that involve an inexact number +produce inexact results. Certain operations on inexact numbers, +however, produce an exact number, such as multiplying an inexact +number with an exact 0. Operations that mathematically produce +irrational numbers for some rational arguments (e.g., sqrt) may +produce inexact results even for exact arguments.

In the case of complex numbers, either the real and imaginary parts +are both exact or inexact with the same precision, or the number has +an exact zero real part and an inexact imaginary part; a complex +number with an exact zero imaginary part is a real number.

Inexact real numbers are implemented as double-precision +IEEE floating-point numbers, also known as +flonums, or as single-precision IEEE floating-point numbers, +also known as single-flonums. Single-flonums are +supported only when (single-flonum-available?) reports +#t. Although we write +inf.f, +-inf.f, and +nan.f to mean +single-flonums, those forms read as double-precision flonums by +default, since read-single-flonum is #f by default. +When single-flonums are supported, inexact numbers are still +represented as flonums by default, and single precision is used only +when a computation starts with single-flonums.

Inexact numbers can be coerced to exact form, except for the inexact +numbers +inf.0, +inf.f, +-inf.0, -inf.f, +nan.0, and +nan.f, which +have no exact form. Dividing a +number by exact zero raises an exception; dividing a non-zero number +other than +nan.0 or +nan.f by an inexact zero returns +inf.0, ++inf.f, -inf.0 +or -inf.f, depending on the sign and precision of the dividend. The ++nan.0 value is not = to itself, but +nan.0 +is eqv? to itself, and +nan.f is similarly eqv? but +not = to itself. Conversely, (= 0.0 -0.0) is +#t, but (eqv? 0.0 -0.0) is #f, and the +same for 0.0f0 and -0.0f0 (which are single-precision variants). The datum +-nan.0 refers to the same constant as +nan.0, +and -nan.f is the same as +nan.f.

Calculations with infinities produce results consistent with IEEE +double- or single-precision floating point where IEEE specifies the result; in +cases where IEEE provides no specification, +the result corresponds to the limit approaching +infinity, or +nan.0 or +nan.f if no such limit exists.

The precision and size of exact numbers is limited only by available +memory (and the precision of operations that can produce irrational +numbers). In particular, adding, multiplying, subtracting, and +dividing exact numbers always produces an exact result.

A fixnum is an exact integer whose two’s complement +representation fits into 30 or 31 bits (depending on the Racket variant) +on a 32-bit platform or 61 or 63 bits (depending on the Racket variant) on a +64-bit platform. No allocation is required when computing +with fixnums. See also the racket/fixnum module, below.

Two fixnums that are = are also the same +according to eq?. Otherwise, the result of eq? +applied to two numbers is undefined, except that numbers produced +by the default reader in read-syntax mode are interned and therefore eq? +when they are eqv?.

Two real numbers are eqv? when they are both inexact with the same precision or both +exact, and when they are = (except for +nan.0, +nan.f, +0.0, +0.0f0, -0.0, and -0.0f0, as noted above). +Two complex numbers are eqv? when their real and imaginary parts are eqv?. +Two numbers are equal? when they are eqv?.

See Reading Numbers + for information on reading + numbers and Printing Numbers + for information on printing numbers.

    4.3.1 Number Types

    4.3.2 Generic Numerics

      4.3.2.1 Arithmetic

      4.3.2.2 Number Comparison

      4.3.2.3 Powers and Roots

      4.3.2.4 Trigonometric Functions

      4.3.2.5 Complex Numbers

      4.3.2.6 Bitwise Operations

      4.3.2.7 Random Numbers

      4.3.2.8 Other Randomness Utilities

      4.3.2.9 Number–String Conversions

      4.3.2.10 Extra Constants and Functions

    4.3.3 Flonums

      4.3.3.1 Flonum Arithmetic

      4.3.3.2 Flonum Vectors

    4.3.4 Fixnums

      4.3.4.1 Fixnum Arithmetic

      4.3.4.2 Fixnum Vectors

      4.3.4.3 Fixnum Range

    4.3.5 Extflonums

      4.3.5.1 Extflonum Arithmetic

      4.3.5.2 Extflonum Constants

      4.3.5.3 Extflonum Vectors

      4.3.5.4 Extflonum Byte Strings

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/objcreation.html b/clones/docs.racket-lang.org/reference/objcreation.html new file mode 100644 index 00000000..fdcf7485 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/objcreation.html @@ -0,0 +1,53 @@ + +6.3 Creating Objects

6.3 Creating Objects

The make-object procedure creates a new object with +by-position initialization arguments, the new form +creates a new object with by-name initialization arguments, and +the instantiate form creates a new object with both +by-position and by-name initialization arguments.

All fields in the newly created object are initially bound to the +special #<undefined> value (see +Void). Initialization variables with default value +expressions (and no provided value) are also initialized to +#<undefined>. After argument values are assigned to +initialization variables, expressions in field clauses, +init-field clauses with no provided argument, +init clauses with no provided argument, private field +definitions, and other expressions are evaluated. Those +expressions are evaluated as they appear in the class expression, +from left to right.

Sometime during the evaluation of the expressions, +superclass-declared initializations must be evaluated once by +using the super-make-object procedure, +super-new form, or super-instantiate form.

By-name initialization arguments to a class that have no matching +initialization variable are implicitly added as by-name arguments +to a super-make-object, super-new, or +super-instantiate invocation, after the explicit +arguments. If multiple initialization arguments are provided for +the same name, the first (if any) is used, and the unused +arguments are propagated to the superclass. (Note that converted +by-position arguments are always placed before explicit by-name +arguments.) The initialization procedure for the +object% class accepts zero initialization arguments; if +it receives any by-name initialization arguments, then +exn:fail:object exception is raised.

If the end of initialization is reached for any class in the +hierarchy without invoking the superclass’s initialization, the +exn:fail:object exception is raised. Also, if superclass initialization is +invoked more than once, the exn:fail:object exception is raised.

Fields inherited from a superclass are not initialized until the +superclass’s initialization procedure is invoked. In contrast, +all methods are available for an object as soon as the object is +created; the overriding of methods is not affected by +initialization (unlike objects in C++).

procedure

(make-object class init-v ...)  object?

  class : class?
  init-v : any/c
Creates an instance of class. The init-vs are +passed as initialization arguments, bound to the initialization +variables of class for the newly created object as +described in Initialization Variables. If class is not a +class, the exn:fail:contract exception is raised.

syntax

(new class-expr (id by-name-expr) ...)

Creates an instance of the value of class-expr (which +must be a class), and the value of each by-name-expr is +provided as a by-name argument for the corresponding +id.

syntax

(instantiate class-expr (by-pos-expr ...) (id by-name-expr) ...)

Creates an instance of the value of class-expr (which +must be a class), and the values of the by-pos-exprs are +provided as by-position initialization arguments. In addition, +the value of each by-name-expr is provided as a by-name +argument for the corresponding id.

Produces a procedure that takes by-position arguments an invokes +superclass initialization. See Creating Objects for more +information.

syntax

(super-instantiate (by-pos-expr ...) (id by-expr ...) ...)

Invokes superclass initialization with the specified by-position and +by-name arguments. See Creating Objects for more +information.

syntax

(super-new (id by-name-expr ...) ...)

Invokes superclass initialization with the specified by-name +arguments. See Creating Objects for more information.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/objectequality.html b/clones/docs.racket-lang.org/reference/objectequality.html new file mode 100644 index 00000000..82c69240 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/objectequality.html @@ -0,0 +1,31 @@ + +6.8 Object Equality and Hashing

6.8 Object Equality and Hashing

By default, objects that are instances of different classes or that +are instances of a non-transparent class are equal? only if +they are eq?. Like transparent structures, two objects that +are instances of the same transparent class (i.e., every superclass of +the class has #f as its inspector) are equal? when +their field values are equal?.

To customize the way that a class instance is compared to other +instances by equal?, implement the equal<%> +interface.

interface

equal<%> : interface?

The equal<%> interface includes three methods, which are +analogous to the functions provided for a structure type with +prop:equal+hash:
  • equal-to? Takes two arguments. The first argument +is an object that is an instance of the same class (or a subclass +that does not re-declare its implementation of equal<%>) +and that is being compared to the target object. The second argument +is an equal?-like procedure of two arguments that should be +used for recursive equality testing. The result should be a true +value if the object and the first argument of the method are equal, +#f otherwise.

  • equal-hash-code-of Takes one argument, which is a +procedure of one argument that should be used for recursive hash-code +computation. The result should be an exact integer representing the +target object’s hash code.

  • equal-secondary-hash-code-of Takes one argument, +which is a procedure of one argument that should be used for +recursive hash-code computation. The result should be an exact +integer representing the target object’s secondary hash code.

The equal<%> interface is unusual in that declaring the +implementation of the interface is different from inheriting the +interface. Two objects can be equal only if they are instances of +classes whose most specific ancestor to explicitly implement +equal<%> is the same ancestor.
See prop:equal+hash for more information on equality +comparisons and hash codes. The equal<%> interface is +implemented with interface* and prop:equal+hash.

Example: +
#lang racket
 
;; Case insensitive words:
(define ci-word%
  (class* object% (equal<%>)
 
    ;; Initialization
    (init-field word)
    (super-new)
 
    ;; We define equality to ignore case:
    (define/public (equal-to? other recur)
      (string-ci=? word (get-field word other)))
 
    ;; The hash codes need to be insensitive to casing as well.
    ;; We'll just downcase the word and get its hash code.
    (define/public (equal-hash-code-of hash-code)
      (hash-code (string-downcase word)))
 
    (define/public (equal-secondary-hash-code-of hash-code)
      (hash-code (string-downcase word)))))
 
;; We can create a hash with a single word:
(define h (make-hash))
(hash-set! h (new ci-word% [word "inconceivable!"]) 'value)
 
;; Lookup into the hash should be case-insensitive, so that
;; both of these should return 'value.
(hash-ref h (new ci-word% [word "inconceivable!"]))
(hash-ref h (new ci-word% [word "INCONCEIVABLE!"]))
 
;; Comparison fails if we use a non-ci-word%:
(hash-ref h "inconceivable!" 'i-dont-think-it-means-what-you-think-it-means)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/objectprinting.html b/clones/docs.racket-lang.org/reference/objectprinting.html new file mode 100644 index 00000000..efa95c13 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/objectprinting.html @@ -0,0 +1,19 @@ + +6.10 Object Printing

6.10 Object Printing

To customize the way that a class instance is printed by +print, write and display, implement the +printable<%> interface.

The printable<%> interface includes only the +custom-print, custom-write, and +custom-display methods. The custom-print method +accepts two arguments: the destination port and the current +quasiquote depth as an exact nonnegative integer. The +custom-write and custom-display methods each accepts +a single argument, which is the destination port to write or +display the object.

Calls to the custom-print, custom-write, or +custom-display methods are like calls to a procedure attached +to a structure type through the prop:custom-write +property. In particular, recursive printing can trigger an escape from +the call.

See prop:custom-write for more information. The +printable<%> interface is implemented with +interface* and prop:custom-write.

Like printable<%>, but includes only the +custom-write and custom-display methods. +A print request is directed to custom-write.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/objectserialize.html b/clones/docs.racket-lang.org/reference/objectserialize.html new file mode 100644 index 00000000..072984d3 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/objectserialize.html @@ -0,0 +1,40 @@ + +6.9 Object Serialization

6.9 Object Serialization

syntax

(define-serializable-class* class-id superclass-expr
                                     (interface-expr ...)
  class-clause ...)
Binds class-id to a class, where superclass-expr, +the interface-exprs, and the class-clauses are as in +class*.

This form can only be used at the top level, either within a module +or outside. The class-id identifier is bound to the new +class, and deserialize-info:class-id is also +defined; if the definition is within a module, then the latter is +provided from a deserialize-info submodule via module+.

Serialization for the class works in one of two ways:

  • If the class implements the built-in interface +externalizable<%>, then an object is serialized by +calling its externalize method; the result can be +anything that is serializable (but, obviously, should not be +the object itself). Deserialization creates an instance of the +class with no initialization arguments, and then calls the +object’s internalize method with the result of +externalize (or, more precisely, a deserialized +version of the serialized result of a previous call).

    To support this form of serialization, the class must be +instantiable with no initialization arguments. Furthermore, +cycles involving only instances of the class (and other such +classes) cannot be serialized.

  • If the class does not implement externalizable<%>, +then every superclass of the class must be either serializable +or transparent (i.e,. have #f as its +inspector). Serialization and deserialization are fully +automatic, and may involve cycles of instances.

    To support cycles of instances, deserialization may create an +instance of the call with all fields as the undefined value, +and then mutate the object to set the field +values. Serialization support does not otherwise make an +object’s fields mutable.

In the second case, a serializable subclass can implement +externalizable<%>, in which case the externalize +method is responsible for all serialization (i.e., automatic +serialization is lost for instances of the subclass). In the first +case, all serializable subclasses implement +externalizable<%>, since a subclass implements all of the +interfaces of its parent class.

In either case, if an object is an immediate instance of a subclass +(that is not itself serializable), the object is serialized as if it +was an immediate instance of the serializable class. In particular, +overriding declarations of the externalize method are ignored +for instances of non-serializable subclasses.

syntax

(define-serializable-class class-id superclass-expr
  class-clause ...)
Like define-serializable-class*, but without interface +expressions (analogous to class).

The externalizable<%> interface includes only the +externalize and internalize methods. See +define-serializable-class* for more information.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/objectutils.html b/clones/docs.racket-lang.org/reference/objectutils.html new file mode 100644 index 00000000..9872ce17 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/objectutils.html @@ -0,0 +1,61 @@ + +6.11 Object, Class, and Interface Utilities

6.11 Object, Class, and Interface Utilities

procedure

(object? v)  boolean?

  v : any/c
Returns #t if v is an object, #f otherwise.

Examples:
> (object? (new object%))

#t

> (object? object%)

#f

> (object? "clam chowder")

#f

procedure

(class? v)  boolean?

  v : any/c
Returns #t if v is a class, #f otherwise.

Examples:
> (class? object%)

#t

> (class? (class object% (super-new)))

#t

> (class? (new object%))

#f

> (class? "corn chowder")

#f

procedure

(interface? v)  boolean?

  v : any/c
Returns #t if v is an interface, #f otherwise.

Examples:
> (interface? (interface () empty cons first rest))

#t

> (interface? object%)

#f

> (interface? "gazpacho")

#f

procedure

(generic? v)  boolean?

  v : any/c
Returns #t if v is a generic, #f otherwise.

Examples:
> (define c%
    (class object%
      (super-new)
      (define/public (m x)
        (+ 3.14 x))))
> (generic? (generic c% m))

#t

> (generic? c%)

#f

> (generic? "borscht")

#f

procedure

(object=? a b)  boolean?

  a : object?
  b : object?
Determines whether a and b were returned from +the same call to new or not. If the two objects +have fields, this procedure determines whether mutating a field +of one would change that field in the other.

This procedure is similar in spirit to +eq? but also works properly with contracts +(and has a stronger guarantee).

Examples:
> (define obj-1 (new object%))
> (define obj-2 (new object%))
> (define/contract obj-3 (object/c) obj-1)
> (object=? obj-1 obj-1)

#t

> (object=? obj-1 obj-2)

#f

> (object=? obj-1 obj-3)

#t

> (eq? obj-1 obj-1)

#t

> (eq? obj-1 obj-2)

#f

> (eq? obj-1 obj-3)

#f

procedure

(object-or-false=? a b)  boolean?

  a : (or/c object? #f)
  b : (or/c object? #f)
Like object=?, but accepts #f for either argument and +returns #t if both arguments are #f.

Examples:

Added in version 6.1.1.8 of package base.

procedure

(object=-hash-code o)  fixnum?

  o : object?
Returns the hash code for o that corresponds to + the equality relation object=?.

Added in version 7.1.0.6 of package base.

procedure

(object->vector object [opaque-v])  vector?

  object : object?
  opaque-v : any/c = #f
Returns a vector representing object that shows its +inspectable fields, analogous to struct->vector.

Examples:
> (object->vector (new object%))

'#(object:object% ...)

> (object->vector (new (class object%
                         (super-new)
                         (field [x 5] [y 10]))))

'#(object:eval:107:0 ...)

procedure

(class->interface class)  interface?

  class : class?
Returns the interface implicitly defined by class.

Example:
> (class->interface object%)

#<interface:object%>

procedure

(object-interface object)  interface?

  object : object?
Returns the interface implicitly defined by the class of +object.

Example:
> (object-interface (new object%))

#<interface:object%>

procedure

(is-a? v type)  boolean?

  v : any/c
  type : (or/c interface? class?)
Returns #t if v is an instance of a class +type or a class that implements an interface type, +#f otherwise.

Examples:
> (define point<%> (interface () get-x get-y))
> (define 2d-point%
    (class* object% (point<%>)
      (super-new)
      (field [x 0] [y 0])
      (define/public (get-x) x)
      (define/public (get-y) y)))
> (is-a? (new 2d-point%) 2d-point%)

#t

> (is-a? (new 2d-point%) point<%>)

#t

> (is-a? (new object%) 2d-point%)

#f

> (is-a? (new object%) point<%>)

#f

procedure

(subclass? v cls)  boolean?

  v : any/c
  cls : class?
Returns #t if v is a class derived from (or equal +to) cls, #f otherwise.

Examples:

procedure

(implementation? v intf)  boolean?

  v : any/c
  intf : interface?
Returns #t if v is a class that implements +intf, #f otherwise.

Examples:
> (define i<%> (interface () go))
> (define c%
    (class* object% (i<%>)
      (super-new)
      (define/public (go) 'go)))
> (implementation? c% i<%>)

#t

> (implementation? object% i<%>)

#f

procedure

(interface-extension? v intf)  boolean?

  v : any/c
  intf : interface?
Returns #t if v is an interface that extends +intf, #f otherwise.

Examples:
> (define point<%> (interface () get-x get-y))
> (define colored-point<%> (interface (point<%>) color))
> (interface-extension? colored-point<%> point<%>)

#t

> (interface-extension? point<%> colored-point<%>)

#f

> (interface-extension? (interface () get-x get-y get-z) point<%>)

#f

procedure

(method-in-interface? sym intf)  boolean?

  sym : symbol?
  intf : interface?
Returns #t if intf (or any of its ancestor +interfaces) includes a member with the name sym, #f +otherwise.

Examples:
> (define i<%> (interface () get-x get-y))
> (method-in-interface? 'get-x i<%>)

#t

> (method-in-interface? 'get-z i<%>)

#f

procedure

(interface->method-names intf)  (listof symbol?)

  intf : interface?
Returns a list of symbols for the method names in intf, +including methods inherited from superinterfaces, but not including +methods whose names are local (i.e., declared with +define-local-member-name).

Examples:
> (define i<%> (interface () get-x get-y))
> (interface->method-names i<%>)

'(get-y get-x)

procedure

(object-method-arity-includes? object    
  sym    
  cnt)  boolean?
  object : object?
  sym : symbol?
  cnt : exact-nonnegative-integer?
Returns #t if object has a method named sym +that accepts cnt arguments, #f otherwise.

Examples:
> (define c%
    (class object%
      (super-new)
      (define/public (m x [y 0])
        (+ x y))))
> (object-method-arity-includes? (new c%) 'm 1)

#t

> (object-method-arity-includes? (new c%) 'm 2)

#t

> (object-method-arity-includes? (new c%) 'm 3)

#f

> (object-method-arity-includes? (new c%) 'n 1)

#f

procedure

(field-names object)  (listof symbol?)

  object : object?
Returns a list of all of the names of the fields bound in +object, including fields inherited from superinterfaces, but +not including fields whose names are local (i.e., declared with +define-local-member-name).

Examples:
> (field-names (new object%))

'()

> (field-names (new (class object% (super-new) (field [x 0] [y 0]))))

'(y x)

procedure

(object-info object)  
(or/c class? #f) boolean?
  object : object?
Returns two values, analogous to the return +values of struct-info: +
  • class: a class or #f; the result is +#f if the current inspector does not control any class for +which the object is an instance.

  • skipped?: #f if the first result corresponds +to the most specific class of object, #t +otherwise.

Returns seven values, analogous to the return +values of struct-type-info:

  • name: the class’s name as a symbol;

  • field-cnt: the number of fields (public and private) +defined by the class;

  • field-name-list: a list of symbols corresponding to the +class’s public fields; this list can be larger than field-cnt +because it includes inherited fields;

  • field-accessor: an accessor procedure for obtaining +field values in instances of the class; the accessor takes an +instance and a field index between 0 (inclusive) +and field-cnt (exclusive);

  • field-mutator: a mutator procedure for modifying +field values in instances of the class; the mutator takes an +instance, a field index between 0 (inclusive) +and field-cnt (exclusive), and a new field value;

  • super-class: a class for the most specific ancestor of +the given class that is controlled by the current inspector, +or #f if no ancestor is controlled by the current +inspector;

  • skipped?: #f if the sixth result is the most +specific ancestor class, #t otherwise.

struct

(struct exn:fail:object exn:fail ()
    #:extra-constructor-name make-exn:fail:object)
Raised for class-related failures, such as attempting to call +a method that is not supplied by an object.

procedure

(class-seal class    
  key    
  unsealed-inits    
  unsealed-fields    
  unsealed-methods    
  inst-proc    
  member-proc)  class?
  class : class?
  key : symbol?
  unsealed-inits : (listof symbol?)
  unsealed-fields : (listof symbol?)
  unsealed-methods : (listof symbol?)
  inst-proc : (-> class? any)
  member-proc : (-> class? (listof symbol?) any)
Adds a seal to a given class keyed with the symbol key. The +given unsealed-inits, unsealed-fields, and +unsealed-methods list corresponding class members that are +unaffected by sealing.

When a class has any seals, the inst-proc procedure is called +on instantiation (normally, this is used to raise an error on +instantiation) and the member-proc function is called +(again, this is normally used to raise an error) when a subclass +attempts to add class members that are not listed in the unsealed lists.

The inst-proc is called with the class value on which an +instantiation was attempted. The member-proc is called with +the class value and the list of initialization argument, field, or +method names.

procedure

(class-unseal class key wrong-key-proc)  class?

  class : class?
  key : symbol?
  wrong-key-proc : (-> class? any)
Removes a seal on a class that has been previously sealed with the +class-seal function and the given key.

If the unseal removed all of the seals in the class, the class +value can be instantiated or subclassed freely. If the given +class value does not contain or any seals or does not contain +any seals with the given key, the wrong-key-proc function +is called with the class value.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/os-lib.html b/clones/docs.racket-lang.org/reference/os-lib.html new file mode 100644 index 00000000..686b5ffb --- /dev/null +++ b/clones/docs.racket-lang.org/reference/os-lib.html @@ -0,0 +1,3 @@ + +15.10 Additional Operating System Functions

15.10 Additional Operating System Functions

 (require racket/os) package: base
The racket/os library +additional functions for querying the operating system.

Added in version 6.3 of package base.

procedure

(gethostname)  string?

Returns a string for the current machine’s hostname (including its domain).

procedure

(getpid)  exact-integer?

Returns an integer identifying the current process within the operating system.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/os.html b/clones/docs.racket-lang.org/reference/os.html new file mode 100644 index 00000000..d20e1294 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/os.html @@ -0,0 +1,2 @@ + +15 Operating System
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/pairs.html b/clones/docs.racket-lang.org/reference/pairs.html new file mode 100644 index 00000000..b033d171 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/pairs.html @@ -0,0 +1,243 @@ + +4.10 Pairs and Lists

4.10 Pairs and Lists

+Pairs and Lists in The Racket Guide introduces pairs and lists.

A pair combines exactly two values. The first value is +accessed with the car procedure, and the second value is +accessed with the cdr procedure. Pairs are not mutable (but +see Mutable Pairs and Lists).

A list is recursively defined: it is either the constant +null, or it is a pair whose second value is a list.

A list can be used as a single-valued sequence (see +Sequences). The elements of the list serve as elements +of the sequence. See also in-list.

Cyclic data structures can be created using only immutable pairs via +read or make-reader-graph. If starting with a pair +and using some number of cdrs returns to the starting pair, +then the pair is not a list.

See Reading Pairs and Lists + for information on reading + pairs and lists and Printing Pairs and Lists + for information on printing pairs and lists.

4.10.1 Pair Constructors and Selectors

procedure

(pair? v)  boolean?

  v : any/c
Returns #t if v is a pair, #f otherwise.

Examples:
> (pair? 1)

#f

> (pair? (cons 1 2))

#t

> (pair? (list 1 2))

#t

> (pair? '(1 2))

#t

> (pair? '())

#f

procedure

(null? v)  boolean?

  v : any/c
Returns #t if v is the empty list, #f +otherwise.

Examples:
> (null? 1)

#f

> (null? '(1 2))

#f

> (null? '())

#t

> (null? (cdr (list 1)))

#t

procedure

(cons a d)  pair?

  a : any/c
  d : any/c
Returns a newly allocated pair whose first element is a and +second element is d.

Examples:
> (cons 1 2)

'(1 . 2)

> (cons 1 '())

'(1)

procedure

(car p)  any/c

  p : pair?
Returns the first element of the pair p.

Examples:
> (car '(1 2))

1

> (car (cons 2 3))

2

procedure

(cdr p)  any/c

  p : pair?
Returns the second element of the pair p.

Examples:
> (cdr '(1 2))

'(2)

> (cdr '(1))

'()

value

null : null?

The empty list.

Examples:
> null

'()

> '()

'()

> (eq? '() null)

#t

procedure

(list? v)  boolean?

  v : any/c
Returns #t if v is a list: either the empty list, or a +pair whose second element is a list. This procedure effectively takes +constant time due to internal caching (so that any necessary traversals +of pairs can in principle count as an extra cost of allocating the +pairs).

Examples:
> (list? '(1 2))

#t

> (list? (cons 1 (cons 2 '())))

#t

> (list? (cons 1 2))

#f

procedure

(list v ...)  list?

  v : any/c
Returns a newly allocated list containing the vs as its +elements.

Examples:
> (list 1 2 3 4)

'(1 2 3 4)

> (list (list 1 2) (list 3 4))

'((1 2) (3 4))

procedure

(list* v ... tail)  any/c

  v : any/c
  tail : any/c
Like list, but the last argument is used as the tail of the +result, instead of the final element. The result is a list only if the +last argument is a list.

Examples:
> (list* 1 2)

'(1 . 2)

> (list* 1 2 (list 3 4))

'(1 2 3 4)

procedure

(build-list n proc)  list?

  n : exact-nonnegative-integer?
  proc : (exact-nonnegative-integer? . -> . any)
Creates a list of n elements by applying proc to the +integers from 0 to (sub1 n) in order. If +lst is the resulting list, then (list-ref lst i) is +the value produced by (proc i).

Examples:
> (build-list 10 values)

'(0 1 2 3 4 5 6 7 8 9)

> (build-list 5 (lambda (x) (* x x)))

'(0 1 4 9 16)

4.10.2 List Operations

procedure

(length lst)  exact-nonnegative-integer?

  lst : list?
Returns the number of elements in lst. This function takes +time proportional to that length.

Examples:
> (length (list 1 2 3 4))

4

> (length '())

0

procedure

(list-ref lst pos)  any/c

  lst : pair?
  pos : exact-nonnegative-integer?
Returns the element of lst at position pos, where the +list’s first element is position 0. If the list has +pos or fewer elements, then the exn:fail:contract exception is raised.

The lst argument need not actually be a list; lst must +merely start with a chain of at least (add1 pos) pairs.

This function takes time proportional to pos.

Examples:
> (list-ref (list 'a 'b 'c) 0)

'a

> (list-ref (list 'a 'b 'c) 1)

'b

> (list-ref (list 'a 'b 'c) 2)

'c

> (list-ref (cons 1 2) 0)

1

> (list-ref (cons 1 2) 1)

list-ref: index reaches a non-pair

  index: 1

  in: '(1 . 2)

procedure

(list-tail lst pos)  any/c

  lst : any/c
  pos : exact-nonnegative-integer?
Returns the list after the first pos elements of lst. +If the list has fewer than pos elements, then the +exn:fail:contract exception is raised.

The lst argument need not actually be a list; lst +must merely start with a chain of at least pos pairs.

This function takes time proportional to pos.

Examples:
> (list-tail (list 1 2 3 4 5) 2)

'(3 4 5)

> (list-tail (cons 1 2) 1)

2

> (list-tail (cons 1 2) 2)

list-tail: index reaches a non-pair

  index: 2

  in: '(1 . 2)

> (list-tail 'not-a-pair 0)

'not-a-pair

procedure

(append lst ...)  list?

  lst : list?
(append lst ... v)  any/c
  lst : list?
  v : any/c
When given all list arguments, the result is a list that contains all of +the elements of the given lists in order. The last argument is used +directly in the tail of the result.

The last argument need not be a list, in which case the result is an +“improper list.”

This function takes time proportional to the length of all arguments +(added together) except the last argument.

Examples:
> (append (list 1 2) (list 3 4))

'(1 2 3 4)

> (append (list 1 2) (list 3 4) (list 5 6) (list 7 8))

'(1 2 3 4 5 6 7 8)

procedure

(reverse lst)  list?

  lst : list?
Returns a list that has the same elements as lst, but in +reverse order.

This function takes time proportional to the length of lst.

Example:
> (reverse (list 1 2 3 4))

'(4 3 2 1)

4.10.3 List Iteration

procedure

(map proc lst ...+)  list?

  proc : procedure?
  lst : list?
Applies proc to the elements of the lsts from the +first elements to the last. The proc argument must accept the +same number of arguments as the number of supplied lsts, and +all lsts must have the same number of elements. The result is +a list containing each result of proc in order.

Examples:
> (map (lambda (number)
         (+ 1 number))
       '(1 2 3 4))

'(2 3 4 5)

> (map (lambda (number1 number2)
         (+ number1 number2))
       '(1 2 3 4)
       '(10 100 1000 10000))

'(11 102 1003 10004)

procedure

(andmap proc lst ...+)  any

  proc : procedure?
  lst : list?
Similar to map in the sense that proc is applied to +each element of lst, but

The andmap function is actually closer to +foldl than map, since andmap doesn’t +produce a list. Still, (andmap f (list x y z)) is equivalent +to (and (f x) (f y) (f z)) in the same way that +(map f (list x y z)) is equivalent to +(list (f x) (f y) (f z)).

  • the result is #f if any application of proc +produces #f, in which case proc is not applied +to later elements of the lsts; and

  • the result is that of proc applied to the last elements +of the lsts; more specifically, the application of +proc to the last elements in the lsts is in tail +position with respect to the andmap call.

If the lsts are empty, then #t is returned.

Examples:
> (andmap positive? '(1 2 3))

#t

> (andmap positive? '(1 2 a))

positive?: contract violation

  expected: real?

  given: 'a

> (andmap positive? '(1 -2 a))

#f

> (andmap + '(1 2 3) '(4 5 6))

9

procedure

(ormap proc lst ...+)  any

  proc : procedure?
  lst : list?
Similar to map in the sense that proc is applied to +each element of lst, but

To continue the andmap note above, +(ormap f (list x y z)) is equivalent to +(or (f x) (f y) (f z)).

  • the result is #f if every application of proc +produces #f; and

  • the result is that of the first application of proc +producing a value other than #f, in which case +proc is not applied to later elements of the +lsts; the application of proc to the last +elements of the lsts is in tail position with respect to +the ormap call.

If the lsts are empty, then #f is returned.

Examples:
> (ormap eq? '(a b c) '(a b c))

#t

> (ormap positive? '(1 2 a))

#t

> (ormap + '(1 2 3) '(4 5 6))

5

procedure

(for-each proc lst ...+)  void?

  proc : procedure?
  lst : list?
Similar to map, but proc is called only for its +effect, and its result (which can be any number of values) is ignored.

Example:
> (for-each (lambda (arg)
              (printf "Got ~a\n" arg)
              23)
            '(1 2 3 4))

Got 1

Got 2

Got 3

Got 4

procedure

(foldl proc init lst ...+)  any/c

  proc : procedure?
  init : any/c
  lst : list?
Like map, foldl applies a procedure to the elements of +one or more lists. Whereas map combines the return values into +a list, foldl combines the return values in an arbitrary way +that is determined by proc.

If foldl is called with n lists, then proc must +take n+1 arguments. The extra argument is the combined return +values so far. The proc is initially invoked with the first +item of each list, and the final argument is init. In +subsequent invocations of proc, the last argument is the return +value from the previous invocation of proc. The input +lsts are traversed from left to right, and the result of the +whole foldl application is the result of the last application +of proc. If the lsts are empty, the result is +init.

Unlike foldr, foldl processes the lsts in +constant space (plus the space for each call to proc).

Examples:
> (foldl cons '() '(1 2 3 4))

'(4 3 2 1)

> (foldl + 0 '(1 2 3 4))

10

> (foldl (lambda (a b result)
           (* result (- a b)))
         1
         '(1 2 3)
         '(4 5 6))

-27

procedure

(foldr proc init lst ...+)  any/c

  proc : procedure?
  init : any/c
  lst : list?
Like foldl, but the lists are traversed from right to left. +Unlike foldl, foldr processes the lsts in +space proportional to the length of lsts (plus the space for +each call to proc).

Examples:
> (foldr cons '() '(1 2 3 4))

'(1 2 3 4)

> (foldr (lambda (v l) (cons (add1 v) l)) '() '(1 2 3 4))

'(2 3 4 5)

4.10.4 List Filtering

procedure

(filter pred lst)  list?

  pred : procedure?
  lst : list?
Returns a list with the elements of lst for which pred +produces a true value. The pred procedure is applied to each +element from first to last.

Example:
> (filter positive? '(1 -2 3 4 -5))

'(1 3 4)

procedure

(remove v lst [proc])  list?

  v : any/c
  lst : list?
  proc : procedure? = equal?
Returns a list that is like lst, omitting the first element of +lst that is equal to v using the comparison procedure +proc (which must accept two arguments), +with v as the first argument and an element in lst as the second argument. +If no element in lst is equal to v (according to proc), +lst is returned unchanged.

Examples:
> (remove 2 (list 1 2 3 2 4))

'(1 3 2 4)

> (remove '(2) (list '(1) '(2) '(3)))

'((1) (3))

> (remove "2" (list "1" "2" "3"))

'("1" "3")

> (remove #\c (list #\a #\b #\c))

'(#\a #\b)

> (remove "B" (list "a" "A" "b" "B") string-ci=?)

'("a" "A" "B")

> (remove 5 (list 1 2 3 2 4))

'(1 2 3 2 4)

Changed in version 8.2.0.2 of package base: Guaranteed that the output is eq? to lst +if no removal occurs.

procedure

(remq v lst)  list?

  v : any/c
  lst : list?
Returns (remove v lst eq?).

Examples:
> (remq 2 (list 1 2 3 4 5))

'(1 3 4 5)

> (remq '(2) (list '(1) '(2) '(3)))

'((1) (2) (3))

> (remq "2" (list "1" "2" "3"))

'("1" "3")

> (remq #\c (list #\a #\b #\c))

'(#\a #\b)

procedure

(remv v lst)  list?

  v : any/c
  lst : list?
Returns (remove v lst eqv?).

Examples:
> (remv 2 (list 1 2 3 4 5))

'(1 3 4 5)

> (remv '(2) (list '(1) '(2) '(3)))

'((1) (2) (3))

> (remv "2" (list "1" "2" "3"))

'("1" "3")

> (remv #\c (list #\a #\b #\c))

'(#\a #\b)

procedure

(remw v lst)  list?

  v : any/c
  lst : list?
Returns (remove v lst equal-always?).

Examples:
> (remw 2 (list 1 2 3 4 5))

'(1 3 4 5)

> (remw '(2) (list '(1) '(2) '(3)))

'((1) (3))

> (remw "2" (list "1" "2" "3"))

'("1" "3")

> (remw #\c (list #\a #\b #\c))

'(#\a #\b)

> (define b1 (box 5))
> (define b2 (box 5))
> (remw b2 (list 0 b1 1 b2 2))

'(0 #&5 1 2)

Added in version 8.5.0.3 of package base.

procedure

(remove* v-lst lst [proc])  list?

  v-lst : list?
  lst : list?
  proc : procedure? = equal?
Like remove, but removes from lst every instance of +every element of v-lst.

Example:
> (remove* (list 1 2) (list 1 2 3 2 4 5 2))

'(3 4 5)

Changed in version 8.2.0.2 of package base: Guaranteed that the output is eq? to lst +if no removal occurs.

procedure

(remq* v-lst lst)  list?

  v-lst : list?
  lst : list?
Returns (remove* v-lst lst eq?).

Example:
> (remq* (list 1 2) (list 1 2 3 2 4 5 2))

'(3 4 5)

procedure

(remv* v-lst lst)  list?

  v-lst : list?
  lst : list?
Returns (remove* v-lst lst eqv?).

Example:
> (remv* (list 1 2) (list 1 2 3 2 4 5 2))

'(3 4 5)

procedure

(remw* v-lst lst)  list?

  v-lst : list?
  lst : list?
Returns (remove* v-lst lst equal-always?).

Examples:
> (remw* (list 1 2) (list 1 2 3 2 4 5 2))

'(3 4 5)

> (define b1 (box 5))
> (define b2 (box 5))
> (remw* (list b2) (list 0 b1 1 b2 2 b2 3))

'(0 #&5 1 2 3)

Added in version 8.5.0.3 of package base.

procedure

(sort lst    
  less-than?    
  [#:key extract-key    
  #:cache-keys? cache-keys?])  list?
  lst : list?
  less-than? : (any/c any/c . -> . any/c)
  extract-key : (any/c . -> . any/c) = (lambda (x) x)
  cache-keys? : boolean? = #f
Returns a list sorted according to the less-than? procedure, +which takes two elements of lst and returns a true value if the +first is less (i.e., should be sorted earlier) than the second.

The sort is stable; if two elements of lst are “equal” +(i.e., less-than? does not return a true value when given the pair in +either order), then the elements preserve their relative order from +lst in the output list. To preserve this guarantee, use +sort with a strict comparison functions (e.g., < or +string<?; not <= or string<=?).

Because of the peculiar fact that the IEEE-754 number system +specifies that +nan.0 is neither greater nor less than nor equal to any other +number, sorting lists containing this value may produce a surprising result.

The #:key argument extract-key is used to extract a +key value for comparison from each list element. That is, the full +comparison procedure is essentially

(lambda (x y)
  (less-than? (extract-key x) (extract-key y)))

By default, extract-key is applied to two list elements for +every comparison, but if cache-keys? is true, then the +extract-key function is used exactly once for each list item. +Supply a true value for cache-keys? when extract-key +is an expensive operation; for example, if +file-or-directory-modify-seconds is used to extract a timestamp +for every file in a list, then cache-keys? should be +#t to minimize file-system calls, but if extract-key +is car, then cache-keys? should be #f. As +another example, providing extract-key as +(lambda (x) (random)) and #t for cache-keys? +effectively shuffles the list.

Examples:
> (sort '(1 3 4 2) <)

'(1 2 3 4)

> (sort '("aardvark" "dingo" "cow" "bear") string<?)

'("aardvark" "bear" "cow" "dingo")

> (sort '(("aardvark") ("dingo") ("cow") ("bear"))
        #:key car string<?)

'(("aardvark") ("bear") ("cow") ("dingo"))

4.10.5 List Searching

procedure

(member v lst [is-equal?])  (or/c #f list? any/c)

  v : any/c
  lst : (or/c list? any/c)
  is-equal? : (any/c any/c -> any/c) = equal?
Locates the first element of lst that is equal? to +v. If such an element exists, the tail of lst +starting with that element is returned. Otherwise, the result is +#f.

The lst argument need not actually be a list; lst +must merely start with a chain of pairs until a matching element is +found. If no matching element is found, then lst must be a +list (and not a cyclic list). The result can be a non-list in the case +that an element is found and the returned tail of lst is a +non-list.

Examples:
> (member 2 (list 1 2 3 4))

'(2 3 4)

> (member 9 (list 1 2 3 4))

#f

> (member #'x (list #'x #'y) free-identifier=?)

'(#<syntax:eval:551:0 x> #<syntax:eval:551:0 y>)

> (member #'a (list #'x #'y) free-identifier=?)

#f

> (member 'b '(a b . etc))

'(b . etc)

procedure

(memw v lst)  (or/c #f list? any/c)

  v : any/c
  lst : (or/c list? any/c)
Like member, but finds an element using equal-always?.

Examples:
> (memw 2 (list 1 2 3 4))

'(2 3 4)

> (memw 9 (list 1 2 3 4))

#f

> (define b1 (box 5))
> (define b2 (box 5))
> (memw b2 (list 0 b1 1 b2 2))

'(#&5 2)

Added in version 8.5.0.3 of package base.

procedure

(memv v lst)  (or/c #f list? any/c)

  v : any/c
  lst : (or/c list? any/c)
Like member, but finds an element using eqv?.

Examples:
> (memv 2 (list 1 2 3 4))

'(2 3 4)

> (memv 9 (list 1 2 3 4))

#f

procedure

(memq v lst)  (or/c #f list? any/c)

  v : any/c
  lst : (or/c list? any/c)
Like member, but finds an element using eq?.

Examples:
> (memq 2 (list 1 2 3 4))

'(2 3 4)

> (memq 9 (list 1 2 3 4))

#f

procedure

(memf proc lst)  (or/c #f list? any/c)

  proc : procedure?
  lst : (or/c list? any/c)
Like member, but finds an element using the predicate +proc; an element is found when proc applied to the +element returns a true value.

Example:
> (memf (lambda (arg)
          (> arg 9))
        '(7 8 9 10 11))

'(10 11)

procedure

(findf proc lst)  any/c

  proc : procedure?
  lst : list?
Like memf, but returns the element or #f instead of a +tail of lst or #f.

Example:
> (findf (lambda (arg)
           (> arg 9))
         '(7 8 9 10 11))

10

procedure

(assoc v lst [is-equal?])  (or/c pair? #f)

  v : any/c
  lst : (or/c (listof pair?) any/c)
  is-equal? : (any/c any/c -> any/c) = equal?
Locates the first element of lst whose car is equal to +v according to is-equal?. If such an element exists, +the pair (i.e., an element of lst) is returned. Otherwise, the +result is #f.

The lst argument need not actually be a list of pairs; +lst must merely start with a chain of pairs contains pairs +until a matching element is found. If no matching element is found, +then lst must be a list of pairs (and not a cyclic list).

Examples:
> (assoc 3 (list (list 1 2) (list 3 4) (list 5 6)))

'(3 4)

> (assoc 9 (list (list 1 2) (list 3 4) (list 5 6)))

#f

> (assoc 3.5
         (list (list 1 2) (list 3 4) (list 5 6))
         (lambda (a b) (< (abs (- a b)) 1)))

'(3 4)

procedure

(assw v lst)  (or/c pair? #f)

  v : any/c
  lst : (or/c (listof pair?) any/c)
Like assoc, but finds an element using equal-always?.

Examples:
> (assw 3 (list (list 1 2) (list 3 4) (list 5 6)))

'(3 4)

> (define b1 (box 0))
> (define b2 (box 0))
> (assw b2 (list (cons b1 1) (cons b2 2)))

'(#&0 . 2)

Added in version 8.5.0.3 of package base.

procedure

(assv v lst)  (or/c pair? #f)

  v : any/c
  lst : (or/c (listof pair?) any/c)
Like assoc, but finds an element using eqv?.

Example:
> (assv 3 (list (list 1 2) (list 3 4) (list 5 6)))

'(3 4)

procedure

(assq v lst)  (or/c pair? #f)

  v : any/c
  lst : (or/c (listof pair?) any/c)
Like assoc, but finds an element using eq?.

Example:
> (assq 'c (list (list 'a 'b) (list 'c 'd) (list 'e 'f)))

'(c d)

procedure

(assf proc lst)  (or/c pair? #f)

  proc : procedure?
  lst : (or/c (listof pair?) any/c)
Like assoc, but finds an element using the predicate +proc; an element is found when proc applied to the +car of an lst element returns a true value.

Example:
> (assf (lambda (arg)
          (> arg 2))
        (list (list 1 2) (list 3 4) (list 5 6)))

'(3 4)

4.10.6 Pair Accessor Shorthands

procedure

(caar v)  any/c

  v : (cons/c pair? any/c)
Returns (car (car v)).

Example:
> (caar '((1 2) 3 4))

1

procedure

(cadr v)  any/c

  v : (cons/c any/c pair?)
Returns (car (cdr v)).

Example:
> (cadr '((1 2) 3 4))

3

procedure

(cdar v)  any/c

  v : (cons/c pair? any/c)
Returns (cdr (car v)).

Example:
> (cdar '((7 6 5 4 3 2 1) 8 9))

'(6 5 4 3 2 1)

procedure

(cddr v)  any/c

  v : (cons/c any/c pair?)
Returns (cdr (cdr v)).

Example:
> (cddr '(2 1))

'()

procedure

(caaar v)  any/c

  v : (cons/c (cons/c pair? any/c) any/c)
Returns (car (car (car v))).

Example:
> (caaar '(((6 5 4 3 2 1) 7) 8 9))

6

procedure

(caadr v)  any/c

  v : (cons/c any/c (cons/c pair? any/c))
Returns (car (car (cdr v))).

Example:
> (caadr '(9 (7 6 5 4 3 2 1) 8))

7

procedure

(cadar v)  any/c

  v : (cons/c (cons/c any/c pair?) any/c)
Returns (car (cdr (car v))).

Example:
> (cadar '((7 6 5 4 3 2 1) 8 9))

6

procedure

(caddr v)  any/c

  v : (cons/c any/c (cons/c any/c pair?))
Returns (car (cdr (cdr v))).

Example:
> (caddr '(3 2 1))

1

procedure

(cdaar v)  any/c

  v : (cons/c (cons/c pair? any/c) any/c)
Returns (cdr (car (car v))).

Example:
> (cdaar '(((6 5 4 3 2 1) 7) 8 9))

'(5 4 3 2 1)

procedure

(cdadr v)  any/c

  v : (cons/c any/c (cons/c pair? any/c))
Returns (cdr (car (cdr v))).

Example:
> (cdadr '(9 (7 6 5 4 3 2 1) 8))

'(6 5 4 3 2 1)

procedure

(cddar v)  any/c

  v : (cons/c (cons/c any/c pair?) any/c)
Returns (cdr (cdr (car v))).

Example:
> (cddar '((7 6 5 4 3 2 1) 8 9))

'(5 4 3 2 1)

procedure

(cdddr v)  any/c

  v : (cons/c any/c (cons/c any/c pair?))
Returns (cdr (cdr (cdr v))).

Example:
> (cdddr '(3 2 1))

'()

procedure

(caaaar v)  any/c

  v : (cons/c (cons/c (cons/c pair? any/c) any/c) any/c)
Returns (car (car (car (car v)))).

Example:
> (caaaar '((((5 4 3 2 1) 6) 7) 8 9))

5

procedure

(caaadr v)  any/c

  v : (cons/c any/c (cons/c (cons/c pair? any/c) any/c))
Returns (car (car (car (cdr v)))).

Example:
> (caaadr '(9 ((6 5 4 3 2 1) 7) 8))

6

procedure

(caadar v)  any/c

  v : (cons/c (cons/c any/c (cons/c pair? any/c)) any/c)
Returns (car (car (cdr (car v)))).

Example:
> (caadar '((7 (5 4 3 2 1) 6) 8 9))

5

procedure

(caaddr v)  any/c

  v : (cons/c any/c (cons/c any/c (cons/c pair? any/c)))
Returns (car (car (cdr (cdr v)))).

Example:
> (caaddr '(9 8 (6 5 4 3 2 1) 7))

6

procedure

(cadaar v)  any/c

  v : (cons/c (cons/c (cons/c any/c pair?) any/c) any/c)
Returns (car (cdr (car (car v)))).

Example:
> (cadaar '(((6 5 4 3 2 1) 7) 8 9))

5

procedure

(cadadr v)  any/c

  v : (cons/c any/c (cons/c (cons/c any/c pair?) any/c))
Returns (car (cdr (car (cdr v)))).

Example:
> (cadadr '(9 (7 6 5 4 3 2 1) 8))

6

procedure

(caddar v)  any/c

  v : (cons/c (cons/c any/c (cons/c any/c pair?)) any/c)
Returns (car (cdr (cdr (car v)))).

Example:
> (caddar '((7 6 5 4 3 2 1) 8 9))

5

procedure

(cadddr v)  any/c

  v : (cons/c any/c (cons/c any/c (cons/c any/c pair?)))
Returns (car (cdr (cdr (cdr v)))).

Example:
> (cadddr '(4 3 2 1))

1

procedure

(cdaaar v)  any/c

  v : (cons/c (cons/c (cons/c pair? any/c) any/c) any/c)
Returns (cdr (car (car (car v)))).

Example:
> (cdaaar '((((5 4 3 2 1) 6) 7) 8 9))

'(4 3 2 1)

procedure

(cdaadr v)  any/c

  v : (cons/c any/c (cons/c (cons/c pair? any/c) any/c))
Returns (cdr (car (car (cdr v)))).

Example:
> (cdaadr '(9 ((6 5 4 3 2 1) 7) 8))

'(5 4 3 2 1)

procedure

(cdadar v)  any/c

  v : (cons/c (cons/c any/c (cons/c pair? any/c)) any/c)
Returns (cdr (car (cdr (car v)))).

Example:
> (cdadar '((7 (5 4 3 2 1) 6) 8 9))

'(4 3 2 1)

procedure

(cdaddr v)  any/c

  v : (cons/c any/c (cons/c any/c (cons/c pair? any/c)))
Returns (cdr (car (cdr (cdr v)))).

Example:
> (cdaddr '(9 8 (6 5 4 3 2 1) 7))

'(5 4 3 2 1)

procedure

(cddaar v)  any/c

  v : (cons/c (cons/c (cons/c any/c pair?) any/c) any/c)
Returns (cdr (cdr (car (car v)))).

Example:
> (cddaar '(((6 5 4 3 2 1) 7) 8 9))

'(4 3 2 1)

procedure

(cddadr v)  any/c

  v : (cons/c any/c (cons/c (cons/c any/c pair?) any/c))
Returns (cdr (cdr (car (cdr v)))).

Example:
> (cddadr '(9 (7 6 5 4 3 2 1) 8))

'(5 4 3 2 1)

procedure

(cdddar v)  any/c

  v : (cons/c (cons/c any/c (cons/c any/c pair?)) any/c)
Returns (cdr (cdr (cdr (car v)))).

Example:
> (cdddar '((7 6 5 4 3 2 1) 8 9))

'(4 3 2 1)

procedure

(cddddr v)  any/c

  v : (cons/c any/c (cons/c any/c (cons/c any/c pair?)))
Returns (cdr (cdr (cdr (cdr v)))).

Example:
> (cddddr '(4 3 2 1))

'()

4.10.7 Additional List Functions and Synonyms

 (require racket/list) package: base
The bindings documented in this section are provided by the racket/list and racket libraries, but not racket/base.

value

empty : null?

The empty list.

Examples:
> empty

'()

> (eq? empty null)

#t

procedure

(cons? v)  boolean?

  v : any/c
The same as (pair? v).

Example:
> (cons? '(1 2))

#t

procedure

(empty? v)  boolean?

  v : any/c
The same as (null? v).

Examples:
> (empty? '(1 2))

#f

> (empty? '())

#t

procedure

(first lst)  any/c

  lst : list?
The same as (car lst), but only for lists (that are not empty).

Example:
> (first '(1 2 3 4 5 6 7 8 9 10))

1

procedure

(rest lst)  list?

  lst : list?
The same as (cdr lst), but only for lists (that are not empty).

Example:
> (rest '(1 2 3 4 5 6 7 8 9 10))

'(2 3 4 5 6 7 8 9 10)

procedure

(second lst)  any

  lst : list?
Returns the second element of the list.

Example:
> (second '(1 2 3 4 5 6 7 8 9 10))

2

procedure

(third lst)  any

  lst : list?
Returns the third element of the list.

Example:
> (third '(1 2 3 4 5 6 7 8 9 10))

3

procedure

(fourth lst)  any

  lst : list?
Returns the fourth element of the list.

Example:
> (fourth '(1 2 3 4 5 6 7 8 9 10))

4

procedure

(fifth lst)  any

  lst : list?
Returns the fifth element of the list.

Example:
> (fifth '(1 2 3 4 5 6 7 8 9 10))

5

procedure

(sixth lst)  any

  lst : list?
Returns the sixth element of the list.

Example:
> (sixth '(1 2 3 4 5 6 7 8 9 10))

6

procedure

(seventh lst)  any

  lst : list?
Returns the seventh element of the list.

Example:
> (seventh '(1 2 3 4 5 6 7 8 9 10))

7

procedure

(eighth lst)  any

  lst : list?
Returns the eighth element of the list.

Example:
> (eighth '(1 2 3 4 5 6 7 8 9 10))

8

procedure

(ninth lst)  any

  lst : list?
Returns the ninth element of the list.

Example:
> (ninth '(1 2 3 4 5 6 7 8 9 10))

9

procedure

(tenth lst)  any

  lst : list?
Returns the tenth element of the list.

Example:
> (tenth '(1 2 3 4 5 6 7 8 9 10))

10

procedure

(last lst)  any

  lst : list?
Returns the last element of the list.

This function takes time proportional to the length of lst.

Example:
> (last '(1 2 3 4 5 6 7 8 9 10))

10

procedure

(last-pair p)  pair?

  p : pair?
Returns the last pair of a (possibly improper) list.

This function takes time proportional to the “length” of p.

Example:
> (last-pair '(1 2 3 4))

'(4)

procedure

(make-list k v)  list?

  k : exact-nonnegative-integer?
  v : any/c
Returns a newly constructed list of length k, holding +v in all positions.

Example:
> (make-list 7 'foo)

'(foo foo foo foo foo foo foo)

procedure

(list-update lst pos updater)  list?

  lst : list?
  pos : (and/c (>=/c 0) (</c (length lst)))
  updater : (-> any/c any/c)
Returns a list that is the same as lst except at the specified index. +The element at the specified index is (updater (list-ref lst pos)).

This function takes time proportional to pos.

Example:
> (list-update '(zero one two) 1 symbol->string)

'(zero "one" two)

Added in version 6.3 of package base.

procedure

(list-set lst pos value)  list?

  lst : list?
  pos : (and/c (>=/c 0) (</c (length lst)))
  value : any/c
Returns a list that is the same as lst except at the specified index. +The element at the specified index is value.

This function takes time proportional to pos.

Example:
> (list-set '(zero one two) 2 "two")

'(zero one "two")

Added in version 6.3 of package base.

procedure

(index-of lst v [is-equal?])  (or/c exact-nonnegative-integer? #f)

  lst : list?
  v : any/c
  is-equal? : (any/c any/c . -> . any/c) = equal?
Like member, but returns the index of the first element found +instead of the tail of the list.

Example:
> (index-of '(1 2 3 4) 3)

2

Added in version 6.7.0.3 of package base.

procedure

(index-where lst proc)  (or/c exact-nonnegative-integer? #f)

  lst : list?
  proc : (any/c . -> . any/c)
Like index-of but with the predicate-searching behavior of +memf.

Example:
> (index-where '(1 2 3 4) even?)

1

Added in version 6.7.0.3 of package base.

procedure

(indexes-of lst v [is-equal?])

  (listof exact-nonnegative-integer?)
  lst : list?
  v : any/c
  is-equal? : (any/c any/c . -> . any/c) = equal?
Like index-of, but returns the a list of all the indexes +where the element occurs in the list instead of just the first one.

Example:
> (indexes-of '(1 2 1 2 1) 2)

'(1 3)

Added in version 6.7.0.3 of package base.

procedure

(indexes-where lst proc)  (listof exact-nonnegative-integer?)

  lst : list?
  proc : (any/c . -> . any/c)
Like indexes-of but with the predicate-searching behavior of +index-where.

Example:
> (indexes-where '(1 2 3 4) even?)

'(1 3)

Added in version 6.7.0.3 of package base.

procedure

(take lst pos)  list?

  lst : any/c
  pos : exact-nonnegative-integer?
Returns a fresh list whose elements are the first pos elements +of lst. If lst has fewer than pos elements, +the exn:fail:contract exception is raised.

The lst argument need not actually be a list; lst +must merely start with a chain of at least pos pairs.

This function takes time proportional to pos.

Examples:
> (take '(1 2 3 4 5) 2)

'(1 2)

> (take 'non-list 0)

'()

procedure

(drop lst pos)  any/c

  lst : any/c
  pos : exact-nonnegative-integer?
Just like list-tail.

procedure

(split-at lst pos)  
list? any/c
  lst : any/c
  pos : exact-nonnegative-integer?
Returns the same result as

(values (take lst pos) (drop lst pos))

except that it can be faster, but it will still take time +proportional to pos.

procedure

(takef lst pred)  list?

  lst : any/c
  pred : procedure?
Returns a fresh list whose elements are taken successively from +lst as long as they satisfy pred. The returned list +includes up to, but not including, the first element in lst for +which pred returns #f.

The lst argument need not actually be a list; the chain of +pairs in lst will be traversed until a non-pair is encountered.

Examples:
> (takef '(2 4 5 8) even?)

'(2 4)

> (takef '(2 4 6 8) odd?)

'()

> (takef '(2 4 . 6) even?)

'(2 4)

procedure

(dropf lst pred)  any/c

  lst : any/c
  pred : procedure?
Drops elements from the front of lst as long as they satisfy +pred.

Examples:
> (dropf '(2 4 5 8) even?)

'(5 8)

> (dropf '(2 4 6 8) odd?)

'(2 4 6 8)

procedure

(splitf-at lst pred)  
list? any/c
  lst : any/c
  pred : procedure?
Returns the same result as

(values (takef lst pred) (dropf lst pred))

except that it can be faster.

procedure

(take-right lst pos)  any/c

  lst : any/c
  pos : exact-nonnegative-integer?
Returns the list’s pos-length tail. If lst +has fewer than pos elements, then the +exn:fail:contract exception is raised.

The lst argument need not actually be a list; lst +must merely end with a chain of at least pos pairs.

This function takes time proportional to the length of lst.

Examples:
> (take-right '(1 2 3 4 5) 2)

'(4 5)

> (take-right 'non-list 0)

'non-list

procedure

(drop-right lst pos)  list?

  lst : any/c
  pos : exact-nonnegative-integer?
Returns a fresh list whose elements are the prefix of lst, +dropping its pos-length tail. If lst has fewer than +pos elements, then the exn:fail:contract exception is raised.

The lst argument need not actually be a list; lst must +merely end with a chain of at least pos pairs.

This function takes time proportional to the length of lst.

Examples:
> (drop-right '(1 2 3 4 5) 2)

'(1 2 3)

> (drop-right 'non-list 0)

'()

procedure

(split-at-right lst pos)  
list? any/c
  lst : any/c
  pos : exact-nonnegative-integer?
Returns the same result as

(values (drop-right lst pos) (take-right lst pos))

except that it can be faster, but it will still take time proportional +to the length of lst.

Examples:
> (split-at-right '(1 2 3 4 5 6) 3)

'(1 2 3)

'(4 5 6)

> (split-at-right '(1 2 3 4 5 6) 4)

'(1 2)

'(3 4 5 6)

procedure

(takef-right lst pred)  any/c

  lst : any/c
  pred : procedure?

procedure

(dropf-right lst pred)  list?

  lst : any/c
  pred : procedure?

procedure

(splitf-at-right lst pred)  
list? any/c
  lst : any/c
  pred : procedure?
Like takef, dropf, and splitf-at, but +combined with the from-right functionality of take-right, +drop-right, and split-at-right.

procedure

(list-prefix? l r [same?])  boolean?

  l : list?
  r : list?
  same? : (any/c any/c . -> . any/c) = equal?
True if l is a prefix of r. +

Example:
> (list-prefix? '(1 2) '(1 2 3 4 5))

#t

Added in version 6.3 of package base.

procedure

(take-common-prefix l r [same?])  list?

  l : list?
  r : list?
  same? : (any/c any/c . -> . any/c) = equal?
Returns the longest common prefix of l and r.

Example:
> (take-common-prefix '(a b c d) '(a b x y z))

'(a b)

Added in version 6.3 of package base.

procedure

(drop-common-prefix l r [same?])  
list? list?
  l : list?
  r : list?
  same? : (any/c any/c . -> . any/c) = equal?
Returns the tails of l and r with the common + prefix removed.

Example:
> (drop-common-prefix '(a b c d) '(a b x y z))

'(c d)

'(x y z)

Added in version 6.3 of package base.

procedure

(split-common-prefix l r [same?])  
list? list? list?
  l : list?
  r : list?
  same? : (any/c any/c . -> . any/c) = equal?
Returns the longest common prefix together with the tails of + l and r with the common prefix removed.

Example:
> (split-common-prefix '(a b c d) '(a b x y z))

'(a b)

'(c d)

'(x y z)

Added in version 6.3 of package base.

procedure

(add-between lst    
  v    
  [#:before-first before-first    
  #:before-last before-last    
  #:after-last after-last    
  #:splice? splice?])  list?
  lst : list?
  v : any/c
  before-first : list? = '()
  before-last : any/c = v
  after-last : list? = '()
  splice? : any/c = #f
Returns a list with the same elements as lst, but with +v between each pair of elements in lst; the last pair +of elements will have before-last between them, instead of +v (but before-last defaults to v).

If splice? is true, then v and before-last +should be lists, and the list elements are spliced into the result. In +addition, when splice? is true, before-first and +after-last are inserted before the first element and after the +last element respectively.

Examples:
> (add-between '(x y z) 'and)

'(x and y and z)

> (add-between '(x) 'and)

'(x)

> (add-between '("a" "b" "c" "d") "," #:before-last "and")

'("a" "," "b" "," "c" "and" "d")

> (add-between '(x y z) '(-) #:before-last '(- -)
               #:before-first '(begin) #:after-last '(end LF)
               #:splice? #t)

'(begin x - y - - z end LF)

procedure

(append* lst ... lsts)  list?

  lst : list?
  lsts : (listof list?)
(append* lst ... lsts)  any/c
  lst : list?
  lsts : list?
Like append, but the last argument is used as a list of +arguments for append, so (append* lst ... lsts) is the +same as (apply append lst ... lsts). In other words, the +relationship between append and append* is similar to +the one between list and list*.

Examples:
> (append* '(a) '(b) '((c) (d)))

'(a b c d)

> (cdr (append* (map (lambda (x) (list ", " x))
                     '("Alpha" "Beta" "Gamma"))))

'("Alpha" ", " "Beta" ", " "Gamma")

procedure

(flatten v)  list?

  v : any/c
Flattens an arbitrary S-expression structure of pairs into a list. More +precisely, v is treated as a binary tree where pairs are +interior nodes, and the resulting list contains all of the +non-null leaves of the tree in the same order as an inorder +traversal.

Examples:
> (flatten '((a) b (c (d) . e) ()))

'(a b c d e)

> (flatten 'a)

'(a)

procedure

(check-duplicates lst    
  [same?    
  #:key extract-key    
  #:default failure-result])  any
  lst : list?
  same? : (any/c any/c . -> . any/c) = equal?
  extract-key : (-> any/c any/c) = (lambda (x) x)
  failure-result : failure-result/c = (lambda () #f)
Returns the first duplicate item in lst. More precisely, it +returns the first x such that there was a previous +y where (same? (extract-key x) (extract-key y)).

If no duplicate is found, then failure-result determines the +result:

  • If failure-result is a procedure, it is called +(through a tail call) with no arguments to produce the result.

  • Otherwise, failure-result is returned as the result.

The same? argument should be an equivalence predicate such as +equal? or eqv? or a dictionary. +The procedures equal?, eqv?, and eq? automatically +use a dictionary for speed.

Examples:
> (check-duplicates '(1 2 3 4))

#f

> (check-duplicates '(1 2 3 2 1))

2

> (check-duplicates '((a 1) (b 2) (a 3)) #:key car)

'(a 3)

> (check-duplicates '(1 2 3 4 5 6)
                    (lambda (x y) (equal? (modulo x 3) (modulo y 3))))

4

> (check-duplicates '(1 2 3 4) #:default "no duplicates")

"no duplicates"

Added in version 6.3 of package base.
Changed in version 6.11.0.2: Added the #:default optional argument.

procedure

(remove-duplicates lst    
  [same?    
  #:key extract-key])  list?
  lst : list?
  same? : (any/c any/c . -> . any/c) = equal?
  extract-key : (any/c . -> . any/c) = (lambda (x) x)
Returns a list that has all items in lst, but without duplicate +items, where same? determines whether two elements of the list +are equivalent. The resulting list is in the same order as +lst, and for any item that occurs multiple times, the first one +is kept.

The #:key argument extract-key is used to extract a +key value from each list element, so two items are considered equal if +(same? (extract-key x) (extract-key y)) is true.

Examples:
> (remove-duplicates '(a b b a))

'(a b)

> (remove-duplicates '(1 2 1.0 0))

'(1 2 1.0 0)

> (remove-duplicates '(1 2 1.0 0) =)

'(1 2 0)

procedure

(filter-map proc lst ...+)  list?

  proc : procedure?
  lst : list?
Like (map proc lst ...), except that, if proc +returns #false, that element is omitted from the resulting list. +In other words, filter-map is equivalent to +(filter (lambda (x) x) (map proc lst ...)), but more efficient, +because filter-map avoids +building the intermediate list.

Example:
> (filter-map (lambda (x) (and (negative? x) (abs x))) '(1 2 -3 -4 8))

'(3 4)

procedure

(count proc lst ...+)  exact-nonnegative-integer?

  proc : procedure?
  lst : list?
Returns (length (filter-map proc lst ...)), but without building +the intermediate list.

Example:
> (count positive? '(1 -1 2 3 -2 5))

4

procedure

(partition pred lst)  
list? list?
  pred : procedure?
  lst : list?
Similar to filter, except that two values are returned: the +items for which pred returns a true value, and the items for +which pred returns #f.

The result is the same as

(values (filter pred lst) (filter (negate pred) lst))

but pred is applied to each item in lst only once.

Example:
> (partition even? '(1 2 3 4 5 6))

'(2 4 6)

'(1 3 5)

procedure

(range end)  list?

  end : real?
(range start end [step])  list?
  start : real?
  end : real?
  step : real? = 1
Similar to in-range, but returns lists.

The resulting list holds numbers starting at start and whose +successive elements are computed by adding step to their +predecessor until end (excluded) is reached. If no starting +point is provided, 0 is used. If no step argument is +provided, 1 is used.

Like in-range, a range application can provide better +performance when it appears directly in a for clause.

Examples:
> (range 10)

'(0 1 2 3 4 5 6 7 8 9)

> (range 10 20)

'(10 11 12 13 14 15 16 17 18 19)

> (range 20 40 2)

'(20 22 24 26 28 30 32 34 36 38)

> (range 20 10 -1)

'(20 19 18 17 16 15 14 13 12 11)

> (range 10 15 1.5)

'(10 11.5 13.0 14.5)

Changed in version 6.7.0.4 of package base: Adjusted to cooperate with for in the same +way that in-range does.

procedure

(inclusive-range start end [step])  list?

  start : real?
  end : real?
  step : real? = 1
Similar to in-inclusive-range, but returns lists.

The resulting list holds numbers starting at start and whose +successive elements are computed by adding step to their +predecessor until end (included) is reached. +If no step argument is provided, 1 is used.

Like in-inclusive-range, an inclusive-range application can provide better +performance when it appears directly in a for clause.

Examples:
> (inclusive-range 10 20)

'(10 11 12 13 14 15 16 17 18 19 20)

> (inclusive-range 20 40 2)

'(20 22 24 26 28 30 32 34 36 38 40)

> (inclusive-range 20 10 -1)

'(20 19 18 17 16 15 14 13 12 11 10)

> (inclusive-range 10 15 1.5)

'(10 11.5 13.0 14.5)

Added in version 8.0.0.13 of package base.

procedure

(append-map proc lst ...+)  list?

  proc : procedure?
  lst : list?
Returns (append* (map proc lst ...)).

Example:
> (append-map vector->list '(#(1) #(2 3) #(4)))

'(1 2 3 4)

procedure

(filter-not pred lst)  list?

  pred : (any/c . -> . any/c)
  lst : list?
Like filter, but the meaning of the pred predicate is +reversed: the result is a list of all items for which pred +returns #f.

Example:
> (filter-not even? '(1 2 3 4 5 6))

'(1 3 5)

procedure

(shuffle lst)  list?

  lst : list?
Returns a list with all elements from lst, randomly shuffled.

Examples:
> (shuffle '(1 2 3 4 5 6))

'(2 4 5 3 6 1)

> (shuffle '(1 2 3 4 5 6))

'(2 5 4 3 6 1)

> (shuffle '(1 2 3 4 5 6))

'(6 1 4 5 2 3)

procedure

(combinations lst)  list?

  lst : list?
(combinations lst size)  list?
  lst : list?
  size : exact-nonnegative-integer?

Wikipedia combinations

Return a list of all combinations of elements in the input list +(aka the powerset of lst). +If size is given, limit results to combinations of size elements.

Examples:
> (combinations '(1 2 3))

'(() (1) (2) (1 2) (3) (1 3) (2 3) (1 2 3))

> (combinations '(1 2 3) 2)

'((1 2) (1 3) (2 3))

procedure

(in-combinations lst)  sequence?

  lst : list?
(in-combinations lst size)  sequence?
  lst : list?
  size : exact-nonnegative-integer?
Returns a sequence of all combinations of elements in the input list, + or all combinations of length size if size is given. +Builds combinations one-by-one instead of all at once.

Examples:
> (time (begin (combinations (range 15)) (void)))

cpu time: 10 real time: 5 gc time: 0

> (time (begin (in-combinations (range 15)) (void)))

cpu time: 0 real time: 0 gc time: 0

procedure

(permutations lst)  list?

  lst : list?
Returns a list of all permutations of the input list. Note that this +function works without inspecting the elements, and therefore it ignores +repeated elements (which will result in repeated permutations). +Raises an error if the input list contains more than 256 elements.

Examples:
> (permutations '(1 2 3))

'((1 2 3) (2 1 3) (1 3 2) (3 1 2) (2 3 1) (3 2 1))

> (permutations '(x x))

'((x x) (x x))

procedure

(in-permutations lst)  sequence?

  lst : list?
Returns a sequence of all permutations of the input list. It is +equivalent to (in-list (permutations l)) but much faster since +it builds the permutations one-by-one on each iteration. +Raises an error if the input list contains more than 256 elements.

procedure

(argmin proc lst)  any/c

  proc : (-> any/c real?)
  lst : (and/c pair? list?)
Returns the first element in the list lst that minimizes the +result of proc. Signals an error on an empty list. +See also min.

Examples:
> (argmin car '((3 pears) (1 banana) (2 apples)))

'(1 banana)

> (argmin car '((1 banana) (1 orange)))

'(1 banana)

procedure

(argmax proc lst)  any/c

  proc : (-> any/c real?)
  lst : (and/c pair? list?)
Returns the first element in the list lst that maximizes the +result of proc. Signals an error on an empty list. +See also max.

Examples:
> (argmax car '((3 pears) (1 banana) (2 apples)))

'(3 pears)

> (argmax car '((3 pears) (3 oranges)))

'(3 pears)

procedure

(group-by key lst [same?])  (listof list?)

  key : (-> any/c any/c)
  lst : list?
  same? : (any/c any/c . -> . any/c) = equal?
Groups the given list into equivalence classes, with equivalence being +determined by same?. Within each equivalence class, group-by +preserves the ordering of the original list. Equivalence classes themselves are +in order of first appearance in the input.

Example:
> (group-by (lambda (x) (modulo x 3)) '(1 2 1 2 54 2 5 43 7 2 643 1 2 0))

'((1 1 43 7 643 1) (2 2 2 5 2 2) (54 0))

Added in version 6.3 of package base.

procedure

(cartesian-product lst ...)  (listof list?)

  lst : list?
Computes the n-ary cartesian product of the given lists.

Examples:
> (cartesian-product '(1 2 3) '(a b c))

'((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c))

> (cartesian-product '(4 5 6) '(d e f) '(#t #f))

'((4 d #t)

  (4 d #f)

  (4 e #t)

  (4 e #f)

  (4 f #t)

  (4 f #f)

  (5 d #t)

  (5 d #f)

  (5 e #t)

  (5 e #f)

  (5 f #t)

  (5 f #f)

  (6 d #t)

  (6 d #f)

  (6 e #t)

  (6 e #f)

  (6 f #t)

  (6 f #f))

Added in version 6.3 of package base.

procedure

(remf pred lst)  list?

  pred : procedure?
  lst : list?
Returns a list that is like lst, omitting the first element of lst +for which pred produces a true value.

Example:
> (remf negative? '(1 -2 3 4 -5))

'(1 3 4 -5)

Added in version 6.3 of package base.

procedure

(remf* pred lst)  list?

  pred : procedure?
  lst : list?
Like remf, but removes all the elements for which pred +produces a true value.

Example:
> (remf* negative? '(1 -2 3 4 -5))

'(1 3 4)

Added in version 6.3 of package base.

4.10.8 Immutable Cyclic Data

procedure

(make-reader-graph v)  any/c

  v : any/c
Returns a value like v, with placeholders created by +make-placeholder replaced with the values that they contain, and +with hash placeholders created by make-hash-placeholder +with an immutable hash table. No part of v is mutated; instead, +parts of v are copied as necessary to construct the resulting +graph, where at most one copy is created for any given value.

Since the copied values can be immutable, and since the copy is also +immutable, make-reader-graph can create cycles involving only +immutable pairs, vectors, boxes, and hash tables.

Only the following kinds of values are copied and traversed to detect +placeholders:

  • pairs

  • vectors, both mutable and immutable

  • boxes, both mutable and immutable

  • hash tables, both mutable and immutable

  • instances of a prefab structure type

  • placeholders created by make-placeholder and +make-hash-placeholder

Due to these restrictions, make-reader-graph creates exactly +the same sort of cyclic values as read.

Example:
> (let* ([ph (make-placeholder #f)]
         [x (cons 1 ph)])
    (placeholder-set! ph x)
    (make-reader-graph x))

#0='(1 . #0#)

procedure

(placeholder? v)  boolean?

  v : any/c
Returns #t if v is a placeholder created by +make-placeholder, #f otherwise.

procedure

(make-placeholder v)  placeholder?

  v : any/c
Returns a placeholder for use with placeholder-set! +and make-reader-graph. The v argument supplies the +initial value for the placeholder.

procedure

(placeholder-set! ph datum)  void?

  ph : placeholder?
  datum : any/c
Changes the value of ph to v.

procedure

(placeholder-get ph)  any/c

  ph : placeholder?
Returns the value of ph.

procedure

(hash-placeholder? v)  boolean?

  v : any/c
Returns #t if v is a hash placeholder created +by make-hash-placeholder, #f otherwise.

procedure

(make-hash-placeholder assocs)  hash-placeholder?

  assocs : (listof pair?)
Like make-immutable-hash, but produces a hash placeholder +for use with make-reader-graph.

procedure

(make-hasheq-placeholder assocs)  hash-placeholder?

  assocs : (listof pair?)
Like make-immutable-hasheq, but produces a hash placeholder +for use with make-reader-graph.

procedure

(make-hasheqv-placeholder assocs)  hash-placeholder?

  assocs : (listof pair?)
Like make-immutable-hasheqv, but produces a hash placeholder +for use with make-reader-graph.

procedure

(make-hashalw-placeholder assocs)  hash-placeholder?

  assocs : (listof pair?)
Like make-immutable-hashalw, but produces a hash placeholder +for use with make-reader-graph.

Added in version 8.5.0.3 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/parameters.html b/clones/docs.racket-lang.org/reference/parameters.html new file mode 100644 index 00000000..1c8fb0e4 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/parameters.html @@ -0,0 +1,57 @@ + +11.3.2 Parameters
11.3.2 Parameters

+Dynamic Binding: parameterize in The Racket Guide introduces parameters.

See Parameters for basic information on the +parameter model. Parameters correspond to preserved thread +fluids in Scsh [Gasbichler02].

To parameterize code in a thread- and continuation-friendly manner, +use parameterize. The parameterize form introduces a +fresh thread cell for the dynamic extent of its body +expressions.

When a new thread is created, the parameterization for the new +thread’s initial continuation is the parameterization of the +creator thread. Since each parameter’s thread cell is +preserved, the new thread “inherits” the parameter values of +its creating thread. When a continuation is moved from one thread to +another, settings introduced with parameterize effectively +move with the continuation.

In contrast, direct assignment to a parameter (by calling the +parameter procedure with a value) changes the value in a thread cell, +and therefore changes the setting only for the current +thread. Consequently, as far as the memory manager is concerned, the +value originally associated with a parameter through +parameterize remains reachable as long the continuation is +reachable, even if the parameter is mutated.

procedure

(make-parameter v [guard name])  parameter?

  v : any/c
  guard : (or/c (any/c . -> . any) #f) = #f
  name : symbol? = 'parameter-procedure
Returns a new parameter procedure. The value of the parameter is +initialized to v in all threads.

If guard is not #f, +it is used as the parameter’s guard procedure. A guard +procedure takes one argument. Whenever the parameter procedure is +applied to an argument, the argument is passed on to the guard +procedure. The result returned by the guard procedure is used as the +new parameter value. A guard procedure can raise an exception to +reject a change to the parameter’s value. The guard is not +applied to the initial v.

The name argument is used as the parameter procedure’s name +as reported by object-name.

Changed in version 7.4.0.6 of package base: Added the name argument.

syntax

(parameterize ([parameter-expr value-expr] ...)
  body ...+)
 
  parameter-expr : parameter?

The result of a parameterize expression is the result of the +last body. The parameter-exprs determine the +parameters to set, and the value-exprs determine the +corresponding values to install while evaluating the +bodys. The parameter-exprs and +value-exprs are evaluated left-to-right (interleaved), and +then the parameters are bound in the continuation to preserved thread +cells that contain the values of the value-exprs; the result +of each parameter-expr is checked with parameter? +just before it is bound. The last body is in tail +position with respect to the entire parameterize form.

Outside the dynamic extent of a parameterize expression, +parameters remain bound to other thread cells. Effectively, therefore, +old parameters settings are restored as control exits the +parameterize expression.

If a continuation is captured during the evaluation of +parameterize, invoking the continuation effectively +re-introduces the parameterization, since a parameterization is +associated to a continuation via a continuation mark (see +Continuation Marks) using a private key.

Examples:
> (parameterize ([exit-handler (lambda (x) 'no-exit)])
    (exit))
> (define p1 (make-parameter 1))
> (define p2 (make-parameter 2))
> (parameterize ([p1 3]
                 [p2 (p1)])
    (cons (p1) (p2)))

'(3 . 1)

> (let ([k (let/cc out
             (parameterize ([p1 2])
               (p1 3)
               (cons (let/cc k
                       (out k))
                     (p1))))])
    (if (procedure? k)
        (k (p1))
        k))

'(1 . 3)

> (define ch (make-channel))
> (parameterize ([p1 0])
    (thread (lambda ()
              (channel-put ch (cons (p1) (p2))))))

#<thread>

> (channel-get ch)

'(0 . 2)

> (define k-ch (make-channel))
> (define (send-k)
    (parameterize ([p1 0])
      (thread (lambda ()
                (let/ec esc
                  (channel-put ch
                               ((let/cc k
                                  (channel-put k-ch k)
                                  (esc)))))))))
> (send-k)

#<thread>

> (thread (lambda () ((channel-get k-ch)
                      (let ([v (p1)])
                        (lambda () v)))))

#<thread>

> (channel-get ch)

1

> (send-k)

#<thread>

> (thread (lambda () ((channel-get k-ch) p1)))

#<thread>

> (channel-get ch)

0

syntax

(parameterize* ((parameter-expr value-expr) ...)
  body ...+)
Analogous to let* compared to let, parameterize* +is the same as a nested series of single-parameter parameterize +forms.

procedure

(make-derived-parameter parameter    
  guard    
  wrap)  parameter?
  parameter : parameter?
  guard : (any/c . -> . any)
  wrap : (any/c . -> . any)
Returns a parameter procedure that sets or retrieves the same value as +parameter, but with:

  • guard applied when setting the parameter (before any +guard associated with parameter), and

  • wrap applied when obtaining the parameter’s value.

See also chaperone-procedure, which can also be used to guard +parameter procedures.

procedure

(parameter? v)  boolean?

  v : any/c
Returns #t if v is a parameter procedure, +#f otherwise.

procedure

(parameter-procedure=? a b)  boolean?

  a : parameter?
  b : parameter?
Returns #t if the parameter procedures a and +b always modify the same parameter with the same guards +(although possibly with different chaperones), #f +otherwise.

Returns the +current continuation’s parameterization.

procedure

(call-with-parameterization parameterization    
  thunk)  any
  parameterization : parameterization?
  thunk : (-> any)
Calls thunk (via a tail call) with parameterization +as the current parameterization.

procedure

(parameterization? v)  boolean?

  v : any/c
Returns #t if v is a parameterization +returned by current-parameterization, #f otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/parametric-contracts.html b/clones/docs.racket-lang.org/reference/parametric-contracts.html new file mode 100644 index 00000000..59c19754 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/parametric-contracts.html @@ -0,0 +1,34 @@ + +8.3 Parametric Contracts

8.3 Parametric Contracts

 (require racket/contract/parametric) package: base

The most convenient way to use parametric contract is to use +contract-out’s #:exists keyword. +The racket/contract/parametric provides a few more, +general-purpose parametric contracts.

syntax

(parametric->/c (x ...) c)

Creates a contract for parametric polymorphic functions. Each function is +protected by c, where each x is bound in c and refers +to a polymorphic type that is instantiated each time the function is applied.

At each application of a function, the parametric->/c contract constructs +a new opaque wrapper for each x; values flowing into the polymorphic +function (i.e. values protected by some x in negative position with +respect to parametric->/c) are wrapped in the corresponding opaque +wrapper. Values flowing out of the polymorphic function (i.e. values protected +by some x in positive position with respect to parametric->/c) +are checked for the appropriate wrapper. If they have it, they are unwrapped; +if they do not, a contract violation is signaled.

Examples:
> (define swap-ctc (parametric->/c [A B] (-> A B (values B A))))
> (define/contract (good-swap a b)
    swap-ctc
    (values b a))
> (good-swap 1 2)

2

1

> (define/contract (bad-swap a b)
    swap-ctc
    (values a b))
> (bad-swap 1 2)

bad-swap: broke its own contract

  promised: B

  produced: #<A>

  in: the range of

      (parametric->/c (A B) (-> A B (values B A)))

  contract from: (function bad-swap)

  blaming: (function bad-swap)

   (assuming the contract is correct)

  at: eval:5:0

> (define/contract (copy-first a b)
    swap-ctc
    (values a a))
> (let ((v 'same-symbol)) (copy-first v v))

copy-first: broke its own contract

  promised: B

  produced: #<A>

  in: the range of

      (parametric->/c (A B) (-> A B (values B A)))

  contract from: (function copy-first)

  blaming: (function copy-first)

   (assuming the contract is correct)

  at: eval:7:0

> (define/contract (inspect-first a b)
    swap-ctc
    (if (integer? a)
      (+ a b)
      (raise-user-error "an opaque wrapped value is not an integer")))
> (inspect-first 1 2)

an opaque wrapped value is not an integer

procedure

(new-∀/c [name])  contract?

  name : (or/c symbol? #f) = #f
Constructs a new universal contract.

Universal contracts accept all values when in negative positions (e.g., function +inputs) and wrap them in an opaque struct, hiding the precise value. +In positive positions (e.g. function returns), +a universal contract accepts only values that were previously accepted +in negative positions (by checking for the wrappers).

The name is used to identify the contract in error messages and defaults +to a name based on the lexical context of new-∀/c.

For example, this contract: +
(let ([a (new-∀/c 'a)])
  (-> a a))
describes the identity function (or a non-terminating function). +That is, the first use of the a appears in a +negative position and thus inputs to that function are wrapped with an opaque struct. +Then, when the function returns, it is checked to determine whether the result is wrapped, since +the second a appears in a positive position.

The new-∀/c contract constructor is dual to new-∃/c.

procedure

(new-∃/c [name])  contract?

  name : (or/c symbol? #f) = #f
Constructs a new existential contract.

Existential contracts accept all values when in positive positions (e.g., function +returns) and wrap them in an opaque struct, hiding the precise value. +In negative positions (e.g. function inputs), +they accepts only values that were previously accepted in positive positions (by checking +for the wrappers).

The name is used to identify the contract in error messages and defaults +to a name based on the lexical context of new-∀/c.

For example, this contract: +
(let ([a (new-∃/c 'a)])
  (-> (-> a a)
      any/c))
describes a function that accepts the identity function (or a non-terminating function) +and returns an arbitrary value. That is, the first use of the a appears in a +positive position and thus inputs to that function are wrapped with an opaque struct. +Then, when the function returns, it is checked to see if the result is wrapped, since +the second a appears in a negative position.

The new-∃/c construct constructor is dual to new-∀/c.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/pathutils.html b/clones/docs.racket-lang.org/reference/pathutils.html new file mode 100644 index 00000000..6fcc0822 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/pathutils.html @@ -0,0 +1,30 @@ + +15.1 Paths

15.1 Paths

When a Racket procedure takes a filesystem path as an argument, the +path can be provided either as a string or as an instance of the +path datatype. If a string is provided, it is converted to a +path using string->path. Beware that some paths may not +be representable as strings; see Unix Path Representation and +Windows Path Representation for more information. +A Racket procedure that generates a +filesystem path always generates a path value.

By default, paths are created and manipulated for the current +platform, but procedures that merely manipulate paths (without using +the filesystem) can manipulate paths using conventions for other +supported platforms. The bytes->path procedure accepts an +optional argument that indicates the platform for the path, either +'unix or 'windows. For other functions, such as +build-path or simplify-path, the behavior is +sensitive to the kind of path that is supplied. Unless otherwise +specified, a procedure that requires a path accepts only paths for the +current platform.

Two path values are equal? when they are use the same +convention type and when their byte-string representations are +equal?. A path string (or byte string) cannot be empty, and +it cannot contain a nul character or byte. When an empty string or a +string containing nul is provided as a path to any procedure except +absolute-path?, relative-path?, or +complete-path?, the exn:fail:contract exception is raised.

Most Racket primitives that accept paths first cleanse the +path before using it. Procedures that build paths or merely check the +form of a path do not cleanse paths, with the exceptions of +cleanse-path, expand-user-path, and +simplify-path. For more information about path cleansing and +other platform-specific details, see Unix and Mac OS Paths and +Windows Paths.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/performance-hint.html b/clones/docs.racket-lang.org/reference/performance-hint.html new file mode 100644 index 00000000..ae997790 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/performance-hint.html @@ -0,0 +1,12 @@ + +3.25 Performance Hints: begin-encourage-inline

3.25 Performance Hints: begin-encourage-inline

The bindings documented in this section are provided by the racket/performance-hint library, not racket/base or racket.

syntax

(begin-encourage-inline form ...)

Attaches a 'compiler-hint:cross-module-inline +syntax property to each form, which is useful when a +form is a function definition. See define-values.

The begin-encourage-inline form is also provided by the +(submod racket/performance-hint begin-encourage-inline) module, +which has fewer dependencies than racket/performance-hint.

Changed in version 6.2 of package base: Added the (submod racket/performance-hint begin-encourage-inline) submodule.

syntax

(define-inline id expr)

(define-inline (head args) body ...+)
 
head = id
  | (head args)
     
args = arg ...
  | arg ... . rest-id
     
arg = arg-id
  | [arg-id default-expr]
  | keyword arg-id
  | keyword [arg-id default-expr]
Like define, but ensures that the definition will be inlined at its +call sites. Recursive calls are not inlined, to avoid infinite inlining. +Higher-order uses are supported, but also not inlined. Misapplication (by +supplying the wrong number of arguments or incorrect keyword arguments) is +also not inlined and left as a run-time error.

The define-inline form may interfere with the Racket compiler’s own inlining +heuristics, and should only be used when other inlining attempts (such as +begin-encourage-inline) fail.

Changed in version 8.1.0.5 of package base: Changed to treat misapplication as a run-time error.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/phantom-bytes.html b/clones/docs.racket-lang.org/reference/phantom-bytes.html new file mode 100644 index 00000000..8e1baf5e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/phantom-bytes.html @@ -0,0 +1,19 @@ + +16.5 Phantom Byte Strings

16.5 Phantom Byte Strings

A phantom byte string is a small Racket value that is +treated by the Racket memory manager as having an arbitrary size, +which is specified when the phantom byte string is created or +when it is changed via set-phantom-bytes!.

A phantom byte string acts as a hint to Racket’s memory +manager that memory is allocated within the process but through a +separate allocator, such as through a foreign library that is accessed +via ffi/unsafe. This hint is used to trigger +garbage collections or to compute the result of +current-memory-use.

procedure

(phantom-bytes? v)  boolean?

  v : any/c
Returns #t if v is a phantom byte string, +#f otherwise.

Creates a phantom byte string that is treated by the Racket +memory manager as being k bytes in size. For a large enough +k, the exn:fail:out-of-memory exception is raised—either because the +size is implausibly large, or because a memory limit has been +installed with custodian-limit-memory.

procedure

(set-phantom-bytes! phantom-bstr k)  phantom-bytes?

  phantom-bstr : phantom-bytes?
  k : exact-nonnegative-integer?
Adjusts the size of a phantom byte string as it is treated by +the Racket memory manager.

For example, if the memory that phantom-bstr represents is +released through a foreign library, then (set-phantom-bytes! phantom-bstr 0) can reflect the change in memory use.

When k is larger than the current size of +phantom-bstr, then this function can raise +exn:fail:out-of-memory, like make-phantom-bytes.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/phase_space.html b/clones/docs.racket-lang.org/reference/phase_space.html new file mode 100644 index 00000000..ad4e079d --- /dev/null +++ b/clones/docs.racket-lang.org/reference/phase_space.html @@ -0,0 +1,39 @@ + +12.13 Phase and Space Utilities

12.13 Phase and Space Utilities

The bindings documented in this section are provided by the racket/phase+space library, not racket/base or racket.

The racket/phase+space library provides functions for +manipulating combined representations of phase levels and +binding spaces, particularly as used for require +transformers and provide transformers.

When identifier-binding (and related functions, like +identifier-transformer-binding), +syntax-local-module-exports, +syntax-local-module-required-identifiers, +module-compiled-exports, or module->exports produces +a phase–space combination (or phase–space shift combination), then +two such values that are equal? will be eqv?.

Added in version 8.2.0.3 of package base.

procedure

(phase? v)  boolean?

  v : any/c
Returns #t if v is a valid representation of a +phase level, #f otherwise. A valid representation +is either an exact integer representing a numbered +phase level or #f representing the label phase level.

procedure

(space? v)  boolean?

  v : any/c
Returns #t if v is a valid representation of a +binding space, #f otherwise. A valid representation +is either an interned symbol representing the space whose +scope is accessed via make-interned-syntax-introducer, or +#f representing the default binding space.

procedure

(phase+space? v)  boolean?

  v : any/c
Returns #t if v is a valid representation of a +phase level and binding space combination, +#f otherwise. The possible +representations are as follows:

  • a phase (in the sense of phase?) by itself, which +represents that phase plus the default binding space

  • a pair whose car is a phase and whose cdr is +a non-#f space (in the sense of space?)

procedure

(phase+space phase space)  phase+space?

  phase : phase?
  space : space?
Returns a value to represent the combination of phase and +space.

procedure

(phase+space-phase p+s)  phase?

  p+s : phase+space?

procedure

(phase+space-space p+s)  phase?

  p+s : phase+space?
Extracts the phase level or binding space component from +a combination.

procedure

(phase+space-shift? v)  boolean?

  v : any/c
Returns #t if v is a valid representation of a +phase level shift and binding space shift combination, +#f otherwise. A +shift can be applied to a combination of a phase level and binding +space using phase+shift+. The possible representations of a +shift are as follows:

  • exact integer — represents an amount to shift a phase level + and no change to the binding space

  • #f represents a shift to the label phase level + and no change to the binding space

  • a pair whose car is an exact integer or #f, +and whose cdr is a space (in the sense of +space?) — represents a phase level shift in the +car and a change to the binding space that is in the +cdr

procedure

(phase+space+ p+s shift)  phase+space?

  p+s : phase+space?
  shift : phase+space-shift?
Applies shift to p+s to produce a new combination of +phase level and binding space.

procedure

(phase+space-shift+ shift additional-shift)  phase+space-shift?

  shift : phase+space?
  additional-shift : phase+space-shift?
Composes shift and additional-shift to produce a new +shift that behaves the same as applying shift followed by +additional-shift.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/pipeports.html b/clones/docs.racket-lang.org/reference/pipeports.html new file mode 100644 index 00000000..e0f680ec --- /dev/null +++ b/clones/docs.racket-lang.org/reference/pipeports.html @@ -0,0 +1,23 @@ + +13.1.7 Pipes
13.1.7 Pipes

A Racket pipe is internal to Racket, and not related to +OS-level pipes for communicating between different +processes.OS-level pipes may be created by +subprocess, opening an existing named file on a Unix +filesystem, or starting Racket with pipes for its original input, +output, or error port. Such pipes are file-stream ports, +unlike the pipes produced by make-pipe.

procedure

(make-pipe [limit input-name output-name])

  
input-port? output-port?
  limit : exact-positive-integer? = #f
  input-name : any/c = 'pipe
  output-name : any/c = 'pipe
Returns two port values: the first port is an input port and the +second is an output port. Data written to the output port is read from +the input port, with no intermediate buffering. Unlike some other +kinds of ports, pipe ports do not need to be explicitly closed to be +reclaimed by garbage collection.

If limit is #f, the new pipe holds an unlimited +number of unread bytes (i.e., limited only by the available +memory). If limit is a positive number, then the pipe will +hold at most limit unread/unpeeked bytes; writing to the +pipe’s output port thereafter will block until a read or peek from the +input port makes more space available. (Peeks effectively extend the +port’s capacity until the peeked bytes are read.)

The optional input-name and output-name are used +as the names for the returned input and output ports, respectively.

procedure

(pipe-content-length pipe-port)  exact-nonnegative-integer?

  pipe-port : port?
Returns the number of bytes contained in a pipe, where +pipe-port is either of the pipe’s ports produced by +make-pipe. The pipe’s content length counts all bytes that +have been written to the pipe and not yet read (though possibly +peeked).

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/places.html b/clones/docs.racket-lang.org/reference/places.html new file mode 100644 index 00000000..e0fa24d7 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/places.html @@ -0,0 +1,215 @@ + +11.5 Places

11.5 Places

+Parallelism with Places in The Racket Guide introduces places.

The bindings documented in this section are provided by the racket/place, racket/place/dynamic, and racket libraries, but not racket/base.

Places enable the development of parallel programs that +take advantage of machines with multiple processors, cores, or +hardware threads.

Currently, parallel support for places is enabled +on all platforms that support Racket CS, the default implementation of Racket. +The 3m implementation also supports parallel execution of places +by default on Windows, Linux x86/x86_64, and Mac OS x86/x86_64. To +enable support for other platforms with 3m, use --enable-places with +configure when building Racket. The place-enabled? +function reports whether places run in parallel.

Implementation and operating-system constraints may limit the +scalability of places. For example, although places can perform +garbage collections in parallel in the CS implementation or independently +in the 3m implementation, a garbage collection +may need to manipulate a page table that is shared across all +places, and that shared page table can be a bottleneck with enough +places—perhaps around 8 or 16.

A place is a parallel task that is effectively a separate +instance of the Racket virtual machine, although all places run within +a single operating-system process. Places communicate through +place channels, which are endpoints for a two-way buffered +communication.

To a first approximation, place channels support only immutable, +transparent values as messages. In addition, place +channels themselves can be sent across channels to establish new +(possibly more direct) lines of communication in addition to any +existing lines. Finally, mutable values produced by +shared-flvector, make-shared-flvector, +shared-fxvector, make-shared-fxvector, +shared-bytes, and make-shared-bytes can be sent +across place channels; mutation of such values is visible to all +places that share the value, because they are allowed in a +shared memory space. See place-message-allowed?.

A place channel can be used as a synchronizable event +(see Events) to receive a value through the channel. +A place channel is ready for synchronization when +a message is available on the channel, and the place channel’s +synchronization result is the message (which is removed on +synchronization). A place +can also receive messages with place-channel-get, and +messages can be sent with place-channel-put.

Two place channels are equal? if they are endpoints +for the same underlying channels while both or neither is a +place descriptor. Place channels can be equal? +without being eq? after being sent messages through a +place channel.

Constraints on messages across a place channel—and therefore on the +kinds of data that places share—enable greater parallelism than +future, even including separate garbage collection of +separate places. At the same time, the setup and communication costs +for places can be higher than for futures.

For example, the following expression launches two places, echoes a +message to each, and then waits for the places to terminate:

(let ([pls (for/list ([i (in-range 2)])
              (dynamic-place "place-worker.rkt" 'place-main))])
   (for ([i (in-range 2)]
         [p pls])
      (place-channel-put p i)
      (printf "~a\n" (place-channel-get p)))
   (map place-wait pls))

The "place-worker.rkt" module (in a file that +is separate from the above code) must export the +place-main function that each place executes, where +place-main must accept a single place channel +argument:

"place-worker.rkt"

#lang racket
(provide place-main)
 
(define (place-main pch)
  (place-channel-put pch (format "Hello from place ~a"
                                  (place-channel-get pch))))

Place channels are subject to garbage collection, like other +Racket values, and a thread that is blocked reading from a +place channel can be garbage collected if place +channel’s writing end becomes unreachable. However, unlike normal channel blocking, +if otherwise unreachable threads are mutually blocked on place +channels that are reachable only from the same threads, the threads +and place channels are all considered reachable, instead of +unreachable.

When a place is created, its parameter values are generally set +to the initial values of the parameters in the creating place, +except that the current values of the following parameters are +used: current-library-collection-paths, +current-library-collection-links, and +current-compiled-file-roots.

A newly created place is registered with the current custodian, +so that the place is terminated when the custodian is shut down.

11.5.1 Using Places

procedure

(place-enabled?)  boolean?

Returns #t if Racket is configured so that +dynamic-place and place create places that can run +in parallel, #f if dynamic-place and place +are simulated using thread.

procedure

(place? v)  boolean?

  v : any/c
Returns #t if v is a place descriptor +value, #f otherwise. Every place descriptor +is also a place channel.

procedure

(place-channel? v)  boolean?

  v : any/c
Returns #t if v is place channel, +#f otherwise.

procedure

(dynamic-place module-path    
  start-name    
  [#:at location    
  #:named named])  place?
  module-path : (or/c module-path? path?)
  start-name : symbol?
  location : (or/c #f place-location?) = #f
  named : any/c = #f
Creates a place to run the procedure that is identified by + module-path and start-name. The result is a + place descriptor value that represents the new parallel task; + the place descriptor is returned immediately. The place descriptor + value is also a place channel that permits communication with + the place.

The module indicated by module-path must export a function + with the name start-name. The function must accept a single + argument, which is a place channel that corresponds to the + other end of communication for the place descriptor returned + by place.

If location is provided, it must be a place location, +such as a distributed places node produced by create-place-node.

When the place is created, the initial exit handler + terminates the place, using the argument to the exit handler as the + place’s completion value. Use (exit v) to + immediately terminate a place with the completion value + v. Since a completion value is limited to an exact integer + between 0 and 255, any other value for v + is converted to 0.

If the function indicated by module-path and + start-name returns, then the place terminates with the + completion value 0.

In the created place, the current-input-port parameter is + set to an empty input port, while the values of the + current-output-port and current-error-port + parameters are connected to the current ports in the creating place. + If the output ports in the creating place are file-stream +ports, then the connected ports in the created place share the + underlying streams, otherwise a thread in the creating place + pumps bytes from the created place’s ports to the current ports in the + creating place.

Most parameters in the created place have their original + initial values, but the created place inherits the creating place’s + values for the following parameters: current-directory, + current-library-collection-paths, + current-library-collection-links, + and current-compiled-file-roots.

The module-path argument must not be a module path of the + form (quote sym) unless the module is predefined (see + module-predefined?).

The dynamic-place binding is protected in the sense of + protect-out, so access to this operation can be prevented + by adjusting the code inspector (see Code Inspectors).

Changed in version 8.2.0.7 of package base: Changed created place to inherit +the creating place’s current-directory +value.

procedure

(dynamic-place* module-path    
  start-name    
  [#:in in    
  #:out out    
  #:err err])  
place?
(or/c output-port? #f)
(or/c input-port? #f)
(or/c input-port? #f)
  module-path : (or/c module-path? path?)
  start-name : symbol?
  in : (or/c input-port? #f) = #f
  out : (or/c output-port? #f) = (current-output-port)
  err : (or/c output-port? #f) = (current-error-port)
Like dynamic-place, but accepts specific ports to the new + place’s ports, and returns a created port when #f is + supplied for a port. The in, out, and + err ports are connected to the current-input-port, + current-output-port, and current-error-port ports, + respectively, for the + place. Any of the ports can be #f, in which case a + file-stream port (for an operating-system pipe) + is created and returned by dynamic-place*. The + err argument can be 'stdout, in which case the + same file-stream port or that is supplied as standard + output is also used for standard error. For each port or + 'stdout that is provided, no pipe is created and the + corresponding returned value is #f.

The caller of dynamic-place* is responsible for closing all + returned ports; none are closed automatically.

The dynamic-place* procedure returns four values:

  • a place descriptor value representing the created place;

  • an output port piped to the place’s standard input, or +#f if in was a port;

  • an input port piped from the place’s standard output, or +#f if out was a port;

  • an input port piped from the place’s standard error, or +#f if err was a port or 'stdout.

The dynamic-place* binding is protected in the same way as + dynamic-place.

procedure

(place-wait p)  exact-integer?

  p : place?
Returns the completion value of the place indicated by p, +blocking until the place has terminated.

If any pumping threads were created to connect a +non-file-stream port to the ports in the place for p +(see dynamic-place), place-wait returns only when +the pumping threads have completed.

procedure

(place-dead-evt p)  evt?

  p : place?
Returns a synchronizable event (see Events) that is +ready for synchronization if and only if p has terminated. +The synchronization result of a place-dead event is the place-dead event itself.

If any pumping threads were created to connect a non-file-stream +port to the ports in the place for p (see + dynamic-place), the event returned by + place-dead-evt may become ready even if a pumping thread is + still running.

procedure

(place-kill p)  void?

  p : place?
Immediately terminates the place, setting the place’s +completion value to 1 if the place does not have a +completion value already.

procedure

(place-break p [kind])  void?

  p : place?
  kind : (or/c #f 'hang-up 'terminate) = #f
Sends the main thread of place p a break; see Breaks.

Returns two place channels. Data sent through the first +channel can be received through the second channel, and data sent +through the second channel can be received from the first.

Typically, one place channel is used by the current place to +send messages to a destination place; the other place channel +is sent to the destination place (via an existing place +channel).

procedure

(place-channel-put pch v)  void

  pch : place-channel?
  v : place-message-allowed?
Sends a message v on channel pch. Since place channels + are asynchronous, place-channel-put calls are non-blocking.

See place-message-allowed? form information on automatic +coercions in v, such as converting a mutable string to an +immutable string.

Returns a message received on channel pch, blocking until a +message is available.

procedure

(place-channel-put/get pch v)  any/c

  pch : place-channel?
  v : any/c
Sends an immutable message v on channel pch and then +waits for a message (perhaps a reply) on the same channel.

procedure

(place-message-allowed? v)  boolean?

  v : any/c
Returns #t if v is allowed as a message on a place channel, +#f otherwise.

If (place-enabled?) returns #f, then the result is +always #t and no conversions are performed on v as a +message. Otherwise, the following kinds of data are allowed as +messages:

Changed in version 8.4.0.7 of package base: Include boxes in allowed messages.

A structure type property and associated predicate for +implementations of place locations. The value of +prop:place-location must be a procedure of four arguments: +the place location itself, a module path, a symbol for the +start function exported by the module, and a place name (which can be +#f for an anonymous place).

A place location can be passed as the #:at argument to +dynamic-place, which in turn simply calls the +prop:place-location value of the place location.

A distributed places note created with create-place-node +is an example of a place location.

11.5.2 Syntactic Support for Using Places

The bindings in this section are not provided by +racket/place/dynamic.

syntax

(place id body ...+)

Creates a place that evaluates body + expressions with id bound to a place channel. The + bodys close only over id plus the top-level + bindings of the enclosing module, because the + bodys are lifted to a submodule. + The result of place is a place descriptor, + like the result of dynamic-place.

The generated submodule has the name place-body-n +for an integer n, and the submodule exports a main +function that takes a place channel for the new place. The submodule +is not intended for use, however, except by the expansion of the +place form.

The place binding is protected in the same way as + dynamic-place.

syntax

(place* maybe-port ...
        id
        body ...+)
 
maybe-port = 
  | #:in in-expr
  | #:out out-expr
  | #:err err-expr
Like place, but supports optional #:in, #:out, + and #:err expressions (at most one of each) to specify ports in the same way and + with the same defaults as dynamic-place*. The result of + a place* form is also the same as for dynamic-place*.

The place* binding is protected in the same way as + dynamic-place.

syntax

(place/context id body ...+)

Like place, but body ... may have free lexical +variables, which are automatically sent to the newly-created place. +Note that these variables must have values accepted by +place-message-allowed?, otherwise an exn:fail:contract exception is raised.

Returns the number of parallel computation units (e.g., processors or +cores) that are available on the current machine.

This is the same binding as available from racket/future.

11.5.3 Places Logging

Place events are reported to a logger named 'place. +In addition to its string message, each event logged for a place has +a data value that is an instance of a place-event +prefab structure:

(struct place-event (place-id action value time)
  #:prefab)

The place-id field is an exact integer that identifies a +place.

The time field is an inexact number that represents time in +the same way as current-inexact-milliseconds.

The action field is a symbol:

  • 'create: a place was created. This event is logged in the +creating place, and the event’s value field has the +ID for the created place.

  • 'reap: a place that was previously created in the +current place has exited (and that fact has been detected, +possibly via place-wait). The event’s value +field has the ID for the exited place.

  • 'enter: a place has started, logged within the started +place. The event’s value field has #f.

  • 'exit: a place is exiting, logged within the exiting +place. The event’s value field has #f.

  • 'put: a place-channel message has been sent. The +event’s value field is a positive exact integer that +approximates the message’s size.

  • 'get: a place-channel message has been received. The +event’s value field is a positive exact integer that +approximates the message’s size.

Changed in version 6.0.0.2 of package base: Added logging via 'place +and place-event.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/plumbers.html b/clones/docs.racket-lang.org/reference/plumbers.html new file mode 100644 index 00000000..6087e3e3 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/plumbers.html @@ -0,0 +1,35 @@ + +14.11 Plumbers

14.11 Plumbers

A plumber supports flush callbacks, which are +normally triggered just before a Racket process or place exits. +For example, a flush callback might flush an output port’s +buffer.

Flush callbacks are roughly analogous to the standard C +library’s atexit, but flush callback can also be used in other, +similar scenarios.

There is no guarantee that a flush callback will be called before a +process terminates—either because the plumber is not the original +plumber that is flushed by the default exit handler, or because +the process is terminated forcibly (e.g., through a custodian +shutdown).

procedure

(plumber? v)  boolean?

  v : any/c
Returns #t if v is a plumber value, +#f otherwise.

Added in version 6.0.1.8 of package base.

procedure

(make-plumber)  plumber?

Creates a new plumber.

Plumbers have no hierarchy (unlike custodians or +inspectors), but a flush callback can be registered in +one plumber to call plumber-flush-all with another plumber.

Added in version 6.0.1.8 of package base.

parameter

(current-plumber)  plumber?

(current-plumber plumber)  void?
  plumber : plumber?
A parameter that determines a current plumber for +flush callbacks. For example, creating an output file +stream port registers a flush callback with the current +plumber to flush the port as long as the port is opened.

Added in version 6.0.1.8 of package base.

procedure

(plumber-flush-all plumber)  void?

  plumber : plumber?
Calls all flush callbacks that are registered with plumber.

The flush callbacks to call are collected from plumber +before the first one is called. If a flush callback registers a +new flush callback, the new one is not called. If a +flush callback raises an exception or otherwise escapes, then +the remaining flush callbacks are not called.

Added in version 6.0.1.8 of package base.

procedure

(plumber-flush-handle? v)  boolean?

  v : any/c
Returns #t if v is a flush handle +represents the registration of a flush callback, #f +otherwise.

Added in version 6.0.1.8 of package base.

procedure

(plumber-add-flush! plumber proc [weak?])  plumber-flush-handle?

  plumber : plumber?
  proc : (plumber-flush-handle? . -> . any)
  weak? : any/c = #f
Registers proc as a flush callback with plumber, so +that proc is called when plumber-flush-all is +applied to plumber.

The result flush handle represents the registration of the +callback, and it can be used with plumber-flush-handle-remove! to +unregister the callback.

The given proc is reachable from the flush handle, but +if weak? is true, then plumber retains only a +weak reference to the result flush handle (and +thus proc).

When proc is called as a flush callback, it is passed +the same value that is returned by plumber-add-flush! so +that proc can conveniently unregister itself. The call of +proc is within a continuation barrier.

Added in version 6.0.1.8 of package base.

procedure

(plumber-flush-handle-remove! handle)  void?

  handle : plumber-flush-handle?
Unregisters the flush callback that was registered by the +plumber-add-flush! call that produced handle.

If the registration represented by handle has been removed already, +then plumber-flush-handle-remove! has no effect.

Added in version 6.0.1.8 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/port-buffers.html b/clones/docs.racket-lang.org/reference/port-buffers.html new file mode 100644 index 00000000..b7799e22 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/port-buffers.html @@ -0,0 +1,86 @@ + +13.1.3 Port Buffers and Positions
13.1.3 Port Buffers and Positions

Some ports—especially those that read from and write to files—are +internally buffered:

  • An input port is typically block-buffered by default, which +means that on any read, the buffer is filled with +immediately-available bytes to speed up future reads. Thus, if +a file is modified between a pair of reads to the file, the +second read can produce stale data. Calling +file-position to set an input port’s file position +flushes its buffer.

  • An output port is typically block-buffered by default, though +a terminal output port is line-buffered, and the initial error +output port is unbuffered. An output buffer is filled with a +sequence of written bytes to be committed as a group, either +when the buffer is full (in block mode), when a newline is +written (in line mode), when the port is closed via +close-output-port, or when a flush is explicitly +requested via a procedure like flush-output.

If a port supports buffering, its buffer mode can be changed via +file-stream-buffer-mode (even if the port is not a +file-stream port).

For an input port, peeking always places peeked bytes into the port’s +buffer, even when the port’s buffer mode is 'none; +furthermore, on some platforms, testing the port for input (via +char-ready? or sync) may be implemented with a +peek. If an input port’s buffer mode is 'none, then at most +one byte is read for read-bytes-avail!*, +read-bytes-avail!, peek-bytes-avail!*, or +peek-bytes-avail!; if any bytes are buffered in the port +(e.g., to satisfy a previous peek), the procedures may access multiple +buffered bytes, but no further bytes are read.

In addition, the initial current output and error ports are +automatically flushed when they are terminal ports (see +terminal-port?) and when read, read-line, +read-bytes, read-string, etc., are performed on the +initial standard input port. (More precisely, instead of +read, flushing is performed by the default port read handler; +see port-read-handler.)

procedure

(flush-output [out])  void?

  out : output-port? = (current-output-port)
Forces all buffered data in the given +output port to be physically written. Only file-stream ports, +TCP ports, and custom ports (see Custom Ports) use +buffers; when called on a port without a buffer, flush-output +has no effect.

If flushing a file-stream port or TCP port encounters an +error when writing, then all buffered bytes in the port are discarded. +Consequently, a further attempt to flush or close the port will not +fail.

Changed in version 7.4.0.10 of package base: Consistently, discard buffered bytes on error, +including in a TCP output port.

procedure

(file-stream-buffer-mode port)  (or/c 'none 'line 'block #f)

  port : port?
(file-stream-buffer-mode port mode)  void?
  port : port?
  mode : (or/c 'none 'line 'block)
Gets or sets the buffer mode for port, if +possible. File-stream ports support setting the buffer mode, +TCP ports (see Networking) support setting and getting +the buffer mode, and custom ports (see Custom Ports) may +support getting and setting buffer modes.

If mode is provided, it must be one of +'none, 'line (output only), or +'block, and the port’s buffering is set +accordingly. If the port does not support setting the mode, the +exn:fail exception is raised.

If mode is not provided, the current mode is returned, or +#f is returned if the mode cannot be determined. If +port is an input port and mode is +'line, the exn:fail:contract exception is raised.

procedure

(file-position port)  exact-nonnegative-integer?

  port : port?
(file-position port pos)  void?
  port : port?
  pos : (or/c exact-nonnegative-integer? eof-object?)
Returns or sets the current read/write position of port.

Calling file-position without a position on a port other +than a file-stream port or string port +returns the number of bytes that have +been read from that port if the position is known (see +Counting Positions, Lines, and Columns), otherwise the exn:fail:filesystem exception is raised.

For file-stream ports and string ports, the position-setting +variant sets the read/write position to pos relative to the +beginning of the file or (byte) string if pos is a number, or to the +current end of the file or (byte) string if pos is eof. In +position-setting mode, file-position raises the +exn:fail:contract exception for port kinds other than +file-stream ports and string ports. Furthermore, not all file-stream +ports support setting the position; if file-position is +called with a position argument on such a file-stream port, the +exn:fail:filesystem exception is raised.

When file-position sets the position pos beyond the +current size of an output file or (byte) string, the file/string is +enlarged to size pos and the new region is filled with +0 bytes; in the case of a file. In the case of a file output +port, the file might not be enlarged until more data is written to the +file; in that case, beware that writing to a file opened in +'append mode on Unix and Mac OS will reset the file pointer +to the end of a file before each write, which defeats file +enlargement via file-position. If pos is beyond the +end of an input file or (byte) string, then reading thereafter returns +eof without changing the port’s position.

When changing the file position for an output port, the port is first +flushed if its buffer is not empty. Similarly, setting the position +for an input port clears the port’s buffer (even if the new position +is the same as the old position). However, although input and output +ports produced by open-input-output-file share the file +position, setting the position via one port does not flush the other +port’s buffer.

procedure

(file-position* port)  (or/c exact-nonnegative-integer? #f)

  port : port?
Like file-position on a single argument, but returns +#f if the position is not known.

procedure

(file-truncate port size)  void?

  port : (and/c output-port? file-stream-port?)
  size : exact-nonnegative-integer?
Sets the size of the file written by port to size, +assuming that the port is associated to a file whose size can be set.

The new file size can be either larger or smaller than its current +size, but “truncate” in this function’s name reflects that it is +normally used to decrease the size of a file, since writing to a file +or using file-position can extend a file’s size.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/port-lib.html b/clones/docs.racket-lang.org/reference/port-lib.html new file mode 100644 index 00000000..3cda1571 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/port-lib.html @@ -0,0 +1,290 @@ + +13.1.10 More Port Constructors, Procedures, and Events
13.1.10 More Port Constructors, Procedures, and Events

 (require racket/port) package: base
The bindings documented in this section are provided by the racket/port and racket libraries, but not racket/base.

13.1.10.1 Port String and List Conversions

procedure

(port->list [r in])  (listof any/c)

  r : (input-port? . -> . any/c) = read
  in : input-port? = (current-input-port)
Returns a list whose elements are produced by calling r +on in until it produces eof.

Examples:
> (define (read-number input-port)
    (define char (read-char input-port))
    (if (eof-object? char)
     char
     (string->number (string char))))
> (port->list read-number (open-input-string "12345"))

'(1 2 3 4 5)

procedure

(port->string [in #:close? close?])  string?

  in : input-port? = (current-input-port)
  close? : any/c = #f
Reads all characters from in and returns them as a string. +The input port is closed unless close? is #f.

Example:
> (port->string (open-input-string "hello world"))

"hello world"

Changed in version 6.8.0.2 of package base: Added the #:close? argument.

procedure

(port->bytes [in #:close? close?])  bytes?

  in : input-port? = (current-input-port)
  close? : any/c = #f
Reads all bytes from in and returns them as a byte string. +The input port is closed unless close? is #f.

Example:
> (port->bytes (open-input-string "hello world"))

#"hello world"

Changed in version 6.8.0.2 of package base: Added the #:close? argument.

procedure

(port->lines [in    
  #:line-mode line-mode    
  #:close? close?])  (listof string?)
  in : input-port? = (current-input-port)
  line-mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'any
  close? : any/c = #f
Read all characters from in, breaking them into lines. The +line-mode argument is the same as the second argument to +read-line, but the default is 'any instead of +'linefeed. +The input port is closed unless close? is #f.

Example:
> (port->lines
   (open-input-string "line 1\nline 2\n  line 3\nline 4"))

'("line 1" "line 2" "  line 3" "line 4")

Changed in version 6.8.0.2 of package base: Added the #:close? argument.

procedure

(port->bytes-lines [in    
  #:line-mode line-mode    
  #:close? close?])  (listof bytes?)
  in : input-port? = (current-input-port)
  line-mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'any
  close? : any/c = #f
Like port->lines, but reading bytes and collecting them into +lines like read-bytes-line. +The input port is closed unless close? is #f.

Example:
> (port->bytes-lines
   (open-input-string "line 1\nline 2\n  line 3\nline 4"))

'(#"line 1" #"line 2" #"  line 3" #"line 4")

Changed in version 6.8.0.2 of package base: Added the #:close? argument.

procedure

(display-lines lst    
  [out    
  #:separator separator])  void?
  lst : list?
  out : output-port? = (current-output-port)
  separator : any/c = #"\n"
Uses display on each element of lst to out, adding +separator after each element.

procedure

(call-with-output-string proc)  string?

  proc : (output-port? . -> . any)
Calls proc with an output port that accumulates all output +into a string, and returns the string.

The port passed to proc is like the one created by +open-output-string, except that it is wrapped via +dup-output-port, so that proc cannot access the +port’s content using get-output-string. If control jumps back +into proc, the port continues to accumulate new data, and +call-with-output-string returns both the old data and newly +accumulated data.

procedure

(call-with-output-bytes proc)  bytes?

  proc : (output-port? . -> . any)
Like call-with-output-string, but returns the accumulated result +in a byte string instead of a string. Furthermore, the port’s +content is emptied when call-with-output-bytes returns, so +that if control jumps back into proc and returns a second +time, only the newly accumulated bytes are returned.

procedure

(with-output-to-string proc)  string?

  proc : (-> any)
Equivalent to

(call-with-output-string
 (lambda (p) (parameterize ([current-output-port p])
               (proc))))

procedure

(with-output-to-bytes proc)  bytes?

  proc : (-> any)
Equivalent to

(call-with-output-bytes
 (lambda (p) (parameterize ([current-output-port p])
               (proc))))

procedure

(call-with-input-string str proc)  any

  str : string?
  proc : (input-port? . -> . any)
Equivalent to (proc (open-input-string str)).

procedure

(call-with-input-bytes bstr proc)  any

  bstr : bytes?
  proc : (input-port? . -> . any)
Equivalent to (proc (open-input-bytes bstr)).

procedure

(with-input-from-string str proc)  any

  str : string?
  proc : (-> any)
Equivalent to

(parameterize ([current-input-port (open-input-string str)])
  (proc))

procedure

(with-input-from-bytes bstr proc)  any

  bstr : bytes?
  proc : (-> any)
Equivalent to

(parameterize ([current-input-port (open-input-bytes str)])
  (proc))
13.1.10.2 Creating Ports

procedure

(input-port-append close-at-eof?    
  in ...    
  [#:name name])  input-port?
  close-at-eof? : any/c
  in : input-port?
  name : any/c = (map object-name in)
Takes any number of input ports and returns an input port. Reading +from the input port draws bytes (and special non-byte values) from the +given input ports in order. If close-at-eof? is true, then +each port is closed when an end-of-file is encountered from the port, +or when the result input port is closed. Otherwise, data not read from +the returned input port remains available for reading in its original +input port.

The name argument determines the name as reported by +object-name for the returned input port.

See also merge-input, which interleaves data from multiple +input ports as it becomes available.

Changed in version 6.90.0.19 of package base: Added the name argument.

procedure

(make-input-port/read-to-peek name    
  read-in    
  fast-peek    
  close    
  [get-location    
  count-lines!    
  init-position    
  buffer-mode    
  buffering?    
  on-consumed])  input-port?
  name : any/c
  read-in : 
(bytes?
 . -> . (or/c exact-nonnegative-integer?
              eof-object?
              procedure?
              evt?))
  fast-peek : 
(or/c #f
      (bytes? exact-nonnegative-integer?
       (bytes? exact-nonnegative-integer?
        . -> . (or/c exact-nonnegative-integer?
                     eof-object?
                     procedure?
                     evt?
                     #f))
       . -> . (or/c exact-nonnegative-integer?
                    eof-object?
                    procedure?
                    evt?
                    #f)))
  close : (-> any)
  get-location : 
(or/c
 (->
  (values
   (or/c exact-positive-integer? #f)
   (or/c exact-nonnegative-integer? #f)
   (or/c exact-positive-integer? #f)))
 #f)
 = #f
  count-lines! : (-> any) = void
  init-position : exact-positive-integer? = 1
  buffer-mode : 
(or/c (case-> ((or/c 'block 'none) . -> . any)
              (-> (or/c 'block 'none #f)))
      #f)
   = #f
  buffering? : any/c = #f
  on-consumed : 
(or/c ((or/c exact-nonnegative-integer? eof-object?
             procedure? evt?)
       . -> . any)
      #f)
   = #f
Similar to make-input-port, but if the given read-in +returns an event, the event’s value must be 0. The resulting +port’s peek operation is implemented automatically (in terms of +read-in) in a way that can handle special non-byte +values. The progress-event and commit operations are also implemented +automatically. The resulting port is thread-safe, but not kill-safe +(i.e., if a thread is terminated or suspended while using the port, +the port may become damaged).

The read-in, close, get-location, +count-lines!, init-position, and +buffer-mode procedures are the same as for +make-input-port.

The fast-peek argument can be either #f or a +procedure of three arguments: a byte string to receive a peek, a skip +count, and a procedure of two arguments. The fast-peek +procedure can either implement the requested peek, or it can dispatch +to its third argument to implement the peek. The fast-peek is +not used when a peek request has an associated progress event.

The buffering? argument determines whether read-in +can be called to read more characters than are immediately demanded by +the user of the new port. If buffer-mode is not #f, +then buffering? determines the initial buffer mode, and +buffering? is enabled after a buffering change only if the +new mode is 'block.

If on-consumed is not #f, it is called when data is +read (or committed) from the port, as opposed to merely peeked. The argument to +on-consumed is the result value of the port’s reading +procedure, so it can be an integer or any result from +read-in.

procedure

(make-limited-input-port in    
  limit    
  [close-orig?])  input-port?
  in : input-port?
  limit : exact-nonnegative-integer?
  close-orig? : any/c = #t
Returns a port whose content is drawn from in, but where an +end-of-file is reported after limit bytes (and non-byte +special values) have been read. If close-orig? is true, then the +original port is closed if the returned port is closed.

Bytes are consumed from in only when they are consumed from +the returned port. In particular, peeking into the returned port peeks +into the original port.

If in is used directly while the resulting port is also used, +then the limit bytes provided by the port need not be +contiguous parts of the original port’s stream.

procedure

(make-pipe-with-specials [limit    
  in-name    
  out-name])  
input-port? output-port?
  limit : exact-nonnegative-integer? = #f
  in-name : any/c = 'pipe
  out-name : any/c = 'pipe
Returns two ports: an input port and an output port. The ports behave +like those returned by make-pipe, except that the ports +support non-byte values written with procedures such as +write-special and read with procedures such as +get-byte-or-special.

The limit argument determines the maximum capacity of the +pipe in bytes, but this limit is disabled if special values are +written to the pipe before limit is reached. The limit is +re-enabled after the special value is read from the pipe.

The optional in-name and out-name arguments +determine the names of the result ports.

procedure

(combine-output a-out b-out)  output-port?

  a-out : output-port?
  b-out : output-port?
Accepts two output ports and returns a new output port +combining the original ports. When written to, the combined port +first writes as many bytes as possible to a-out, and then +tries to write the same number of bytes to b-out. If that +doesn’t succeed, what is left over is buffered and no further writes +can go through until the ports are evened out. The port is ready (for +the purposes of synchronization) when each port reports being ready. +However, the first port may stop being ready while waiting on +the second port to sync, so it cannot be guaranteed that both +ports are ready at once. Closing the combined port is done +after writing all remaining bytes to b-out.

Added in version 7.7.0.10 of package base.

procedure

(merge-input a-in b-in [buffer-limit])  input-port?

  a-in : input-port?
  b-in : input-port?
  buffer-limit : (or/c exact-nonnegative-integer? #f) = 4096
Accepts two input ports and returns a new input port. The new port +merges the data from two original ports, so data can be read from the +new port whenever it is available from either of the two original ports. The data +from the original ports are interleaved. When an end-of-file has been +read from an original port, it no longer contributes characters to the +new port. After an end-of-file has been read from both original ports, +the new port returns end-of-file. Closing the merged port does not +close the original ports.

The optional buffer-limit argument limits the number of bytes +to be buffered from a-in and b-in, so that the merge +process does not advance arbitrarily beyond the rate of consumption of +the merged data. A #f value disables the limit. As for +make-pipe-with-specials, buffer-limit does not apply +when a special value is produced by one of the input ports before the +limit is reached.

See also input-port-append, which concatenates input streams +instead of interleaving them.

procedure

(open-output-nowhere [name special-ok?])  output-port?

  name : any/c = 'nowhere
  special-ok? : any/c = #t
Creates and returns an output port that discards all output sent to it +(without blocking). The name argument is used as the port’s +name. If the special-ok? argument is true, then the +resulting port supports write-special, otherwise it does not.

procedure

(peeking-input-port in 
  [name 
  skip 
  #:init-position init-position]) 
  input-port?
  in : input-port?
  name : any/c = (object-name in)
  skip : exact-nonnegative-integer? = 0
  init-position : exact-positive-integer? = 1
Returns an input port whose content is determined by peeking into +in. In other words, the resulting port contains an internal +skip count, and each read of the port peeks into in with the +internal skip count, and then increments the skip count according to +the amount of data successfully peeked.

The optional name argument is the name of the resulting +port. The skip argument is the port initial skip count, and +it defaults to 0.

The resulting port’s initial position (as reported by file-position) +is (- init-position 1), no matter the position of in.

The resulting port supports buffering, and a 'block buffer +mode allows the port to peek further into in than +requested. The resulting port’s initial buffer mode is +'block, unless in supports buffer mode and its mode +is initially 'none (i.e., the initial buffer mode is taken +from in when it supports buffering). If in supports +buffering, adjusting the resulting port’s buffer mode via +file-stream-buffer-mode adjusts in’s buffer mode.

For example, when you read from a peeking port, you +see the same answers as when you read from the original port:

Examples:
> (define an-original-port (open-input-string "123456789"))
> (define a-peeking-port (peeking-input-port an-original-port))
> (file-stream-buffer-mode a-peeking-port 'none)
> (read-string 3 a-peeking-port)

"123"

> (read-string 3 an-original-port)

"123"

Beware that the read from the original port is invisible to the peeking +port, which keeps its own separate internal counter, and thus +interleaving reads on the two ports can produce confusing results. +Continuing the example before, if we read three more characters from +the peeking port, we end up skipping over the 456 in the port +(but only because we disabled buffering above):

Example:
> (read-string 3 a-peeking-port)

"789"

If we had left the buffer mode of a-peeking-port alone, that +last read-string would have likely produced "456" as +a result of buffering bytes from an-original-port earlier.

Changed in version 6.1.0.3 of package base: Enabled buffering and buffer-mode +adjustments via file-stream-buffer-mode, +and set the port’s initial buffer mode to that of +in.

procedure

(reencode-input-port in    
  encoding    
  [error-bytes    
  close?    
  name    
  convert-newlines?    
  enc-error])  input-port?
  in : input-port?
  encoding : string?
  error-bytes : (or/c #f bytes?) = #f
  close? : any/c = #f
  name : any/c = (object-name in)
  convert-newlines? : any/c = #f
  enc-error : (string? input-port? . -> . any)
   = (lambda (msg port) (error ...))
Produces an input port that draws bytes from in, but converts +the byte stream using (bytes-open-converter encoding-str "UTF-8"). In addition, if convert-newlines? is true, then +decoded sequences that correspond to UTF-8 encodings of "\r\n", +"\r\u0085", "\r", "\u0085", and "\u2028" +are all converted to the UTF-8 encoding of "\n".

If error-bytes is provided and not #f, then the +given byte sequence is used in place of bytes from in that +trigger conversion errors. Otherwise, if a conversion is encountered, +enc-error is called, which must raise an exception.

If close? is true, then closing the result input port also +closes in. The name argument is used as the name of +the result input port.

In non-buffered mode, the resulting input port attempts to draw bytes +from in only as needed to satisfy requests. Toward that end, +the input port assumes that at least n bytes must be read to +satisfy a request for n bytes. (This is true even if the port +has already drawn some bytes, as long as those bytes form an +incomplete encoding sequence.)

procedure

(reencode-output-port out    
  encoding    
  [error-bytes    
  close?    
  name    
  newline-bytes    
  enc-error])  output-port?
  out : output-port?
  encoding : string?
  error-bytes : (or/c #f bytes?) = #f
  close? : any/c = #f
  name : any/c = (object-name out)
  newline-bytes : (or/c #f bytes?) = #f
  enc-error : (string? output-port? . -> . any)
   = (lambda (msg port) (error ...))
Produces an output port that directs bytes to out, but +converts its byte stream using (bytes-open-converter "UTF-8" encoding-str). In addition, if newline-bytes is not +#f, then bytes written to the port that are the UTF-8 +encoding of "\n" are first converted to +newline-bytes (before applying the convert from UTF-8 to +encoding-str).

If error-bytes is provided and not #f, then the +given byte sequence is used in place of bytes that have been sent to the output port +and that trigger conversion errors. Otherwise, enc-error is +called, which must raise an exception.

If close? is true, then closing the result output port also +closes out. The name argument is used as the name of +the result output port.

The resulting port supports buffering, and the initial buffer mode is +(or (file-stream-buffer-mode out) 'block). In 'block +mode, the port’s buffer is flushed only when it is full or a flush is +requested explicitly. In 'line mode, the buffer is flushed +whenever a newline or carriage-return byte is written to the port. In +'none mode, the port’s buffer is flushed after every write. +Implicit flushes for 'line or 'none leave bytes in +the buffer when they are part of an incomplete encoding sequence.

The resulting output port does not support atomic writes. An explicit +flush or special-write to the output port can hang if the most +recently written bytes form an incomplete encoding sequence.

When the port is buffered, a flush callback is registered with +the current plumber to flush the buffer.

procedure

(dup-input-port in [close?])  input-port?

  in : input-port?
  close? : any/c = #f
Returns an input port that draws directly from in. Closing +the resulting port closes in only if close? is +#t.

The new port is initialized with the port read handler of +in, but setting the handler on the result port does not +affect reading directly from in.

procedure

(dup-output-port out [close?])  output-port?

  out : output-port?
  close? : any/c = #f
Returns an output port that propagates data directly to +out. Closing the resulting port closes out only if +close? is #t.

The new port is initialized with the port display handler and +port write handler of out, but setting the handlers on +the result port does not affect writing directly to out.

procedure

(relocate-input-port in    
  line    
  column    
  position    
  [close?]    
  #:name name)  input-port?
  in : input-port?
  line : (or/c exact-positive-integer? #f)
  column : (or/c exact-nonnegative-integer? #f)
  position : exact-positive-integer?
  close? : any/c = #t
  name : (object-name in)
Produces an input port that is equivalent to in except in how +it reports location information (and possibly its name). The resulting port’s content starts +with the remaining content of in, and it starts at the given +line, column, and position. A #f for the line or column means +that the line and column will always be reported as #f.

The line and column values are used only if line +counting is enabled for in and for the resulting port, +typically through port-count-lines!. The column +value determines the column for the first line (i.e., the one numbered +line), and later lines start at column 0. The given +position is used even if line counting is not enabled.

When line counting is on for the resulting port, reading from +in instead of the resulting port increments location reports +from the resulting port. Otherwise, the resulting port’s position does +not increment when data is read from in.

If close? is true, then closing the resulting port also +closes in. If close? is #f, then closing +the resulting port does not close in.

The name argument is used as the name for the resulting port; +the default value keeps the same name as in.

procedure

(relocate-output-port out    
  line    
  column    
  position    
  [close?]    
  #:name name)  output-port?
  out : output-port?
  line : (or/c exact-positive-integer? #f)
  column : (or/c exact-nonnegative-integer? #f)
  position : exact-positive-integer?
  close? : any/c = #t
  name : (object-name out)
Like relocate-input-port, but for output ports.

procedure

(transplant-input-port in    
  get-location    
  init-pos    
  [close?    
  count-lines!]    
  #:name name)  input-port?
  in : input-port?
  get-location : 
(or/c
 (->
  (values
   (or/c exact-positive-integer? #f)
   (or/c exact-nonnegative-integer? #f)
   (or/c exact-positive-integer? #f)))
 #f)
  init-pos : exact-positive-integer?
  close? : any/c = #t
  count-lines! : (-> any) = void
  name : (object-name in)
Like relocate-input-port, except that arbitrary position +information can be produced (when line counting is enabled) via +get-location, which is used as for make-input-port. If +get-location is #f, then the port counts lines in +the usual way starting from init-pos, independent of +locations reported by in.

If count-lines! is supplied, it is called when line counting +is enabled for the resulting port. The default is void.

procedure

(transplant-output-port out    
  get-location    
  init-pos    
  [close?    
  count-lines!]    
  #:name name)  output-port?
  out : output-port?
  get-location : 
(or/c
 (->
  (values
   (or/c exact-positive-integer? #f)
   (or/c exact-nonnegative-integer? #f)
   (or/c exact-positive-integer? #f)))
 #f)
  init-pos : exact-positive-integer?
  close? : any/c = #t
  count-lines! : (-> any) = void
  name : (object-name out)
Like transplant-input-port, but for output ports.

procedure

(filter-read-input-port in    
  read-wrap    
  peek-wrap    
  [close?])  input-port?
  in : input-port?
  read-wrap : 
(bytes? (or/c exact-nonnegative-integer?
              eof-object?
              procedure?
              evt?)
        . -> .
        (or/c exact-nonnegative-integer?
              eof-object?
              procedure?
              evt?))
  peek-wrap : 
(bytes? exact-nonnegative-integer? (or/c evt? #f)
        (or/c exact-nonnegative-integer?
         eof-object?
         procedure?
         evt?
         #f)
 . -> . (or/c exact-nonnegative-integer?
         eof-object?
         procedure?
         evt?
         #f))
  close? : any/c = #t
Creates a port that draws from in, but each result from the +port’s read and peek procedures (in the sense of make-input-port) +is filtered by read-wrap and +peek-wrap. The filtering procedures each receive both the +arguments and results of the read and peek procedures on in +for each call.

If close? is true, then closing the resulting port also +closes in.

procedure

(special-filter-input-port in proc [close?])  input-port?

  in : input-port?
  proc : 
(procedure? bytes? . -> . (or/c exact-nonnegative-integer?
                                eof-object?
                                procedure?
                                evt?))
  close? : any/c = #t
Produces an input port that is equivalent to in, except +that when in produces a procedure to access a special value, +proc is applied to the procedure to allow the special value +to be replaced with an alternative. The proc is called with +the special-value procedure and the byte string that was given to the +port’s read or peek function (see make-input-port), and the +result is used as the read or peek function’s result. The +proc can modify the byte string to substitute a byte for the +special value, but the byte string is guaranteed only to hold at least +one byte.

If close? is true, then closing the resulting input port also +closes in.

13.1.10.3 Port Events

procedure

(eof-evt in)  evt?

  in : input-port?
Returns a synchronizable event that is ready when +in produces an eof. If in produces a +mid-stream eof, the eof is consumed by the event +only if the event is chosen in a synchronization.

If attempting to read from in raises an exception during a +synchronization attempt, then the exception may be reported during the +synchronization attempt, but it will silently discarded if some another +event in the same synchronization is selected or if some other event +raises an exception first.

Changed in version 7.5.0.3 of package base: Changed handling of read errors so +they are propagated to a synchronization attempt, +instead of treated as unhandled errors in a +background thread.

procedure

(read-bytes-evt k in)  evt?

  k : exact-nonnegative-integer?
  in : input-port?
Returns a synchronizable event that is ready when k +bytes can be read from in, or when an end-of-file is +encountered in in. If k is 0, then the +event is ready immediately with "". For non-zero k, +if no bytes are available before an end-of-file, the event’s result is +eof. Otherwise, the event’s result is a byte string of up to +k bytes, which contains as many bytes as are available (up to +k) before an available end-of-file. (The result is a byte +string on less than k bytes only when an end-of-file is +encountered.)

Bytes are read from the port if and only if the event is chosen in a +synchronization, and the returned bytes always represent contiguous +bytes in the port’s stream.

The event can be synchronized multiple times—event +concurrently—and each synchronization corresponds to a distinct read +request.

The in must support progress events, and it must not produce +a special non-byte value during the read attempt.

Exceptions attempting to read from in are handled in the same +way as by eof-evt.

procedure

(read-bytes!-evt bstr in)  evt?

  bstr : (and/c bytes? (not/c immutable?))
  in : input-port?
Like read-bytes-evt, except that the read bytes are placed +into bstr, and the number of bytes to read corresponds to +(bytes-length bstr). The event’s result is either +eof or the number of read bytes.

The bstr may be mutated any time after the first +synchronization attempt on the event and until either the event is +selected, a non-#f progress-evt is ready, or the +current custodian (at the time of synchronization) is shut +down. Note that there is no time bound otherwise on when bstr +might be mutated if the event is not selected by a synchronzation; +nevertheless, multiple synchronization attempts can use the same +result from read-bytes!-evt as long as there is no +intervening read on in until one of the synchronization +attempts selects the event.

Exceptions attempting to read from in are handled in the same +way as by eof-evt.

procedure

(read-bytes-avail!-evt bstr in)  evt?

  bstr : (and/c bytes? (not/c immutable?))
  in : input-port?
Like read-bytes!-evt, except that the event reads only as +many bytes as are immediately available, after at least one byte or +one eof becomes available.

procedure

(read-string-evt k in)  evt?

  k : exact-nonnegative-integer?
  in : input-port?
Like read-bytes-evt, but for character strings instead of +byte strings.

procedure

(read-string!-evt str in)  evt?

  str : (and/c string? (not/c immutable?))
  in : input-port?
Like read-bytes!-evt, but for a character string instead of +a byte string.

procedure

(read-line-evt in [mode])  evt?

  in : input-port?
  mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'linefeed
Returns a synchronizable event that is ready when a line of +characters or end-of-file can be read from in. The +meaning of mode is the same as for read-line. The +event result is the read line of characters (not including the line +separator).

A line is read from the port if and only if the event is chosen in a +synchronization, and the returned line always represents contiguous +bytes in the port’s stream.

Exceptions attempting to read from in are handled in the same +way as by eof-evt.

procedure

(read-bytes-line-evt in [mode])  evt?

  in : input-port?
  mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'linefeed
Like read-line-evt, but returns a byte string instead of a +string.

procedure

(peek-bytes-evt k skip progress-evt in)  evt?

  k : exact-nonnegative-integer?
  skip : exact-nonnegative-integer?
  progress-evt : (or/c progress-evt? #f)
  in : input-port?
(peek-bytes!-evt bstr skip progress-evt in)  evt?
  bstr : (and/c bytes? (not/c immutable?))
  skip : exact-nonnegative-integer?
  progress-evt : (or/c progress-evt? #f)
  in : input-port?
(peek-bytes-avail!-evt bstr    
  skip    
  progress-evt    
  in)  evt?
  bstr : (and/c bytes? (not/c immutable?))
  skip : exact-nonnegative-integer?
  progress-evt : (or/c progress-evt? #f)
  in : input-port?
(peek-string-evt k skip progress-evt in)  evt?
  k : exact-nonnegative-integer?
  skip : exact-nonnegative-integer?
  progress-evt : (or/c progress-evt? #f)
  in : input-port?
(peek-string!-evt str skip progress-evt in)  evt?
  str : (and/c string? (not/c immutable?))
  skip : exact-nonnegative-integer?
  progress-evt : (or/c progress-evt? #f)
  in : input-port?
Like the read-bytes-evt, etc., functions, but for peeking. The +skip argument indicates the number of bytes to skip, and +progress-evt indicates an event that effectively cancels the peek +(so that the event never becomes ready). The progress-evt +argument can be #f, in which case the event is never +canceled.

procedure

(regexp-match-evt pattern in)  any

  pattern : (or/c string? bytes? regexp? byte-regexp?)
  in : input-port?
Returns a synchronizable event that is ready when +pattern matches the stream of bytes/characters from +in; see also regexp-match. The event’s value is the +result of the match, in the same form as the result of +regexp-match.

If pattern does not require a start-of-stream match, then +bytes skipped to complete the match are read and discarded when the +event is chosen in a synchronization.

Bytes are read from the port if and only if the event is chosen in a +synchronization, and the returned match always represents contiguous +bytes in the port’s stream. If not-yet-available bytes from the port +might contribute to the match, the event is not ready. Similarly, if +pattern begins with a start-of-stream ^ and the +pattern does not initially match, then the event cannot +become ready until bytes have been read from the port.

The event can be synchronized multiple times—even concurrently—and +each synchronization corresponds to a distinct match request.

The in port must support progress events. If in +returns a special non-byte value during the match attempt, it is +treated like eof.

Exceptions attempting to read from in are handled in the same +way as by eof-evt.

13.1.10.4 Copying Streams

procedure

(convert-stream from-encoding    
  in    
  to-encoding    
  out)  void?
  from-encoding : string?
  in : input-port?
  to-encoding : string?
  out : output-port?
Reads data from in, converts it using +(bytes-open-converter from-encoding to-encoding) and writes the converted bytes to +out. The convert-stream procedure returns after +reaching eof in in.

If opening the converter fails, the exn:fail exception is raised. Similarly, if +a conversion error occurs at any point while reading from in, then +exn:fail exception is raised.

procedure

(copy-port in out ...+)  void?

  in : input-port?
  out : output-port?
Reads data from in and writes it back out to out, +returning when in produces eof. The copy is +efficient, and it is without significant buffer delays (i.e., a byte +that becomes available on in is immediately transferred to +out, even if future reads on in must block). If +in produces a special non-byte value, it is transferred to +out using write-special.

This function is often called from a “background” thread to +continuously pump data from one stream to another.

If multiple outs are provided, data from in is +written to every out. The different outs block +output to each other, because each block of data read from in +is written completely to one out before moving to the next +out. The outs are written in the provided order, so +non-blocking ports (e.g., file output ports) should be placed first in the +argument list.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/port-ops.html b/clones/docs.racket-lang.org/reference/port-ops.html new file mode 100644 index 00000000..4eab9524 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/port-ops.html @@ -0,0 +1,34 @@ + +13.1.2 Managing Ports
13.1.2 Managing Ports

procedure

(input-port? v)  boolean?

  v : any/c
Returns #t if v is an input port, #f otherwise.

procedure

(output-port? v)  boolean?

  v : any/c
Returns #t if v is an output port, #f otherwise.

procedure

(port? v)  boolean?

  v : any/c
Returns #t if either (input-port? v) or +(output-port? v) is #t, #f otherwise.

procedure

(close-input-port in)  void?

  in : input-port?
Closes the input port in. For some kinds of ports, closing +the port releases lower-level resources, such as a file handle. If +the port is already closed, close-input-port has no effect.

procedure

(close-output-port out)  void?

  out : output-port?
Closes the output port out. For some kinds of ports, closing +the port releases lower-level resources, such as a file handle. Also, +if the port is buffered, closing may first flush the port before +closing it, and this flushing process can block. If the port is +already closed, close-output-port has no effect.

procedure

(port-closed? port)  boolean?

  port : port?
Returns #t if the input or output port port is +closed, #f otherwise.

procedure

(port-closed-evt port)  evt?

  port : port?
Return a synchronizable event that becomes ready for +synchronization when port is +closed. The synchronization result of a port-closed event is the port-closed event itself.

parameter

(current-input-port)  input-port?

(current-input-port in)  void?
  in : input-port?
A parameter that +determines a default input port for many operations, such as +read.

A parameter that +determines a default output port for many operations, such as +write.

parameter

(current-error-port)  output-port?

(current-error-port out)  void?
  out : output-port?
A parameter that +determines an output port that is typically used for errors and +logging. For example, the default error display handler writes to this +port.

procedure

(file-stream-port? v)  boolean?

  v : any/c
Returns #t if v is a file-stream port (see +File Ports), #f otherwise.

Changed in version 7.2.0.5 of package base: Extended file-stream-port? +to any value, instead of resticting +the domain to ports

procedure

(terminal-port? v)  boolean?

  v : any/c
Returns #t if v is a port that is attached to an +interactive terminal, #f otherwise.

Changed in version 7.2.0.5 of package base: Extended terminal-port? +to any value, instead of resticting +the domain to ports

procedure

(port-waiting-peer? port)  boolean?

  port : port?
Returns #t if port is not ready for reading or +writing because it is waiting for a peer process to complete a stream +construction, #f otherwise.

On Unix and Mac OS, opening a fifo for output creates a peer-waiting +port if no reader for the same fifo is already opened. In that case, +the output port is not ready for writing until a reader is opened; +that is, write opertaions will block. Use sync if necessary +to wait until writing will not block—that is, until the read end of +the fifo is opened.

Added in version 7.4.0.5 of package base.

value

eof : eof-object?

A value (distinct from all other values) +that represents an end-of-file.

procedure

(eof-object? v)  boolean?

  v : any/c
Returns #t if +v is eof, #f otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/ports.html b/clones/docs.racket-lang.org/reference/ports.html new file mode 100644 index 00000000..f5bf80bc --- /dev/null +++ b/clones/docs.racket-lang.org/reference/ports.html @@ -0,0 +1,40 @@ + +13.1 Ports

13.1 Ports

Ports produce and/or consume bytes. An input port +produces bytes, while an output port consumes bytes (and +some ports are both input ports and output ports). When an input port +is provided to a character-based operation, the bytes are decoded to a +character, and character-based output operations similarly encode the +character to bytes; see Encodings and Locales. In addition to bytes and +characters encoded as bytes, some ports can produce and/or consume +arbitrary values as special results.

When a port corresponds to a file, network connection, or some other +system resource, it must be explicitly closed via +close-input-port or close-output-port (or indirectly +via custodian-shutdown-all) to release low-level resources +associated with the port. For any kind of port, after it is closed, +attempting to read from or write to the port raises exn:fail.

Data produced by a input port can be read or peeked. When data is read, it is considered consumed and +removed from the port’s stream. When data is peeked, it remains +in the port’s stream to be returned again by the next read or +peek. Previously peeked data can be committed, which causes the data to be removed from the +port as for a read in a way that can be synchronized with other +attempts to peek or read through a synchronizable +event. Both read and peek operations are normally blocking, in +the sense that the read or peek operation does not complete +until data is available from the port; non-blocking variants of read +and peek operations are also available.

The global variable eof is bound to the end-of-file value, +and eof-object? returns #t only when applied to this +value. Reading from a port produces an end-of-file result when the +port has no more data, but some ports may also return end-of-file +mid-stream. For example, a port connected to a Unix terminal returns +an end-of-file when the user types control-D; if the user provides +more input, the port returns additional bytes after the end-of-file.

Every port has a name, as reported by object-name. The name +can be any value, and it is used mostly for error-reporting +purposes. The read-syntax procedure uses the name of an input +port as the default source location for the syntax objects that +it produces.

A port can be used as a synchronizable event. An input port is +ready for synchronization when read-byte would not +block, and an output port is ready for synchronization when +write-bytes-avail would not block or when the port contains +buffered characters and write-bytes-avail* can flush part of +the buffer (although write-bytes-avail might block). A value +that can act as both an input port and an output port acts as an input +port for a synchronizable event. The synchronization result of a port is the port itself.

    13.1.1 Encodings and Locales

    13.1.2 Managing Ports

    13.1.3 Port Buffers and Positions

    13.1.4 Counting Positions, Lines, and Columns

    13.1.5 File Ports

    13.1.6 String Ports

    13.1.7 Pipes

    13.1.8 Structures as Ports

    13.1.9 Custom Ports

    13.1.10 More Port Constructors, Procedures, and Events

      13.1.10.1 Port String and List Conversions

      13.1.10.2 Creating Ports

      13.1.10.3 Port Events

      13.1.10.4 Copying Streams

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/portstructs.html b/clones/docs.racket-lang.org/reference/portstructs.html new file mode 100644 index 00000000..824712c0 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/portstructs.html @@ -0,0 +1,16 @@ + +13.1.8 Structures as Ports
13.1.8 Structures as Ports

The prop:input-port and prop:output-port structure type +properties identify structure types whose instances can serve as input +and output ports, respectively.

Each property value can be either of the following:

  • An input port (for prop:input-port) or output port +(for prop:output-port): In this case, using the structure +as port is equivalent to using the given input or output port.

  • An exact, non-negative integer between 0 (inclusive) and +the number of non-automatic fields in the structure type (exclusive, not +counting supertype fields): The integer identifies a field in +the structure, and the field must be designated as immutable. If the +field contains an input port (for prop:input-port) or +output port (for prop:output-port), the port is used. +Otherwise, an empty string input port is used for prop:input-port, +and a port that discards all data is used for prop:output-port.

Some procedures, such as file-position, work on both input +and output ports. When given an instance of a structure type with both +the prop:input-port and prop:output-port properties, +the instance is used as an input port.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/pretty-print.html b/clones/docs.racket-lang.org/reference/pretty-print.html new file mode 100644 index 00000000..07a660ad --- /dev/null +++ b/clones/docs.racket-lang.org/reference/pretty-print.html @@ -0,0 +1,173 @@ + +13.6 Pretty Printing

13.6 Pretty Printing

 (require racket/pretty) package: base
The bindings documented in this section are provided by the racket/pretty and racket libraries, but not racket/base.

procedure

(pretty-print v    
  [port    
  quote-depth    
  #:newline? newline?])  void?
  v : any/c
  port : output-port? = (current-output-port)
  quote-depth : (or/c 0 1) = 0
  newline? : boolean? = #t
Pretty-prints the value v using the same printed form as the +default print mode, but with newlines and whitespace inserted +to avoid lines longer than (pretty-print-columns), as +controlled by (pretty-print-current-style-table). The printed +form ends in a newline by default, unless the newline? +argument is supplied with false or the pretty-print-columns +parameter is set to 'infinity. When port has line +counting enabled (see Counting Positions, Lines, and Columns), then printing is sensitive +to the column when printing starts—both for determining an initial +line break and indenting subsequent lines.

In addition to the parameters defined in this section, +pretty-print conforms to the print-graph, +print-struct, print-hash-table, +print-vector-length, print-box, and +print-as-expression parameters.

The pretty printer detects structures that have the +prop:custom-write property and calls the corresponding +custom-write procedure. The custom-write procedure can check the +parameter pretty-printing to cooperate with the +pretty-printer. Recursive printing to the port automatically uses +pretty printing, but if the structure has multiple recursively printed +sub-expressions, a custom-write procedure may need to cooperate more +to insert explicit newlines. Use port-next-location to +determine the current output column, use pretty-print-columns +to determine the target printing width, and use +pretty-print-newline to insert a newline (so that the +function in the pretty-print-print-line parameter can be +called appropriately). Use +make-tentative-pretty-print-output-port to obtain a port for +tentative recursive prints (e.g., to check the length of the output).

If the newline? argument is omitted or supplied with true, +the pretty-print-print-line callback is called with false as +the first argument to print the last newline after the printed value. +If it is supplied with false, the pretty-print-print-line +callback is not called after the printed value.

Changed in version 6.6.0.3 of package base: Added newline? argument.

procedure

(pretty-write v [port #:newline? newline?])  void?

  v : any/c
  port : output-port? = (current-output-port)
  newline? : boolean? = #t
Same as pretty-print, but v is printed like +write instead of like print.

Changed in version 6.6.0.3 of package base: Added newline? argument.

procedure

(pretty-display v [port #:newline? newline?])  void?

  v : any/c
  port : output-port? = (current-output-port)
  newline? : boolean? = #t
Same as pretty-print, but v is printed like +display instead of like print.

Changed in version 6.6.0.3 of package base: Added newline? argument.

procedure

(pretty-format v [columns #:mode mode])  string?

  v : any/c
  columns : exact-nonnegative-integer? = (pretty-print-columns)
  mode : (or/c 'print 'write 'display) = 'print
Like pretty-print, except that it returns a string containing +the pretty-printed value, rather than sending the output to a port.

The optional argument columns argument is used to +parameterize pretty-print-columns.

The keyword argument mode controls whether printing is done like +either pretty-print (the default), pretty-write or +pretty-display.

Changed in version 6.3 of package base: Added a mode argument.

procedure

(pretty-print-handler v)  void?

  v : any/c
Pretty-prints v if v is not #<void>, or prints +nothing if v is #<void>. Pass this procedure to +current-print to install the pretty printer into the REPL run +by read-eval-print-loop.

13.6.1 Basic Pretty-Print Options

parameter

(pretty-print-columns)

  (or/c exact-positive-integer? 'infinity)
(pretty-print-columns width)  void?
  width : (or/c exact-positive-integer? 'infinity)
A parameter that determines the default width for pretty printing.

If the display width is 'infinity, then pretty-printed output +is never broken into lines, and a newline is not added to the end of +the output.

Parameter that controls the default depth for recursive pretty +printing. Printing to depth means that elements nested more +deeply than depth are replaced with “...”; in particular, a +depth of 0 indicates that only simple values are printed. A depth of +#f (the default) allows printing to arbitrary +depths.

parameter

(pretty-print-exact-as-decimal)  boolean?

(pretty-print-exact-as-decimal as-decimal?)  void?
  as-decimal? : any/c
A parameter that determines how exact non-integers are printed. If +the parameter’s value is #t, then an exact non-integer with a +decimal representation is printed as a decimal number instead of a +fraction. The initial value is #f.

A parameter that controls the printing of the symbol whose print name +is just a period. If set to a true value, then such a symbol is +printed as only the period. If set to a false value, it is printed as +a period with vertical bars surrounding it.

A parameter that determines how inexact numbers are printed. If the +parameter’s value is #t, then inexact numbers are always +printed with a leading #i. The initial value is #f.

13.6.2 Per-Symbol Special Printing

A parameter that controls whether or not quote, +unquote, unquote-splicing, etc., are +abbreviated with ', ,, ,@, etc. +By default, the abbreviations are enabled.

See also pretty-print-remap-stylable.

procedure

(pretty-print-style-table? v)  boolean?

  v : any/c
Returns #t if v is a style table for use with +pretty-print-current-style-table, #f otherwise.

A parameter that holds a table of style mappings. See +pretty-print-extend-style-table.

procedure

(pretty-print-extend-style-table style-table 
  symbol-list 
  like-symbol-list) 
  pretty-print-style-table?
  style-table : pretty-print-style-table?
  symbol-list : (listof symbol?)
  like-symbol-list : (listof symbol?)
Creates a new style table by extending an existing +style-table, so that the style mapping for each symbol of +like-symbol-list in the original table is used for the +corresponding symbol of symbol-list in the new table. The +symbol-list and like-symbol-list lists must have the +same length. The style-table argument can be #f, in +which case the default mappings are used from the original table (see +below).

The style mapping for a symbol controls the way that whitespace is +inserted when printing a list that starts with the symbol. In the +absence of any mapping, when a list is broken across multiple lines, +each element of the list is printed on its own line, each with the +same indentation.

The default style mapping includes mappings for the following symbols, +so that the output follows popular code-formatting rules:

'lambda 'λ 'case-lambda
'define 'define-macro 'define-syntax
'let 'letrec 'let*
'let-syntax 'letrec-syntax
'let-values 'letrec-values 'let*-values
'let-syntaxes 'letrec-syntaxes
'begin 'begin0 'do
'if 'set! 'set!-values
'unless 'when
'cond 'case 'and 'or
'module
'syntax-rules 'syntax-case 'letrec-syntaxes+values
'import 'export 'link
'require 'require-for-syntax 'require-for-template 'provide
'public 'private 'override 'rename 'inherit 'field 'init
'shared 'send 'class 'instantiate 'make-object

parameter

(pretty-print-remap-stylable)

  (any/c . -> . (or/c symbol? #f))
(pretty-print-remap-stylable proc)  void?
  proc : (any/c . -> . (or/c symbol? #f))
A parameter that controls remapping for styles and for the determination of +the reader shorthands.

This procedure is +called with each sub-expression that appears as the first element in a +sequence. If it returns a symbol, the style table is used, as if that +symbol were at the head of the sequence. If it returns #f, +the style table is treated normally. +Similarly, when determining whether to abbreviate reader macros, +this parameter is consulted.

13.6.3 Line-Output Hook

procedure

(pretty-print-newline port width)  void?

  port : output-port?
  width : exact-nonnegative-integer?
Calls the procedure associated with the +pretty-print-print-line parameter to print a newline to +port, if port is the output port that is redirected +to the original output port for printing, otherwise a plain newline is +printed to port. The width argument should be the +target column width, typically obtained from +pretty-print-columns.

A parameter that determines a procedure for printing the newline +separator between lines of a pretty-printed value. The procedure is +called with four arguments: a new line number, an output port, the old +line’s length, and the number of destination columns. The return value +from proc is the number of extra characters it printed at the +beginning of the new line.

The proc procedure is called before any characters are +printed with 0 as the line number and 0 as the old +line length. Whenever the pretty-printer starts a new line, +proc is called with the new line’s number (where the first +new line is numbered 1) and the just-finished line’s length. +The destination-columns argument to proc is always +the total width of the destination printing area, or +'infinity if pretty-printed values are not broken into lines.

If the #:newline? argument was omitted or supplied with +a true value, proc is also called after the last character of the +value has been printed, with #f as the line number and with +the length of the last line.

The default proc procedure prints a newline whenever the line +number is not 0 and the column count is not +'infinity, always returning 0. A custom +proc procedure can be used to print extra text before each +line of pretty-printed output; the number of characters printed before +each line should be returned by proc so that the next line +break can be chosen correctly.

The destination port supplied to proc is generally not the +port supplied to pretty-print or pretty-display (or +the current output port), but output to this port is ultimately +redirected to the port supplied to pretty-print or +pretty-display.

13.6.4 Value Output Hook

A parameter that determines a sizing hook for pretty-printing.

The sizing hook is applied to each value to be printed. If the hook +returns #f, then printing is handled internally by the +pretty-printer. Otherwise, the value should be an integer specifying +the length of the printed value in characters; the print hook will be +called to actually print the value (see +pretty-print-print-hook).

The sizing hook receives three arguments. The first argument is the +value to print. The second argument is a boolean: #t for +printing like display and #f for printing like +write. The third argument is the destination port; the port +is the one supplied to pretty-print or +pretty-display (or the current output port). The sizing hook +may be applied to a single value multiple times during +pretty-printing.

A parameter that determines a print hook for pretty-printing. The +print-hook procedure is applied to a value for printing when the +sizing hook (see pretty-print-size-hook) returns an integer +size for the value.

The print hook receives three arguments. The first argument is the +value to print. The second argument is a boolean: #t for +printing like display and #f for printing like +write. The third argument is the destination port; this port +is generally not the port supplied to pretty-print or +pretty-display (or the current output port), but output to +this port is ultimately redirected to the port supplied to +pretty-print or pretty-display.

parameter

(pretty-print-pre-print-hook)

  (any/c output-port? . -> . void)
(pretty-print-pre-print-hook proc)  void?
  proc : (any/c output-port? . -> . void)
A parameter that determines a hook procedure to be called just before +an object is printed. The hook receives two arguments: the object and +the output port. The port is the one supplied to pretty-print +or pretty-display (or the current output port).

A parameter that determines a hook procedure to be called just after +an object is printed. The hook receives two arguments: the object and +the output port. The port is the one supplied to pretty-print +or pretty-display (or the current output port).

13.6.5 Additional Custom-Output Support

parameter

(pretty-printing)  boolean?

(pretty-printing on?)  void?
  on? : any/c
A parameter that is set to #t when the pretty printer calls a +custom-write procedure (see prop:custom-write) for output in +a mode that supports line breaks. When pretty printer calls a +custom-write procedure merely to detect cycles or to try to print on a +single line, it sets this parameter to #f.

procedure

(make-tentative-pretty-print-output-port out 
  width 
  overflow-thunk) 
  output-port?
  out : output-port?
  width : exact-nonnegative-integer?
  overflow-thunk : (-> any)
Produces an output port that is suitable for recursive pretty printing +without actually producing output. Use such a port to tentatively +print when proper output depends on the size of recursive +prints. After printing, determine the size of the tentative output +using file-position.

The out argument should be a pretty-printing port, such as +the one supplied to a custom-write procedure when +pretty-printing is set to true, or another tentative output +port. The width argument should be a target column width, +usually obtained from pretty-print-columns, possibly +decremented to leave room for a terminator. The +overflow-thunk procedure is called if more than +width items are printed to the port or if a newline is +printed to the port via pretty-print-newline; it can escape from the +recursive print through a continuation as a shortcut, but +overflow-thunk can also return, in which case it is called +every time afterward that additional output is written to the port.

After tentative printing, either accept the result with +tentative-pretty-print-port-transfer or reject it with +tentative-pretty-print-port-cancel. Failure to accept or +cancel properly interferes with graph-structure printing, calls to +hook procedures, etc. Explicitly cancel the tentative print even when +overflow-thunk escapes from a recursive print.

procedure

(tentative-pretty-print-port-transfer tentative-out    
  orig-out)  void?
  tentative-out : output-port?
  orig-out : output-port?
Causes the data written to tentative-out to be transferred as +if written to orig-out. The tentative-out argument +should be a port produced by +make-tentative-pretty-print-output-port, and +orig-out should be either a pretty-printing port (provided to +a custom-write procedure) or another tentative output port.

procedure

(tentative-pretty-print-port-cancel tentative-out)  void?

  tentative-out : output-port?
Cancels the content of tentative-out, which was produced by +make-tentative-pretty-print-output-port. The main effect of +canceling is that graph-reference definitions are undone, so that a +future print of a graph-referenced object includes the defining +#n=.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/printing.html b/clones/docs.racket-lang.org/reference/printing.html new file mode 100644 index 00000000..e461e4da --- /dev/null +++ b/clones/docs.racket-lang.org/reference/printing.html @@ -0,0 +1,425 @@ + +1.4 The Printer

1.4 The Printer

The Racket printer supports three modes:

  • write mode prints core datatypes in such a way that +using read on the output produces a value that is +equal? to the printed value;

  • display mode prints core datatypes in a more +“end-user” style rather than “programmer” style; for +example, a string displays as its content characters +without surrounding "s or escapes;

  • print mode by default—when +print-as-expression is #tprints most +datatypes in such a way that evaluating the output as an +expression produces a value that is equal? to the +printed value; when print-as-expression is set to +#f, then print mode is like write +mode.

In print mode when print-as-expression is +#t (as is the default), a value prints at a quoting +depth of either 0 (unquoted) or 1 (quoted). The +initial quoting depth is accepted as an optional argument by +print, and printing of some compound datatypes adjusts the +print depth for component values. For example, when a list is printed +at quoting depth 0 and all of its elements are +quotable, the list is printed with a ' prefix, and +the list’s elements are printed at quoting depth 1.

When the print-graph parameter is set to #t, then +the printer first scans an object to detect cycles. The scan traverses +the components of pairs, mutable pairs, vectors, boxes (when +print-box is #t), hash tables (when +print-hash-table is #t and when key are held strongly), fields of structures +exposed by struct->vector (when print-struct is +#t), and fields of structures exposed by printing when the +structure’s type has the prop:custom-write property. If +print-graph is #t, then this information is used to +print sharing through graph definitions and references (see +Reading Graph Structure). If a cycle is detected in the initial scan, +then print-graph is effectively set to #t +automatically.

With the exception of displaying byte strings, printing is defined in +terms of Unicode characters; see Ports for information +on how a character stream is written to a port’s underlying byte +stream.

1.4.1 Printing Symbols

Symbols containing spaces or special characters write using +escaping \ and quoting |s. When the +read-case-sensitive parameter is set to #f, then +symbols containing uppercase characters also use escaping +\ and quoting |s. In addition, symbols are +quoted with |s or leading \ when they would +otherwise print the same as a numerical constant or as a delimited +. (when read-accept-dot is #t).

When read-accept-bar-quote is #t, |s are +used in printing when one | at the beginning and one +| at the end suffice to correctly print the +symbol. Otherwise, \s are always used to escape special +characters, instead of quoting them with |s.

When read-accept-bar-quote is #f, then | +is not treated as a special character. The following are always +special characters:

   ( ) [ ] +{ } +" , ' ` +; \

In addition, # is a special character when it appears at the +beginning of the symbol, and when it is not followed by %.

Symbols display without escaping or quoting special +characters. That is, the display form of a symbol is the same as the +display form of symbol->string applied to the symbol.

Symbols print the same as they write, unless +print-as-expression is set to #t (as is the default) and the current +quoting depth is 0. In that case, the symbol’s +printed form is prefixed with '. For the purposes +of printing enclosing datatypes, a symbol is quotable.

1.4.2 Printing Numbers

A number prints the same way in write, display, and +print modes. For the purposes of printing enclosing +datatypes, a number is quotable.

A complex number that is not a real number always prints +as m+ni or +m-ni, where m and +n (for a non-negative imaginary part) or +-n (for a negative imaginary part) are the printed +forms of its real and imaginary parts, respectively.

An exact 0 prints as 0. A positive, exact +integer prints as a sequence of digits that does not start with +0. A positive, exact, real, non-integer number prints as +m/n, where m and n +are the printed forms of the number’s numerator and denominator (as +determined by numerator and denominator). A negative +exact number prints with a - prefix on the printed +form of the number’s exact negation. When printing a number as +hexadecimal (e.g., via number->string), digits a +though f are printed in lowercase. A #e or radix +marker such as #d does not prefix the number.

A double-precision inexact number (i.e., a flonum) that +is a rational number prints with either a . decimal +point, an e exponent marker and non-zero exponent, or both. +The form is selected to keep the output short, with +the constraint that reading the printed form back in produces an +equal? number. A #i does not prefix the +number, and # is never used in place of a digit. A ++ does not prefix a positive number, but a + or +- is printed before the exponent if e is present. +Positive infinity prints as +inf.0, negative infinity prints +as -inf.0, and not-a-number prints as +nan.0.

A single-precision inexact number that is a rational +number prints like a double-precision number, but always with an +exponent, using f in place of e to indicate the +number’s precision; if the number would otherwise print without an +exponent, 0 (with no +) is printed as the exponent +part. Single-precision positive infinity prints as ++inf.f, negative infinity prints as -inf.f, and +not-a-number prints as +nan.f.

1.4.3 Printing Extflonums

An extflonum prints the same way in write, +display, and print modes. For the purposes of +printing enclosing datatypes, an extflonum is quotable.

An extflonum prints in the same way a single-precision inexact number +(see Printing Numbers), but always with a t or +T exponent marker or as a suffix for +inf.t, -inf.t, +or +nan.t. When +extflonum operations are supported, printing always uses lowercase +t; when extflonum operations are not supported, an +extflonum prints the same as its reader (see The Reader) +source, since reading is the only way to produce an extflonum.

1.4.4 Printing Booleans

The boolean constant #t prints as #true or #t in +all modes (display, write, and print), +depending on the value of print-boolean-long-form, and the +constant #f prints as #false or #f. For +the purposes of printing enclosing datatypes, a symbol is +quotable.

1.4.5 Printing Pairs and Lists

In write and display modes, an empty list prints as +(). A pair normally prints starting with ( +followed by the printed form of its car. The rest of the +printed form depends on the cdr:

  • If the cdr is a pair or the empty list, then the +printed form of the pair completes with the printed form of the +cdr, except that the leading ( in the +cdr’s printed form is omitted.

  • Otherwise, the printed for of the pair continues with a space, +., another space, the printed form of the +cdr, and a ).

If print-reader-abbreviations is set to #t, then +pair printing in write mode is adjusted in the case of a pair +that starts a two-element list whose first element is 'quote, +'quasiquote, 'unquote, 'unquote-splicing, +'syntax, 'quasisyntax, 'unsyntax, or +'unsyntax-splicing. In that case, the pair is printed with +the corresponding reader syntax: ', `, +,, ,@, #', #`, #,, +or #,@, respectively. After the reader syntax, the second +element of the list is printed. When the list is a tail of an +enclosing list, the tail is printed after a . in the +enclosing list (after which the reader abbreviations work), instead of +including the tail as two elements of the enclosing list. If the +reader syntax , or #, is followed by a symbol +that prints with a leading @, then the printer adds an +extra space before the @.

The printed form of a pair is the same in both write and +display modes, except as the printed form of the pair’s +car and cdr vary with the mode. The print +form is also the same if print-as-expression is #f +or the quoting depth is 1.

For print mode when print-as-expression is +#t and the quoting depth is 0, then the empty +list prints as '(). For a pair whose car and +cdr are quotable, the pair prints in write +mode but with a ' prefix; the pair’s content is printed with +quoting depth 1. Otherwise, when the car or +cdr is not quotable, then pair prints with either +cons (when the cdr is not a pair), list +(when the pair is a list), or list* (otherwise) after the +opening (, any . that would otherwise be printed +is suppressed, and the pair content is printed at quoting depth +0. In all cases, when print-as-expression is +#t for print mode, then the value of +print-reader-abbreviations is ignored and reader +abbreviations are always used for lists printed at quoting +depth 1.

By default, mutable pairs (as created with mcons) print the +same as pairs for write and display, except that +{ and } are used instead of ( and +). Note that the reader treats {...} +and (...) equivalently on input, creating +immutable pairs in both cases. Mutable pairs in print mode with +print-as-expression as #f or a quoting depth +of 1 also use { and }. In +print mode with print-as-expression as #t +and a quoting depth of 0, a mutable pair prints as +(mcons , the mcar and mcdr printed at +quoting depth 0 and separated by a space, and a +closing ).

If the print-pair-curly-braces parameter is set to +#t, then pairs print using { and } +when not using print mode with print-as-expression as +#t and a quoting depth of 0. If the +print-mpair-curly-braces parameter is set to #f, +then mutable pairs print using ( and ) in that +mode.

For the purposes of printing enclosing datatypes, an empty list is +always quotable, a pair is quotable when its +car and cdr are quotable, and a mutable list +is never quotable.

Changed in version 6.9.0.6 of package base: Added a space when printing , +or #, followed by a symbol +that prints with a leading @.

1.4.6 Printing Strings

All strings display as their literal character sequences.

The write or print form of a string starts with " and ends +with another ". Between the "s, each character is +represented. Each graphic or blank character is represented as itself, +with two exceptions: " is printed as \", and +\ is printed as \\. Each non-graphic, non-blank +character (according to char-graphic? and +char-blank?) is printed using the escape sequences described +in Reading Strings, using \a, \b, +\t, \n, \v, \f, \r, +or \e if possible, otherwise using \u with four +hexadecimal digits or \U with eight hexadecimal digits +(using the latter only if the character value does not fit into four +digits).

All byte strings display as their literal byte sequence; this +byte sequence may not be a valid UTF-8 encoding, so it may not +correspond to a sequence of characters.

The write or print form of a byte string starts with #" and +ends with a ". Between the "s, each byte is +written using the corresponding ASCII decoding if the byte is between +0 and 127 and the character is graphic or blank (according to +char-graphic? and char-blank?). Otherwise, the byte +is written using \a, \b, \t, +\n, \v, \f, \r, or +\e if possible, otherwise using \ followed by one +to three octal digits (only as many as necessary).

For the purposes of printing enclosing datatypes, a string or a byte +string is quotable.

1.4.7 Printing Vectors

In display mode, the printed form of a vector is # +followed by the printed form of vector->list applied to the +vector. In write mode, the printed form is the same, except +that when the print-vector-length parameter is #t, a +decimal integer is printed after the #, and a repeated last +element is printed only once.

Vectors print the same as they write, unless +print-as-expression is set to #t and the current +quoting depth is 0. In that case, if all of the +vector’s elements are quotable, then the vector’s +printed form is prefixed with ' and its elements +printed with quoting depth 1. If its elements are not +all quotable, then the vector prints as +(vector , the elements at quoting depth 0, +and a closing ). A vector is quotable when all of +its elements are quotable.

In write or display mode, a flvector prints +like a vector, but with a #fl prefix instead of +#. A fxvector similarly prints with a #fx +prefix instead of #. The print-vector-length +parameter affects flvector and fxvector printing the +same as vector printing. In print mode, +flvectors and fxvectors are not quotable, and +they print like a vector at quoting depth 0 using a +(flvector  or (fxvector  prefix, respectively.

1.4.8 Printing Structures

When the print-struct parameter is set to #t, then +the way that structures print depends on details of the structure type +for which the structure is an instance:

  • If the structure type is a prefab structure type, +then it prints in write or display mode using +#s( followed by the prefab structure type key, +then the printed form of each field in the structure, and then +).

    In print mode when print-as-expression is set +to #t and the current quoting depth is +0, if the structure’s content is all quotable, +then the structure’s printed form is prefixed with +' and its content is printed with quoting +depth 1. If any of its content is not quotable, then +the structure type prints the same as a non-prefab +structure type.

    An instance of a prefab structure type is quotable +when all of its content is quotable.

  • If the structure has a prop:custom-write property +value, then the associated procedure is used to print the +structure, unless the print-unreadable parameter is +set to #f.

    For print mode, an instance of a structure type with a +prop:custom-write property is treated as +quotable if it has the +prop:custom-print-quotable property with a value of +'always. If it has 'maybe as the property +value, then the structure is treated as quotable if its +content is quotable, where the content is determined by +the values recursively printed by the structure’s +prop:custom-write procedure. Finally, if the structure +has 'self as the property value, then it is treated as +quotable.

    In print mode when print-as-expression is +#t, the structure’s prop:custom-write +procedure is called with either 0 or 1 as the +quoting depth, normally depending on the structure’s +prop:custom-print-quotable property value. If the +property value is 'always, the quoting depth is +normally 1. If the property value is 'maybe, +then the quoting depth is 1 if the structure is +quotable, or normally 0 otherwise. If the +property value is 'self, then the quoting depth may be +0 or 1; it is normally 0 if the +structure is not printed as a part of an enclosing +quotable value, even though the structure is treated as +quotable. Finally, if the property value is +'never, then the quoting depth is normally +0. The quoting depth can vary from its normal +value if the structure is printed with an explicit quoting +depth of 1.

  • If the structure’s type is transparent or if any ancestor is +transparent (i.e., struct? on the instance produces +#t), then the structure prints as the vector produced +by struct->vector in display mode, in +write mode, or in print mode when +print-as-expression is set to #f or when the +quoting depth is 0.

    In print mode with print-as-expression as +#t and a quoting depth of 0, the +structure content is printed with a ( followed by +the structure’s type name (as determined by +object-name) in write mode; the remaining +elements are printed at quoting depth +0 and separated by a space, and finally a closing +).

    A transparent structure type that is not a prefab +structure type is never quotable.

  • For any other structure type, the structure prints as an +unreadable value; see Printing Unreadable Values for more +information.

If the print-struct parameter is set to #f, then all +structures without a prop:custom-write property print as +unreadable values (see Printing Unreadable Values) and count as +quotable.

1.4.9 Printing Hash Tables

When the print-hash-table parameter is set to #t, in +write and display modes, a hash table prints +starting with #hash(, #hasheqv(, or +#hasheq( for a table using equal?, eqv?, +or eq? key comparisons, respectively, as long as the hash table +retains keys strongly. After the prefix, each +key–value mapping is shown as (, the printed form of a key, +a space, ., a space, the printed form the corresponding +value, and ), with an additional space if the key–value +pair is not the last to be printed. After all key–value pairs, the +printed form completes with ).

In print mode when print-as-expression is +#f or the quoting depth is 1, the printed form +is the same as for write. Otherwise, if the hash table’s keys +and values are all quotable, the table prints with a +' prefix, and the table’s key and values are printed +at quoting depth 1. If some key or value is not +quotable, the hash table prints as (hash , +(hasheqv , or (hasheq  followed by alternating +keys and values printed at quoting depth 1 and +separated by spaces, and finally a closing ). A hash table +is quotable when all of its keys and values are +quotable.

When the print-hash-table parameter is set to #f +or when a hash table retains its keys weakly, a +hash table prints as #<hash> and counts as quotable.

1.4.10 Printing Boxes

When the print-box parameter is set to #t, a box +prints as #& followed by the printed form of its content in +write, display, or print mode when +print-as-expression is #f or the quoting +depth is 1.

In print mode when print-as-expression is +#t and the quoting depth is 0, a box prints +with a ' prefix and its value is printed at quoting +depth 1 when its content is quotable, otherwise the +box prints a (box  followed by the content at +quoting depth 0 and a closing ). A box is +quotable when its content is quotable.

When the print-box parameter is set to #f, a box +prints as #<box> and counts as quotable.

1.4.11 Printing Characters

Characters with the special names described in +Reading Characters write and print using the +same name. (Some characters have multiple names; the +#\newline and #\nul names are used instead of +#\linefeed and #\null.) Other graphic characters +(according to char-graphic?) write as #\ +followed by the single character, and all others characters are +written in #\u notation with four digits or #\U +notation with eight digits (using the latter only if the character +value does not fit in four digits).

All characters display directly as themselves (i.e., a single +character).

For the purposes of printing enclosing datatypes, a character is +quotable.

1.4.12 Printing Keywords

Keywords write, print, and display the same +as symbols (see Printing Symbols) except with a leading +#: (after any ' prefix added in print +mode), and without special handling for an initial # or when +the printed form would match a number or a delimited . +(since #: distinguishes the keyword).

For the purposes of printing enclosing datatypes, a keyword is +quotable.

1.4.13 Printing Regular Expressions

Regexp values write, display, and print +starting with #px (for pregexp-based regexps) or +#rx (for regexp-based regexps) followed by the +write form of the regexp’s source string or byte string.

For the purposes of printing enclosing datatypes, a regexp value is +quotable.

1.4.14 Printing Paths

Paths write and print as #<path:....>. A +path displays the same as the string produced by +path->string. For the purposes of printing enclosing +datatypes, a path counts as quotable.

Although a path can be converted to a string with +path->string or to a byte string with path->bytes, +neither is clearly the right choice for printing a path and reading it +back. If the path value is meant to be moved among platforms, then a +string is probably the right choice, despite the potential for losing +information when converting a path to a string. For a path that is +intended to be re-read on the same platform, a byte string is probably +the right choice, since it preserves information in an unportable +way. Paths do not print in a readable way so that programmers are not +misled into thinking that either choice is always appropriate.

1.4.15 Printing Unreadable Values

For any value with no other printing specification, assuming that the +print-unreadable parameter is set to #t, the output +form is #<something>, where +something is specific to the type of the value and sometimes +to the value itself. If print-unreadable is set to +#f, then attempting to print an unreadable value raises +exn:fail.

For the purposes of printing enclosing datatypes, a value that prints +unreadably nevertheless counts as quotable.

1.4.16 Printing Compiled Code

Compiled code as produced by compile prints using +#~. Compiled code printed with #~ is essentially +assembly code for Racket, and reading such a form produces a compiled +form when the read-accept-compiled parameter is set to +#t.

Compiled code parsed from #~ is marked as non-runnable if +the current code inspector (see current-code-inspector) is +not the original code inspector; on attempting to evaluate or reoptimize +non-runnable bytecode, exn:fail exception is raised. Otherwise, compiled +code parsed from #~ may contain references to unexported or +protected bindings from a module. Conceptually, the references in +bytecode are associated with the current code inspector, where the +code will only execute if that inspector controls the relevant module +invocation (see Code Inspectors)—but the original code +inspector controls all other inspectors, anyway.

A compiled-form object may contain uninterned symbols (see +Symbols) that were created by gensym or +string->uninterned-symbol. When the compiled object is read +via #~, each uninterned symbol in the original form is +mapped to a new uninterned symbol, where multiple instances of a +single symbol are consistently mapped to the same new symbol. The +original and new symbols have the same printed +representation. Unreadable symbols, which are typically +generated indirectly during expansion and compilation, are saved and +restored consistently through #~.

The dynamic nature of uninterned symbols and their localization +within #~ can cause problems when gensym or +string->uninterned-symbol is used to construct an identifier +for a top-level or module binding (depending on how the identifier and +its references are compiled). To avoid problems, generate distinct +identifiers either with generate-temporaries or by applying +the result of make-syntax-introducer to an existing +identifier; those functions lead to top-level and module variables +with unreadable symbolic names, and the names are deterministic +as long as expansion is otherwise deterministic.

When a compiled-form object has string and byte string literals, they +are interned using datum-intern-literal when the +compiled-object for is read back in. Numbers and other values that +read-syntax would intern, however, are not interned when read +back as quoted literals in a compiled object.

A compiled form may contain path literals. Although paths are +not normally printed in a way that can be read back in, path literals +can be written and read as part of compiled code. The +current-write-relative-directory parameter is used to convert +the path to a relative path as is it written, and then +current-load-relative-directory parameter (falling back to +current-directory) is used to convert +any relative path back as it is read.

For a path in a syntax object’s source, if the +current-write-relative-directory parameter is not set or the +path is not relative to the value of the +current-write-relative-directory parameter, then the path is +coerced to a string that preserves only part of the path (an in effort +to make it less tied to the build-time filesystem, which can be +different than the run-time filesystem).

Finally, a compiled form may contain srcloc structures if the +source field of the structure is a path for some system, a string, a +byte string, a symbol, or #f. For a path value (matching the +current platform’s convention), if the path cannot be recorded as a +relative path based on current-write-relative-directory, then +it is converted to a string with at most two path elements; if the +path contains more than two elements, then the string contains +.../, the next-to-last element, / and the last +element. The intent of the constraints on srcloc values and +the conversion of the source field is to preserve some source +information but not expose or record a path that makes no sense on +a different filesystem or platform.

For internal testing purposes in the BC implementation of Racket, when the +PLT_VALIDATE_LOAD environment variable is set, the +reader runs a validator on bytecode parsed from #~. The +validator may catch miscompilations or bytecode-file corruption. The +validator may run lazily, such as checking a procedure only when the +procedure is called.

Changed in version 6.90.0.21 of package base: Adjusted the effect of changing +the code inspector on parsed +bytecode, causing the reader to +mark the loaded code as generally +unrunnable instead of rejecting at +read time references to unsafe +operations.
Changed in version 7.0: Allowed some srcloc values +embedded in compiled code.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/procedures.html b/clones/docs.racket-lang.org/reference/procedures.html new file mode 100644 index 00000000..d8cceaee --- /dev/null +++ b/clones/docs.racket-lang.org/reference/procedures.html @@ -0,0 +1,262 @@ + +4.19 Procedures

4.19 Procedures

procedure

(procedure? v)  boolean?

  v : any/c
Returns #t if +v is a procedure, #f otherwise.

procedure

(apply proc v ... lst #:<kw> kw-arg ...)  any

  proc : procedure?
  v : any/c
  lst : list?
  kw-arg : any/c

Applies proc using the content of (list* v ... lst) +as the (by-position) arguments. The #:<kw> kw-arg sequence is +also supplied as keyword arguments to proc, where +#:<kw> stands for any keyword.

The given proc must accept as many arguments as the number of +vs plus length of lst, it must accept the supplied +keyword arguments, and it must not require any other keyword +arguments; otherwise, the exn:fail:contract exception is raised. The given +proc is called in tail position with respect to the +apply call.

Examples:
> (apply + '(1 2 3))

6

> (apply + 1 2 '(3))

6

> (apply + '())

0

> (apply sort (list (list '(2) '(1)) <) #:key car)

'((1) (2))

procedure

(compose proc ...)  procedure?

  proc : procedure?

procedure

(compose1 proc ...)  procedure?

  proc : procedure?
Returns a procedure that composes the given functions, applying the last +proc first and the first proc last. The compose function +allows the given functions to consume and produce any number of values, as +long as each function produces as many values as the preceding function +consumes, while compose1 restricts the internal value passing to +a single value. In both cases, the input arity of the last function and +the output arity of the first are unrestricted, and they become the +corresponding arity of the resulting composition (including keyword +arguments for the input side).

When no proc arguments are given, the result is +values. When exactly one is given, it is returned.

Examples:
> ((compose1 - sqrt) 10)

-3.1622776601683795

> ((compose1 sqrt -) 10)

0.0+3.1622776601683795i

> ((compose list split-path) (bytes->path #"/a" 'unix))

'(#<path:/> #<path:a> #f)

Note that in many cases, compose1 is preferred. For example, +using compose with two library functions may lead to problems +when one function is extended to return two values, and the preceding +one has an optional input with different semantics. In addition, +compose1 may create faster compositions.

procedure

(procedure-rename proc name [realm])  procedure?

  proc : procedure?
  name : symbol?
  realm : symbol? = 'racket
Returns a procedure that is like proc, except that its name +as returned by object-name (and as printed for debugging) is +name and its realm (potentially used for adjusting +error messages) is realm.

The given name and realm are used for printing and adjusting +an error message if the +resulting procedure is applied to the wrong number of arguments. In +addition, if proc is an accessor or mutator +produced by struct, +make-struct-field-accessor, or +make-struct-field-mutator, the resulting procedure also uses +name when its (first) argument has the wrong type. More +typically, however, name is not used for reporting errors, +since the procedure name is typically hard-wired into an internal +check.

Changed in version 8.4.0.2 of package base: Added the realm argument.

procedure

(procedure-realm proc)  symbol?

  proc : procedure?
Reports the realm of a procedure, which can depend on the +module where the procedure was created, the +current-compile-realm value when the procedure’s code was +compiled, or a realm explicitly assigned through a function like +procedure-rename.

Added in version 8.4.0.2 of package base.

procedure

(procedure->method proc)  procedure?

  proc : procedure?
Returns a procedure that is like proc except that, when applied +to the wrong number of arguments, the resulting error hides the first +argument as if the procedure had been compiled with the +'method-arity-error syntax property.

procedure

(procedure-closure-contents-eq? proc1    
  proc2)  boolean?
  proc1 : procedure?
  proc2 : procedure?
Compares the contents of the closures of proc1 and proc2 +for equality by comparing closure elements pointwise using eq?

4.19.1 Keywords and Arity

procedure

(keyword-apply proc    
  kw-lst    
  kw-val-lst    
  v ...    
  lst    
  #:<kw> kw-arg ...)  any
  proc : procedure?
  kw-lst : (listof keyword?)
  kw-val-lst : list?
  v : any/c
  lst : list?
  kw-arg : any/c

Like apply, but kw-lst and kw-val-lst +supply by-keyword arguments in addition to the by-position arguments +of the vs and lst, and in addition to the directly +supplied keyword arguments in the #:<kw> kw-arg sequence, +where #:<kw> stands for any keyword.

The given kw-lst must be sorted using keyword<?. No +keyword can appear twice in kw-lst or in both +kw-list and as a #:<kw>, otherwise, the +exn:fail:contract exception is raised. The given kw-val-lst must have +the same length as kw-lst, otherwise, the +exn:fail:contract exception is raised. The given proc must accept all +of the keywords in kw-lst plus the #:<kw>s, it must +not require any other keywords, and it must accept as many by-position +arguments as supplied via the vs and lst; otherwise, +the exn:fail:contract exception is raised.

Examples:
(define (f x #:y y #:z [z 10])
  (list x y z))

 

> (keyword-apply f '(#:y) '(2) '(1))

'(1 2 10)

> (keyword-apply f '(#:y #:z) '(2 3) '(1))

'(1 2 3)

> (keyword-apply f #:z 7 '(#:y) '(2) '(1))

'(1 2 7)

procedure

(procedure-arity proc)  normalized-arity?

  proc : procedure?
Returns information about the number of by-position arguments accepted +by proc. See also procedure-arity?, +normalized-arity?, and procedure-arity-mask.

procedure

(procedure-arity? v)  boolean?

  v : any/c
A valid arity a is one of the following:

  • An exact non-negative integer, which means that the procedure +accepts a arguments, only.

  • A arity-at-least instance, which means that the +procedure accepts (arity-at-least-value a) or more +arguments.

  • A list containing integers and arity-at-least +instances, which means that the procedure accepts any number of +arguments that can match one of the elements of a.

The result of procedure-arity is always normalized in the sense of +normalized-arity?.

Examples:

procedure

(procedure-arity-mask proc)  exact-integer?

  proc : procedure?
Returns the same information as procedure-arity, but encoded +differently. The arity is encoded as an exact integer mask +where (bitwise-bit-set? mask n) returns true if proc +accepts n arguments.

The mask encoding of an arity is often easier to test and manipulate, +and procedure-arity-mask is sometimes faster than +procedure-arity while always being at least as fast.

Added in version 7.0.0.11 of package base.

procedure

(procedure-arity-includes? proc k [kws-ok?])  boolean?

  proc : procedure?
  k : exact-nonnegative-integer?
  kws-ok? : any/c = #f
Returns #t if the procedure can accept k by-position +arguments, #f otherwise. If kws-ok? is #f, +the result is #t only if proc has no required +keyword arguments.

Examples:
> (procedure-arity-includes? cons 2)

#t

> (procedure-arity-includes? display 3)

#f

> (procedure-arity-includes? (lambda (x #:y y) x) 1)

#f

> (procedure-arity-includes? (lambda (x #:y y) x) 1 #t)

#t

procedure

(procedure-reduce-arity proc    
  arity    
  [name    
  realm])  procedure?
  proc : procedure?
  arity : procedure-arity?
  name : (or/c symbol? #f) = #f
  realm : symbol? = 'racket
Returns a procedure that is the same as proc (including +the same name returned by object-name), but that accepts +only arguments consistent with arity. In particular, +when procedure-arity is applied to the generated +procedure, it returns a value that is equal? to +the normalized form of arity.

If the arity specification allows arguments that are not in +(procedure-arity proc), the exn:fail:contract exception is raised. If +proc accepts keyword argument, either the keyword arguments +must be all optional (and they are not accepted in by the +arity-reduced procedure) or arity must be the empty list +(which makes a procedure that cannot be called); otherwise, the +exn:fail:contract exception is raised.

If name is not #f, then object-name of the +result procedure produces name, and procedure-realm +of the result produced produces realm. Otherwise, +object-name and procedure-realm of the result procedure +produce the same result as for proc.

Examples:
> (define my+ (procedure-reduce-arity + 2))
> (my+ 1 2)

3

> (my+ 1 2 3)

+: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 2

  given: 3

> (define also-my+ (procedure-reduce-arity + 2 'also-my+))
> (also-my+ 1 2 3)

also-my+: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 2

  given: 3

Changed in version 7.0.0.11 of package base: Added the optional name +argument.
Changed in version 8.4.0.2: Added the realm argument.

procedure

(procedure-reduce-arity-mask proc    
  mask    
  [name    
  realm])  procedure?
  proc : procedure?
  mask : exact-integer?
  name : (or/c symbol? #f) = #f
  realm : symbol? = 'racket
The same as procedure-reduce-arity, but using the +representation of arity described with procedure-arity-mask.

The mask encoding of an arity is often easier to test and manipulate, +and procedure-reduce-arity-mask is sometimes faster than +procedure-reduce-arity while always being at least as fast.

Added in version 7.0.0.11 of package base.
Changed in version 8.4.0.2: Added the realm argument.

procedure

(procedure-keywords proc)  
(listof keyword?)
(or/c (listof keyword?) #f)
  proc : procedure?
Returns information about the keyword arguments required and accepted +by a procedure. The first result is a list of distinct keywords (sorted by +keyword<?) that are required when applying proc. The +second result is a list of distinct accepted keywords (sorted by +keyword<?), or #f to mean that any keyword is +accepted. When the second result is a list, every element in the first +list is also in the second list.

Examples:
> (procedure-keywords +)

'()

'()

> (procedure-keywords (lambda (#:tag t #:mode m) t))

'(#:mode #:tag)

'(#:mode #:tag)

> (procedure-keywords (lambda (#:tag t #:mode [m #f]) t))

'(#:tag)

'(#:mode #:tag)

procedure

(procedure-result-arity proc)  (or/c #f procedure-arity?)

  proc : procedure?
Returns the arity of the result of the procedure proc or +#f if the number of results are not known, perhaps due to shortcomings +in the implementation of procedure-result-arity or +because proc’s behavior is not sufficiently simple.

Examples:
> (procedure-result-arity car)

1

> (procedure-result-arity values)

#f

> (procedure-result-arity
   (λ (x)
     (apply
      values
      (let loop ()
        (cond
          [(zero? (random 10)) '()]
          [else (cons 1 (loop))])))))

#f

Added in version 6.4.0.3 of package base.

procedure

(make-keyword-procedure proc [plain-proc])  procedure?

  proc : (((listof keyword?) list?) () #:rest list? . ->* . any)
  plain-proc : procedure?
   = (lambda args (apply proc null null args))
Returns a procedure that accepts all keyword arguments (without +requiring any keyword arguments).

When the procedure returned by make-keyword-procedure +is called with keyword arguments, then proc +is called; the first argument is a list of distinct keywords sorted by +keyword<?, the second argument is a parallel list containing a +value for each keyword, and the remaining arguments are the +by-position arguments.

When the procedure returned by make-keyword-procedure +is called without keyword arguments, then +plain-proc is called—possibly more efficiently than +dispatching through proc. Normally, plain-proc +should have the same behavior as calling proc with empty lists as +the first two arguments, but that correspondence is in no way +enforced.

The result of procedure-arity and object-name on the +new procedure is the same as for plain-proc. See also +procedure-reduce-keyword-arity and procedure-rename.

Examples:
(define show
  (make-keyword-procedure (lambda (kws kw-args . rest)
                            (list kws kw-args rest))))

 

> (show 1)

'(() () (1))

> (show #:init 0 1 2 3 #:extra 4)

'((#:extra #:init) (4 0) (1 2 3))

 

(define show2
  (make-keyword-procedure (lambda (kws kw-args . rest)
                            (list kws kw-args rest))
                          (lambda args
                            (list->vector args))))

 

> (show2 1)

'#(1)

> (show2 #:init 0 1 2 3 #:extra 4)

'((#:extra #:init) (4 0) (1 2 3))

procedure

(procedure-reduce-keyword-arity proc    
  arity    
  required-kws    
  allowed-kws    
  [name    
  realm])  procedure?
  proc : procedure?
  arity : procedure-arity?
  required-kws : (listof keyword?)
  allowed-kws : 
(or/c (listof keyword?)
      #f)
  name : (or/c symbol? #f) = #f
  realm : symbol? = 'racket
Like procedure-reduce-arity, but constrains the keyword +arguments according to required-kws and allowed-kws, +which must be sorted using keyword<? and contain no duplicates. If allowed-kws +is #f, then the resulting procedure still accepts any +keyword, otherwise the keywords in required-kws must be a +subset of those in allowed-kws. The original proc +must require no more keywords than the ones listed in +required-kws, and it must allow at least the keywords in +allowed-kws (or it must allow all keywords if +allowed-kws is #f).

Examples:
(define orig-show
  (make-keyword-procedure (lambda (kws kw-args . rest)
                            (list kws kw-args rest))))
(define show (procedure-reduce-keyword-arity
              orig-show 3 '(#:init) '(#:extra #:init)))

 

> (show #:init 0 1 2 3 #:extra 4)

'((#:extra #:init) (4 0) (1 2 3))

> (show 1)

unknown: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 3 plus an argument with keyword #:init plus an

optional argument with keyword #:extra

  given: 1

  arguments...:

   1

> (show #:init 0 1 2 3 #:extra 4 #:more 7)

application: procedure does not expect an argument with

given keyword

  procedure: unknown

  given keyword: #:more

  arguments...:

   1

   2

   3

   #:extra 4

   #:init 0

   #:more 7

Changed in version 8.4.0.2 of package base: Added the realm argument.

procedure

(procedure-reduce-keyword-arity-mask proc    
  mask    
  required-kws    
  allowed-kws    
  [name    
  realm])  procedure?
  proc : procedure?
  mask : exact-integer?
  required-kws : (listof keyword?)
  allowed-kws : 
(or/c (listof keyword?)
       #f)
  name : (or/c symbol? #f) = #f
  realm : symbol? = 'racket
The same as procedure-reduce-keyword-arity, but using the +representation of arity described with procedure-arity-mask.

Added in version 7.0.0.11 of package base.
Changed in version 8.4.0.2: Added the realm argument.

struct

(struct arity-at-least (value)
    #:extra-constructor-name make-arity-at-least)
  value : exact-nonnegative-integer?
A structure type used for the result of procedure-arity. +See also procedure-arity?.

A structure type property to identify structure types whose +instances can be applied as procedures. In particular, when +procedure? is applied to the instance, the result will be +#t, and when an instance is used in the function position of +an application expression, a procedure is extracted from the instance +and used to complete the procedure call.

If the prop:procedure property value is an exact non-negative integer, it +designates a field within the structure that should contain a +procedure. The integer must be between 0 (inclusive) and the +number of non-automatic fields in the structure type (exclusive, not +counting supertype fields). The designated field must also be +specified as immutable, so that after an instance of the structure is +created, its procedure cannot be changed. (Otherwise, the arity and +name of the instance could change, and such mutations are generally +not allowed for procedures.) When the instance is used as the +procedure in an application expression, the value of the designated +field in the instance is used to complete the procedure call. (This +procedure can be another structure that acts as a procedure; the +immutability of procedure fields disallows cycles in the procedure +graph, so that the procedure call will eventually continue with a +non-structure procedure.) That procedure receives all of the arguments +from the application expression. The procedure’s name (see +object-name), arity (see procedure-arity), and +keyword protocol (see procedure-keywords) are also used for +the name, arity, and keyword protocol of the structure. If the value +in the designated field is not a procedure, then the instance behaves +like (case-lambda) (i.e., a procedure which does not accept +any number of arguments). See also procedure-extract-target.

Providing an integer proc-spec argument to +make-struct-type is the same as both supplying the value with +the prop:procedure property and designating the field as +immutable (so that a property binding or immutable designation is +redundant and disallowed).

Examples:
> (struct annotated-proc (base note)
    #:property prop:procedure
               (struct-field-index base))
> (define plus1 (annotated-proc
                  (lambda (x) (+ x 1))
                  "adds 1 to its argument"))
> (procedure? plus1)

#t

> (annotated-proc? plus1)

#t

> (plus1 10)

11

> (annotated-proc-note plus1)

"adds 1 to its argument"

When the prop:procedure value is a procedure, it should +accept at least one non-keyword argument. When an instance of the +structure is used in an application expression, the property-value +procedure is called with the instance as the first argument. The +remaining arguments to the property-value procedure are the arguments +from the application expression (including keyword arguments). Thus, +if the application expression provides five non-keyword arguments, the +property-value procedure is called with six non-keyword arguments. The +name of the instance (see object-name) and its keyword +protocol (see procedure-keywords) are unaffected by the +property-value procedure, but the instance’s arity is determined by +subtracting one from every possible non-keyword argument count of the +property-value procedure. If the property-value procedure cannot +accept at least one argument, then the instance behaves like +(case-lambda).

Providing a procedure proc-spec argument to +make-struct-type is the same as supplying the value with the +prop:procedure property (so that a specific property binding +is disallowed).

Examples:
> (struct fish (weight color)
    #:mutable
    #:property
    prop:procedure
    (lambda (f n)
      (let ([w (fish-weight f)])
        (set-fish-weight! f (+ n w)))))
> (define wanda (fish 12 'red))
> (fish? wanda)

#t

> (procedure? wanda)

#t

> (fish-weight wanda)

12

> (for-each wanda '(1 2 3))
> (fish-weight wanda)

18

If the value supplied for the prop:procedure property is not +an exact non-negative integer or a procedure, the +exn:fail:contract exception is raised.

procedure

(procedure-struct-type? type)  boolean?

  type : struct-type?
Returns #t if instances of the structure type represented by +type are procedures (according to procedure?), +#f otherwise.

procedure

(procedure-extract-target proc)  (or/c #f procedure?)

  proc : procedure?
If proc is an instance of a structure type with property +prop:procedure, and if the property value indicates a field +of the structure, and if the field value is a procedure, then +procedure-extract-target returns the field value. Otherwise, +the result is #f.

When a prop:procedure property value is a procedure, the +procedure is not returned by +procedure-extract-target. Such a procedure is different from +one accessed through a structure field, because it consumes an extra +argument, which is always the structure that was applied as a +procedure. Keeping the procedure private ensures that is it always +called with a suitable first argument.

A structure type property that is used for reporting arity-mismatch errors when a +structure type with the prop:procedure property is applied to +the wrong number of arguments. The value of the +prop:arity-string property must be a procedure that takes a +single argument, which is the misapplied structure, and returns a +string. The result string is used after the word “expects,” and it +is followed in the error message by the number of actual arguments.

Arity-mismatch reporting automatically uses +procedure-extract-target when the prop:arity-string +property is not associated with a procedure structure type.

Examples:
> (struct evens (proc)
    #:property prop:procedure (struct-field-index proc)
    #:property prop:arity-string
    (lambda (p)
      "an even number of arguments"))
> (define pairs
    (evens
     (case-lambda
      [() null]
      [(a b . more)
       (cons (cons a b)
             (apply pairs more))])))
> (pairs 1 2 3 4)

'((1 . 2) (3 . 4))

> (pairs 5)

arity mismatch;

 the expected number of arguments does not match the given

number

  expected: an even number of arguments

  given: 1

  arguments...:

   5

A structure type property that is used with +checked-procedure-check-and-extract, which is a hook to allow +the compiler to improve the performance of keyword arguments. The +property can only be attached to a structure type without a +supertype and with at least two fields.

procedure

(checked-procedure-check-and-extract type    
  v    
  proc    
  v1    
  v2)  any/c
  type : struct-type?
  v : any/c
  proc : (any/c any/c any/c . -> . any/c)
  v1 : any/c
  v2 : any/c
Extracts a value from v if it is an instance of +type, which must have the property +prop:checked-procedure. If v is such an instance, +then the first field of v is extracted and applied to +v1 and v2; if the result is a true value, the result +is the value of the second field of v.

If v is not an instance of type, or if the first +field of v applied to v1 and v2 produces +#f, then proc is applied to v, v1, +and v2, and its result is returned by +checked-procedure-check-and-extract.

procedure

(procedure-specialize proc)  procedure?

  proc : procedure?
Returns proc or its equivalent, but provides a hint to the +run-time system that it should spend extra time and memory to +specialize the implementation of proc.

The hint is currently used when proc is the value of a +lambda or case-lambda form that references variables +bound outside of the lambda or case-lambda, and when +proc has not been previously applied.

Added in version 6.3.0.10 of package base.

4.19.2 Reflecting on Primitives

A primitive procedure is a built-in procedure that may be +implemented in a lower-level language. Not all procedures of +racket/base are primitives, but many are. The +distinction between primitives and other procedures may be useful to +other low-level code.

The distinction between primitives and other procedures may also be +useful for adjusting exception messages through parameters such as +error-primitive-name->symbol-handler, but the notion of +“primitive” for those handlers and the notion for +primitive? do not coincide completely.

procedure

(primitive? v)  boolean?

  v : any/c
Returns #t if v is a primitive procedure, +#f otherwise.

procedure

(primitive-closure? v)  boolean

  v : any/c
Returns #t if v is internally implemented as a +primitive closure rather than a simple primitive procedure, +#f otherwise.

procedure

(primitive-result-arity prim)  procedure-arity?

  prim : primitive?
Returns the arity of the result of the primitive procedure +prim (as opposed to the procedure’s input arity as returned +by procedure-arity). For most primitives, this procedure +returns 1, since most primitives return a single value when +applied.

4.19.3 Additional Higher-Order Functions

The bindings documented in this section are provided by the racket/function and racket libraries, but not racket/base.

procedure

(identity v)  any/c

  v : any/c
Returns v.

procedure

(const v)  procedure?

  v : any
Returns a procedure that accepts any arguments (including keyword +arguments) and returns v.

Examples:
> ((const 'foo) 1 2 3)

'foo

> ((const 'foo))

'foo

syntax

(thunk  body ...+)

syntax

(thunk* body ...+)

The thunk form creates a nullary function that evaluates the +given body. The thunk* form is similar, except that the +resulting function accepts any arguments (including keyword arguments).

Examples:
(define th1 (thunk (define x 1) (printf "~a\n" x)))

 

> (th1)

1

> (th1 'x)

th1: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 0

  given: 1

> (th1 #:y 'z)

application: procedure does not accept keyword arguments

  procedure: th1

  arguments...:

   #:y 'z

 

(define th2 (thunk* (define x 1) (printf "~a\n" x)))

 

> (th2)

1

> (th2 'x)

1

> (th2 #:y 'z)

1

procedure

(negate proc)  procedure?

  proc : procedure?
Returns a procedure that is just like proc, except that it +returns the not of proc’s result.

Examples:
> (filter (negate symbol?) '(1 a 2 b 3 c))

'(1 2 3)

> (map (negate =) '(1 2 3) '(1 1 1))

'(#f #t #t)

procedure

((conjoin f ...) x ...)  any

  f : procedure?
  x : any/c
Combines calls to each function with and. Equivalent to +(and (f x ...) ...)

Examples:
(define f (conjoin exact? integer?))

 

> (f 1)

#t

> (f 1.0)

#f

> (f 1/2)

#f

> (f 0.5)

#f

> ((conjoin (λ (x) (values 1 2))) 0)

1

2

procedure

((disjoin f ...) x ...)  any

  f : procedure?
  x : any/c
Combines calls to each function with or. Equivalent to +(or (f x ...) ...)

Examples:
(define f (disjoin exact? integer?))

 

> (f 1)

#t

> (f 1.0)

#t

> (f 1/2)

#t

> (f 0.5)

#f

> ((disjoin (λ (x) (values 1 2))) 0)

1

2

procedure

(curry proc)  procedure?

  proc : procedure?
(curry proc v ...+)  any/c
  proc : procedure?
  v : any/c
The result of (curry proc) is a procedure that is a curried +version of proc. When +the resulting procedure is first applied, unless it is given the +maximum number of arguments that it can accept according to +(procedure-arity proc), the result is a +procedure to accept additional arguments.

Examples:
> ((curry list) 1 2)

#<procedure:curried:list>

> ((curry cons) 1)

#<procedure:curried:cons>

> ((curry cons) 1 2)

'(1 . 2)

After the first application of the result of (curry proc), each +further application accumulates arguments until an acceptable number +of arguments according to (procedure-arity proc) have been +accumulated, at which point the original +proc is called.

Examples:
> (((curry list) 1 2) 3)

'(1 2 3)

> (((curry list) 1) 3)

'(1 3)

> ((((curry foldl) +) 0) '(1 2 3))

6

> (define foo (curry (lambda (x y z) (list x y z))))
> (foo 1 2 3)

'(1 2 3)

> (((((foo) 1) 2)) 3)

'(1 2 3)

A function call (curry proc v ...) is equivalent to +((curry proc) v ...). In other words, curry itself +is curried.

Examples:
> (map ((curry +) 10) '(1 2 3))

'(11 12 13)

> (map (curry + 10) '(1 2 3))

'(11 12 13)

> (map (compose (curry * 2) (curry + 10)) '(1 2 3))

'(22 24 26)

The curry function also supports functions with keyword arguments: +keyword arguments will be accumulated in the same way as positional arguments +until all required keyword arguments according to (procedure-keywords proc) +have been supplied.

Examples:
(define (f #:a a #:b b #:c c)
  (list a b c))

 

> ((((curry f) #:a 1) #:b 2) #:c 3)

'(1 2 3)

> ((((curry f) #:b 1) #:c 2) #:a 3)

'(3 1 2)

> ((curry f #:a 1 #:c 2) #:b 3)

'(1 3 2)

Changed in version 7.0.0.7 of package base: Added support for keyword arguments.

procedure

(curryr proc)  procedure?

  proc : procedure?
(curryr proc v ...+)  any/c
  proc : procedure?
  v : any/c
Like curry, except that the arguments are collected in the +opposite direction: the first step collects the rightmost group of +arguments, and following steps add arguments to the left of these.

Example:
> (map (curryr list 'foo) '(1 2 3))

'((1 foo) (2 foo) (3 foo))

procedure

(normalized-arity? arity)  boolean?

  arity : any/c
A normalized arity has one of the following forms: +
  • the empty list;

  • an exact non-negative integer;

  • an arity-at-least instance;

  • a list of two or more strictly increasing, exact non-negative integers; +or

  • a list of one or more strictly increasing, exact non-negative integers +followed by a single arity-at-least instance whose value is greater +than the preceding integer by at least 2.

Every normalized arity is a valid procedure arity and satisfies +procedure-arity?. Any two normalized arity values that are +arity=? must also be equal?.

Examples:

procedure

(normalize-arity arity)

  (and/c normalized-arity? (lambda (x) (arity=? x arity)))
  arity : procedure-arity?
Produces a normalized form of arity. See also +normalized-arity? and arity=?.

Examples:
> (normalize-arity 1)

1

> (normalize-arity (list 1))

1

> (normalize-arity (arity-at-least 2))

(arity-at-least 2)

> (normalize-arity (list (arity-at-least 2)))

(arity-at-least 2)

> (normalize-arity (list 1 (arity-at-least 2)))

(arity-at-least 1)

> (normalize-arity (list (arity-at-least 2) 1))

(arity-at-least 1)

> (normalize-arity (list (arity-at-least 2) 3))

(arity-at-least 2)

> (normalize-arity (list 3 (arity-at-least 2)))

(arity-at-least 2)

> (normalize-arity (list (arity-at-least 6) 0 2 (arity-at-least 4)))

(list 0 2 (arity-at-least 4))

procedure

(arity=? a b)  boolean?

  a : procedure-arity?
  b : procedure-arity?
Returns #true if procedures with arity a and b +accept the same numbers of arguments, and #false otherwise. +Equivalent to both (and (arity-includes? a b) (arity-includes? b a)) +and (equal? (normalize-arity a) (normalize-arity b)).

Examples:
> (arity=? 1 1)

#t

> (arity=? (list 1) 1)

#t

> (arity=? 1 (list 1))

#t

> (arity=? 1 (arity-at-least 1))

#f

> (arity=? (arity-at-least 1) 1)

#f

> (arity=? (arity-at-least 1) (list 1 (arity-at-least 2)))

#t

> (arity=? (list 1 (arity-at-least 2)) (arity-at-least 1))

#t

> (arity=? (arity-at-least 1) (list 1 (arity-at-least 3)))

#f

> (arity=? (list 1 (arity-at-least 3)) (arity-at-least 1))

#f

> (arity=? (list 0 1 2 (arity-at-least 3)) (list (arity-at-least 0)))

#t

> (arity=? (list (arity-at-least 0)) (list 0 1 2 (arity-at-least 3)))

#t

> (arity=? (list 0 2 (arity-at-least 3)) (list (arity-at-least 0)))

#f

> (arity=? (list (arity-at-least 0)) (list 0 2 (arity-at-least 3)))

#f

procedure

(arity-includes? a b)  boolean?

  a : procedure-arity?
  b : procedure-arity?
Returns #true if procedures with arity a accept any number of +arguments that procedures with arity b accept.

Examples:

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/quasiquote.html b/clones/docs.racket-lang.org/reference/quasiquote.html new file mode 100644 index 00000000..fca81171 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/quasiquote.html @@ -0,0 +1,36 @@ + +3.20 Quasiquoting: quasiquote, unquote, and unquote-splicing

3.20 Quasiquoting: quasiquote, unquote, and unquote-splicing

+Quasiquoting: quasiquote and in The Racket Guide introduces quasiquote.

syntax

(quasiquote datum)

The same as 'datum if datum does not include +(unquote expr) or (unquote-splicing expr). An +(unquote expr) form escapes from the quote, however, +and the result of the expr takes the place of the +(unquote expr) form in the quasiquote result. An +(unquote-splicing expr) similarly escapes, but the +expr produces a list whose elements are spliced as +multiple values place of the (unquote-splicing expr).

An unquote or unquote-splicing form is recognized in any +of the following escaping positions within datum: in a pair, +in a vector, in a box, in a prefab structure field after the +name position, and in hash table value position (but not in a hash +table key position). Such escaping positions can be nested to an +arbitrary depth.

An unquote-splicing form must appear as the car of a +quoted pair, as an element of a quoted vector, or as an element of a +quoted prefab structure. In the case of a pair, if the +cdr of the relevant quoted pair is empty, then expr +need not produce a list, and its result is used directly in place of +the quoted pair (in the same way that append accepts a +non-list final argument).

If unquote or unquote-splicing appears within +quasiquote in an escaping position but in a way other than as +(unquote expr) or (unquote-splicing expr), a syntax error is reported.

Examples:
> (quasiquote (0 1 2))

'(0 1 2)

> (quasiquote (0 (unquote (+ 1 2)) 4))

'(0 3 4)

> (quasiquote (0 (unquote-splicing (list 1 2)) 4))

'(0 1 2 4)

> (quasiquote (0 (unquote-splicing 1) 4))

unquote-splicing: contract violation

  expected: list?

  given: 1

> (quasiquote (0 (unquote-splicing 1)))

'(0 . 1)

A quasiquote, unquote, or unquote-splicing +form is typically abbreviated with `, ,, or +,@, respectively. See also Reading Quotes.

Examples:
> `(0 1 2)

'(0 1 2)

> `(1 ,(+ 1 2) 4)

'(1 3 4)

> `#s(stuff 1 ,(+ 1 2) 4)

'#s(stuff 1 3 4)

> `#hash(("a" . ,(+ 1 2)))

'#hash(("a" . 3))

> `#hash((,(+ 1 2) . "a"))

'#hash((,(+ 1 2) . "a"))

> `(1 ,@(list 1 2) 4)

'(1 1 2 4)

> `#(1 ,@(list 1 2) 4)

'#(1 1 2 4)

A quasiquote form within the original datum +increments the level of quasiquotation: within the quasiquote +form, each unquote or unquote-splicing is preserved, +but a further nested unquote or unquote-splicing +escapes. Multiple nestings of quasiquote require multiple +nestings of unquote or unquote-splicing to escape.

Examples:
> `(1 `,(+ 1 ,(+ 2 3)) 4)

'(1 `,(+ 1 5) 4)

> `(1 ```,,@,,@(list (+ 1 2)) 4)

'(1 ```,,@,3 4)

The quasiquote form allocates only as many fresh cons cells, +vectors, and boxes as are needed without analyzing unquote +and unquote-splicing expressions. For example, in

`(,1 2 3)

a single tail '(2 3) is used for every evaluation of the +quasiquote expression. When allocating fresh data, +the quasiquote form allocates mutable vectors, mutable boxes +and immutable hashes.

Examples:
> (immutable? `#(,0))

#f

> (immutable? `#hash((a . ,0)))

#t

syntax

unquote

See quasiquote, where unquote is recognized as an +escape. An unquote form as an expression is a syntax error.

See quasiquote, where unquote-splicing is recognized as an +escape. An unquote-splicing form as an expression is a syntax error.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/quote.html b/clones/docs.racket-lang.org/reference/quote.html new file mode 100644 index 00000000..78cf1f13 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/quote.html @@ -0,0 +1,9 @@ + +3.3 Literals: quote and #%datum
On this page:
quote
#%datum

3.3 Literals: quote and #%datum

Many forms are implicitly quoted (via #%datum) as literals. See +Expansion Steps for more information.

+Quoting: quote and in The Racket Guide introduces quote.

syntax

(quote datum)

Produces a constant value corresponding to datum (i.e., the +representation of the program fragment) without its lexical +information, source location, etc. Quoted pairs, vectors, and boxes +are immutable.

Examples:
> (quote x)

'x

> (quote (+ 1 2))

'(+ 1 2)

> (+ 1 2)

3

syntax

(#%datum . datum)

Expands to (quote datum), as long as +datum is not a keyword. If datum is a keyword, a +syntax error is reported.

See also Expansion Steps for information on how the expander +introduces #%datum identifiers.

Examples:
> (#%datum . 10)

10

> (#%datum . x)

'x

> (#%datum . #:x)

eval:6:0: #%datum: keyword misused as an expression

  at: #:x

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/racket_contract_base.html b/clones/docs.racket-lang.org/reference/racket_contract_base.html new file mode 100644 index 00000000..4af37dab --- /dev/null +++ b/clones/docs.racket-lang.org/reference/racket_contract_base.html @@ -0,0 +1,10 @@ + +8.9 racket/contract/base

8.9 racket/contract/base

 (require racket/contract/base) package: base

The racket/contract/base module provides a subset +of the exports of racket/contract module. In +particular, it contains everything in the +

Unfortunately, using racket/contract/base does not +yield a significantly smaller memory footprint than +racket/contract, but it can still be useful to +add contracts to libraries that racket/contract +uses to implement some of the more sophisticated +parts of the contract system.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/reader-procs.html b/clones/docs.racket-lang.org/reference/reader-procs.html new file mode 100644 index 00000000..1e8783cb --- /dev/null +++ b/clones/docs.racket-lang.org/reference/reader-procs.html @@ -0,0 +1,32 @@ + +13.7.2 Reader-Extension Procedures
13.7.2 Reader-Extension Procedures

Calls to reader extension procedures can be triggered +through read, read/recursive, or read-syntax. +In addition, a special-read procedure +can be triggered by calls to read-char-or-special, or +by the context of read-bytes-avail!, +peek-bytes-avail!*, read-bytes-avail!, and +peek-bytes-avail!*.

Optional arities for reader-macro and special-result procedures allow +them to distinguish reads via read, etc., from reads via +read-syntax, etc. (where the source value is #f and +no other location information is available).

When a reader-extension procedure is called in syntax-reading mode +(via read-syntax, etc.), it should generally return a syntax +object that has no lexical context (e.g., a syntax object created +using datum->syntax with #f as the first +argument and with the given location information as the third +argument). Another possible result is a special-comment value (see +Special Comments). If the procedure’s result is not a +syntax object and not a special-comment value, it is converted to one +using datum->syntax.

When a reader-extension procedure is called in non-syntax-reading +modes, it should generally not return a syntax object. If a syntax +object is returned, it is converted to a plain value using +syntax->datum.

In either context, when the result from a reader-extension procedure +is a special-comment value (see Special Comments), then +read, read-syntax, etc. treat the value as a +delimiting comment and otherwise ignore it.

Also, in either context, the result may be copied to prevent mutation +to vectors or boxes before the read result is completed, and to +support the construction of graphs with cycles. Mutable boxes, +vectors, and prefab structures are copied, along with any +pairs, boxes, vectors, prefab structures that lead to such mutable +values, to placeholders produced by a recursive read (see +read/recursive), or to references of a shared value. Graph +structure (including cycles) is preserved in the copy.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/reader.html b/clones/docs.racket-lang.org/reference/reader.html new file mode 100644 index 00000000..0e5b5984 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/reader.html @@ -0,0 +1,468 @@ + +1.3 The Reader

1.3 The Reader

Racket’s reader is a recursive-descent parser that can be configured +through a readtable and various other +parameters. This section describes the reader’s parsing when +using the default readtable.

Reading from a stream produces one datum. If the result +datum is a compound value, then reading the datum typically requires +the reader to call itself recursively to read the component data.

The reader can be invoked in either of two modes: read mode, +or read-syntax mode. In read-syntax mode, the result +is always a syntax object that includes +source-location and (initially empty) lexical information wrapped +around the sort of datum that read mode would produce. In the +case of pairs, vectors, and boxes, the content is also +wrapped recursively as a syntax object. Unless specified otherwise, +this section describes the reader’s behavior in read mode, +and read-syntax mode does the same modulo wrapping of the final +result.

Reading is defined in terms of Unicode characters; see +Ports for information on how a byte stream is converted +to a character stream.

Symbols, keywords, strings, byte strings, regexps, characters, and +numbers produced by the reader in read-syntax mode are +interned, which means that such values in the result of +read-syntax are always eq? when they are +equal? (whether from the same call or different calls to +read-syntax). Symbols and keywords are interned in +both read and read-syntax mode. When a quoted value +is in compiled code that written and then read back in (see +Printing Compiled Code), only strings and byte strings are +interned when reading the code. Sending an +interned value across a place channel does not +necessarily produce an interned value at the receiving +place. See also datum-intern-literal and +datum->syntax.

Note that interned values are only weakly held by the reader’s +internal table, so they may be garbage +collected if they are no longer otherwise reachable. This weakness +can never affect the result of an eq?, eqv?, or +equal? test, but an interned value may disappear when placed into +a weak box (see Weak Boxes), used as the key in a weak hash +table (see Hash Tables), or used as an ephemeron key (see +Ephemerons).

1.3.1 Delimiters and Dispatch

Along with whitespace and a BOM +character, the following characters are delimiters:

   ( ) [ ] +{ } +" , ' ` +;

A delimited sequence that starts with any other character is typically +parsed as either a symbol, number, or extflonum, but a few non-delimiter +characters play special roles:

  • # has a special meaning as an initial character in a +delimited sequence; its meaning depends on the characters that +follow; see below.

  • | starts a subsequence of characters to +be included verbatim in the delimited sequence (i.e., they are +never treated as delimiters, and they are not case-folded when +case-insensitivity is enabled); the subsequence is terminated +by another |, and neither the initial nor +terminating | is part of the subsequence.

  • \ outside of a | pair causes +the following character to be included verbatim in a delimited +sequence.

More precisely, after skipping whitespace and #\uFEFF BOM +characters, the reader dispatches based on the next character or +characters in the input stream as follows:

 

(

 

starts a pair or list; see Reading Pairs and Lists

 

[

 

starts a pair or list; see Reading Pairs and Lists

 

{

 

starts a pair or list; see Reading Pairs and Lists

 

)

 

matches ( or raises exn:fail:read

 

]

 

matches [ or raises exn:fail:read

 

}

 

matches { or raises exn:fail:read

 

"

 

starts a string; see Reading Strings

 

'

 

starts a quote; see Reading Quotes

 

`

 

starts a quasiquote; see Reading Quotes

 

,

 

starts a [splicing] unquote; see Reading Quotes

 

;

 

starts a line comment; see Reading Comments

 

#t or #T

 

true; see Reading Booleans

 

#f or #F

 

false; see Reading Booleans

 

#(

 

starts a vector; see Reading Vectors

 

#[

 

starts a vector; see Reading Vectors

 

#{

 

starts a vector; see Reading Vectors

 

#fl( or #Fl(

 

starts a flvector; see Reading Vectors

 

#fl[ or #Fl[

 

starts a flvector; see Reading Vectors

 

#fl{ or #Fl{

 

starts a flvector; see Reading Vectors

 

#fx( or #Fx(

 

starts a fxvector; see Reading Vectors

 

#fx[ or #Fx[

 

starts a fxvector; see Reading Vectors

 

#fx{ or #Fx{

 

starts a fxvector; see Reading Vectors

 

#s(

 

starts a structure literal; see Reading Structures

 

#s[

 

starts a structure literal; see Reading Structures

 

#s{

 

starts a structure literal; see Reading Structures

 

#\

 

starts a character; see Reading Characters

 

#"

 

starts a byte string; see Reading Strings

 

#%

 

starts a symbol; see Reading Symbols

 

#:

 

starts a keyword; see Reading Keywords

 

#&

 

starts a box; see Reading Boxes

 

#|

 

starts a block comment; see Reading Comments

 

#;

 

starts an S-expression comment; see Reading Comments

 

#'

 

starts a syntax quote; see Reading Quotes

 

#! 

 

starts a line comment; see Reading Comments

 

#!/

 

starts a line comment; see Reading Comments

 

#!

 

may start a reader extension; see Reading via an Extension

 

#`

 

starts a syntax quasiquote; see Reading Quotes

 

#,

 

starts a syntax [splicing] unquote; see Reading Quotes

 

#~

 

starts compiled code; see Printing Compiled Code

 

#i or #I

 

starts a number; see Reading Numbers

 

#e or #E

 

starts a number; see Reading Numbers

 

#x or #X

 

starts a number or extflonum; see Reading Numbers

 

#o or #O

 

starts a number or extflonum; see Reading Numbers

 

#d or #D

 

starts a number or extflonum; see Reading Numbers

 

#b or #B

 

starts a number or extflonum; see Reading Numbers

 

#<<

 

starts a string; see Reading Strings

 

#rx

 

starts a regular expression; see Reading Regular Expressions

 

#px

 

starts a regular expression; see Reading Regular Expressions

 

#ci, #cI, #Ci, or #CI

 

switches case sensitivity; see Reading Symbols

 

#cs, #cS, #Cs, or #CS

 

switches case sensitivity; see Reading Symbols

 

#hash

 

starts a hash table; see Reading Hash Tables

 

#reader

 

starts a reader extension use; see Reading via an Extension

 

#lang

 

starts a reader extension use; see Reading via an Extension

 

#digit10+(

 

starts a vector; see Reading Vectors

 

#digit10+[

 

starts a vector; see Reading Vectors

 

#digit10+{

 

starts a vector; see Reading Vectors

 

#fldigit10+(

 

starts a flvector; see Reading Vectors

 

#fldigit10+[

 

starts a flvector; see Reading Vectors

 

#fldigit10+{

 

starts a flvector; see Reading Vectors

 

#Fldigit10+(

 

starts a flvector; see Reading Vectors

 

#Fldigit10+[

 

starts a flvector; see Reading Vectors

 

#Fldigit10+{

 

starts a flvector; see Reading Vectors

 

#fxdigit10+(

 

starts a fxvector; see Reading Vectors

 

#fxdigit10+[

 

starts a fxvector; see Reading Vectors

 

#fxdigit10+{

 

starts a fxvector; see Reading Vectors

 

#Fxdigit10+(

 

starts a fxvector; see Reading Vectors

 

#Fxdigit10+[

 

starts a fxvector; see Reading Vectors

 

#Fxdigit10+{

 

starts a fxvector; see Reading Vectors

 

#digit10{1,8}=

 

binds a graph tag; see Reading Graph Structure

 

#digit10{1,8}#

 

uses a graph tag; see Reading Graph Structure

 

otherwise

 

starts a symbol; see Reading Symbols

Changed in version 7.8.0.9 of package base: Changed treatment of the BOM +character so that it is treated +like whitespace in the same places +that comments are allowed.

1.3.2 Reading Symbols

+Symbols in The Racket Guide introduces the syntax of symbols.

A sequence that does not start with a delimiter or # is +parsed as either a symbol, a number (see +Reading Numbers), or a extflonum +(see Reading Extflonums), +except that . by itself is never +parsed as a symbol or number (unless the read-accept-dot +parameter is set to #f). A successful +number or extflonum parse takes precedence over a symbol parse. +A #% also +starts a symbol. The resulting symbol is interned. +See the start of Delimiters and Dispatch for information +about | and \ in parsing symbols.

When the +read-case-sensitive parameter is set to #f, +characters in the sequence that are not quoted by | or +\ are first case-normalized. If the reader encounters +#ci, #CI, #Ci, or +#cI, then it recursively reads the following datum in +case-insensitive mode. If the reader encounters +#cs, #CS, #Cs, or +#cS, then it recursively reads the following datum in +case-sensitive mode.

Examples:

 Apple

 reads equal to 

(string->symbol "Apple")

 Ap#ple

 reads equal to 

(string->symbol "Ap#ple")

 Ap ple

 reads equal to 

(string->symbol "Ap")

 Ap| |ple

 reads equal to 

(string->symbol "Ap ple")

 Ap\ ple

 reads equal to 

(string->symbol "Ap ple")

 #ci Apple

 reads equal to 

(string->symbol "apple")

 #ci |A|pple

 reads equal to 

(string->symbol "Apple")

 #ci \Apple

 reads equal to 

(string->symbol "Apple")

 #ci#cs Apple

 reads equal to 

(string->symbol "Apple")

 #%Apple

 reads equal to 

(string->symbol "#%Apple")

1.3.3 Reading Numbers

+Numbers in The Racket Guide introduces the syntax of numbers.

A sequence that does not start with a delimiter is parsed as a number +when it matches the following grammar case-insensitively for +number10 (decimal), where n is a +meta-meta-variable in the grammar. The resulting number is interned in +read-syntax mode.

A number is optionally prefixed by an exactness specifier, +#e (exact) or #i (inexact), +which specifies its parsing as an exact or inexact number; see +Numbers for information on number exactness. As the +non-terminal names suggest, a number that has no exactness specifier +and matches only inexact-numbern is normally parsed as an +inexact number, otherwise it is parsed as an exact number. If the +read-decimal-as-inexact parameter is set to #f, then +all numbers without an exactness specifier are instead parsed as +exact.

If the reader encounters #b (binary), +#o (octal), #d (decimal), or +#x (hexadecimal), it must be followed by a +sequence that is terminated by a delimiter or end-of-file, and that +is either an extflonum (see Reading Extflonums) or +matches the general-number2, +general-number8, general-number10, or +general-number16 grammar, respectively.

A #e or #i followed immediately by #b, +#o, #d, or #x is treated the same as the +reverse order: #b, #o, #d, or +#x followed by #e or #i.

An exponent-markn in an inexact number serves both to specify +an exponent and to specify a numerical precision. If +single-flonums are supported (see Numbers) and the +read-single-flonum parameter is set to #t, +the marks f and s specify single-flonums. If +read-single-flonum is set to #f, or with any other +mark, a double-precision flonum is produced. If single-flonums +are not supported and read-single-flonum is set to +#t, then the exn:fail:unsupported exception is raised when a single-flonum +would otherwise be produced. Special infinity and not-a-number flonums +and single-flonums are distinct; specials with the .0 +suffix, like +nan.0, are double-precision flonums, while +specials with the .f suffix, like +nan.0, +are single-flonums if enabled though read-single-flonum.

A # in an inexactn number is the same as +0, but # can be used to suggest +that the digit’s actual value is unknown.

All letters in a number representation are parsed case-insensitively, +independent of the read-case-sensitive parameter. For +example, #I#D+InF.F+3I is parsed the same as +#i#d+inf.f+3i. In the grammar below, each literal lowercase +letter stands for both itself and its uppercase form.

 

numbern

 ::= 

exactn  |  inexactn

 

exactn

 ::= 

exact-rationaln  |  exact-complexn

 

exact-rationaln

 ::= 

[sign] unsigned-rationaln

 

unsigned-rationaln

 ::= 

unsigned-integern

 

  |  

unsigned-integern / unsigned-integern

 

exact-integern

 ::= 

[sign] unsigned-integern

 

unsigned-integern

 ::= 

digitn+

 

exact-complexn

 ::= 

exact-rationaln sign unsigned-rationaln i

 

inexactn

 ::= 

inexact-realn  |  inexact-complexn

 

inexact-realn

 ::= 

[sign] inexact-normaln

 

  |  

sign inexact-specialn

 

inexact-unsignedn

 ::= 

inexact-normaln  |  inexact-specialn

 

inexact-normaln

 ::= 

inexact-simplen [exp-markn exact-integern]

 

inexact-simplen

 ::= 

digits#n [.] #*

 

  |  

[unsigned-integern] . digits#n

 

  |  

digits#n / digits#n

 

inexact-specialn

 ::= 

inf.0  |  nan.0  |  inf.f  |  nan.f

 

digits#n

 ::= 

digitn+ #*

 

inexact-complexn

 ::= 

[inexact-realn] sign inexact-unsignedn i

 

  |  

inexact-realn @ inexact-realn

 

sign

 ::= 

+  |  -

 

digit16

 ::= 

digit10  |  a  |  b  |  c  |  d  |  e  |  f

 

digit10

 ::= 

digit8  |  8  |  9

 

digit8

 ::= 

digit2  |  2  |  3  |  4  |  5  |  6  |  7

 

digit2

 ::= 

0  |  1

 

exp-mark16

 ::= 

s  |  l

 

exp-mark10

 ::= 

exp-mark16  |  d  |  e  |  f

 

exp-mark8

 ::= 

exp-mark10

 

exp-mark2

 ::= 

exp-mark10

 

general-numbern

 ::= 

[exactness] numbern

 

exactness

 ::= 

#e  |  #i

Examples:

 -1

 reads equal to 

-1

 1/2

 reads equal to 

(/ 1 2)

 1.0

 reads equal to 

(exact->inexact 1)

 1+2i

 reads equal to 

(make-rectangular 1 2)

 1/2+3/4i

 reads equal to 

(make-rectangular (/ 1 2) (/ 3 4))

 1.0+3.0e7i

 reads equal to 

(exact->inexact (make-rectangular 1 30000000))

 2e5

 reads equal to 

(exact->inexact 200000)

 #i5

 reads equal to 

(exact->inexact 5)

 #e2e5

 reads equal to 

200000

 #x2e5

 reads equal to 

741

 #b101

 reads equal to 

5

1.3.4 Reading Extflonums

An extflonum has the same syntax as an inexact-realn +that includes an exp-markn, but with t or +T in place of the exp-markn. In addition, ++inf.t, -inf.t, +nan.t, -nan.t +are extflonums. A #b +(binary), #o (octal), #d (decimal), or +#x (hexadecimal) radix specification can prefix an +extflonum, but #i or #e cannot, and a +extflonum cannot be used to form a complex number. The +read-decimal-as-inexact parameter has no effect on +extflonum reading.

1.3.5 Reading Booleans

A #true, #t, +#T followed by a delimiter is the input syntax +for the boolean constant “true,” and #false, +#f, or #F followed by a +delimiter is the complete input syntax for the boolean constant +“false.”

1.3.6 Reading Pairs and Lists

When the reader encounters a (, +[, or {, it starts +parsing a pair or list; see Pairs and Lists for information on pairs +and lists.

To parse the pair or list, the reader recursively reads data +until a matching ), ], or +} (respectively) is found, and it specially handles +a . surrounded by delimiters. Pairs (), [], and +{} are treated the same way, so the remainder of this +section simply uses “parentheses” to mean any of these pair.

If the reader finds no delimited . among the elements +between parentheses, then it produces a list containing the results of +the recursive reads.

If the reader finds two data between the matching parentheses +that are separated by a delimited ., then it creates a +pair. More generally, if it finds two or more data where the +last datum is preceded by a delimited ., then it constructs +nested pairs: the next-to-last element is paired with the last, then +the third-to-last datum is paired with that pair, and so on.

If the reader finds three or more data between the matching +parentheses, and if a pair of delimited .s surrounds any +other than the first and last elements, the result is a list +containing the element surrounded by .s as the first +element, followed by the others in the read order. This convention +supports a kind of infix notation at the reader level.

In read-syntax mode, the recursive reads for the pair/list +elements are themselves in read-syntax mode, so that the +result is a list or pair of syntax objects that is itself wrapped as a +syntax object. If the reader constructs nested pairs because the input +included a single delimited ., then only the innermost pair +and outermost pair are wrapped as syntax objects.

Whether wrapping a pair or list, if the pair or list was formed with +[ and ], then a 'paren-shape +property is attached to the result with the value #\[. If the +read-square-bracket-with-tag parameter is set to +#t, then the resulting pair or list is wrapped by the +equivalent of (cons '#%brackets pair-or-list).

Similarly, if the list or pair was formed with { and +}, then a 'paren-shape property is attached to +the result with the value #\{. If the +read-curly-brace-with-tag parameter is set to +#t, then the resulting pair or list is wrapped by the +equivalent of (cons '#%braces pair-or-list).

If a delimited . appears in any other configuration, then +the exn:fail:read exception is raised. Similarly, if the reader encounters a +), ], or } that does not end a list +being parsed, then the exn:fail:read exception is raised.

Examples:

 ()

 reads equal to 

(list)

 (1 2 3)

 reads equal to 

(list 1 2 3)

 {1 2 3}

 reads equal to 

(list 1 2 3)

 [1 2 3]

 reads equal to 

(list 1 2 3)

 (1 (2) 3)

 reads equal to 

(list 1 (list 2) 3)

 (1 . 3)

 reads equal to 

(cons 1 3)

 (1 . (3))

 reads equal to 

(list 1 3)

 (1 . 2 . 3)

 reads equal to 

(list 2 1 3)

If the read-square-bracket-as-paren and +read-square-bracket-with-tag parameters are set to +#f, then when the reader encounters [ and +], the exn:fail:read exception is raised. Similarly, if the +read-curly-brace-as-paren and +read-curly-brace-with-tag parameters are set to +#f, then when the reader encounters { and +}, the exn:fail:read exception is raised.

If the read-accept-dot parameter is set to +#f, then a delimited . triggers an +exn:fail:read exception. If the +read-accept-infix-dot parameter is set to #f, +then multiple delimited .s trigger an exn:fail:read +exception, instead of the infix conversion.

1.3.7 Reading Strings

+Strings (Unicode) in The Racket Guide introduces the syntax of strings.

When the reader encounters ", it begins parsing +characters to form a string. The string continues until it is +terminated by another " (that is not escaped by +\). The resulting string is interned in +read-syntax mode.

Within a string sequence, the following escape sequences are + recognized:

  • \a: alarm (ASCII 7)

  • \b: backspace (ASCII 8)

  • \t: tab (ASCII 9)

  • \n: linefeed (ASCII 10)

  • \v: vertical tab (ASCII 11)

  • \f: formfeed (ASCII 12)

  • \r: return (ASCII 13)

  • \e: escape (ASCII 27)

  • \": double-quotes (without terminating the string)

  • \': quote (i.e., the backslash has no effect)

  • \\: backslash (i.e., the second is not an escaping backslash)

  • \digit8{1,3}: +Unicode for the octal number specified by digit8{1,3} (i.e., 1 to 3 digit8s), where +each digit8 is 0, 1, +2, 3, 4, 5, +6, or 7. A longer form takes precedence +over a shorter form, and the resulting octal number must be +between 0 and 255 decimal, otherwise the +exn:fail:read exception is raised.

  • \xdigit16{1,2}: Unicode for the hexadecimal +number specified by digit16{1,2}, +where each digit16 is 0, 1, +2, 3, 4, 5, +6, 7, 8, 9, +a, b, c, d, +e, or f (case-insensitive). The longer form +takes precedence over the shorter form.

  • \udigit16{1,4}: like \x, but with up to +four hexadecimal digits (longer sequences take precedence). +The resulting hexadecimal number must be a valid argument to +integer->char, otherwise the +exn:fail:read exception is raised—unless the encoding continues with +another \u to form a surrogate-style encoding.

  • \udigit16{4,4}\udigit16{4,4}: like \u, but for two +hexadecimal numbers, where the first is in the range +#xD800 to #xDBFF and the second is in the +range #xDC00 to #xDFFF; the resulting +character is the one represented by the numbers as a UTF-16 +surrogate pair.

  • \Udigit16{1,8}: like \x, but with up +to eight hexadecimal digits (longer sequences take precedence). +The resulting hexadecimal number must be a valid argument to +integer->char, otherwise the +exn:fail:read exception is raised.

  • \newline: elided, where +newline is either a linefeed, carriage return, or +carriage return–linefeed combination. This convention allows +single-line strings to span multiple lines in the source.

If the reader encounters any other use of a backslash in a string +constant, the exn:fail:read exception is raised.

+Bytes and Byte Strings in The Racket Guide introduces the syntax of byte strings.

A string constant preceded by # is parsed as a +byte string. (That is, #" starts a byte-string +literal.) See Byte Strings for information on byte +strings. The resulting byte string is interned in +read-syntax mode. +Byte-string constants support the same escape sequences as +character strings, except \u and \U. Otherwise, each +character within the byte-string quotes must have a Unicode code-point number +in the range 0 to 255, which is used as the corresponding byte’s value; if +a character is not in that range, the exn:fail:read exception is raised.

When the reader encounters #<<, it starts parsing a +here string. The characters following #<< until +a newline character define a terminator for the string. The content of +the string includes all characters between the #<< line and +a line whose only content is the specified terminator. More precisely, +the content of the string starts after a newline following +#<<, and it ends before a newline that is followed by the +terminator, where the terminator is itself followed by either a +newline or end-of-file. No escape sequences are recognized between the +starting and terminating lines; all characters are included in the +string (and terminator) literally. A return character is not treated +as a line separator in this context. If no characters appear between +#<< and a newline or end-of-file, or if an end-of-file is +encountered before a terminating line, the exn:fail:read exception is raised.

Examples:

 "Apple"

 reads equal to 

"Apple"

 "\x41pple"

 reads equal to 

"Apple"

 "\"Apple\""

 reads equal to 

"\x22Apple\x22"

 "\\"

 reads equal to 

"\x5C"

 #"Apple"

 reads equal to 

(bytes 65 112 112 108 101)

1.3.8 Reading Quotes

When the reader encounters ', it recursively +reads one datum and forms a new list containing the symbol +'quote and the following datum. This convention is mainly +useful for reading Racket code, where 's can be used as a +shorthand for (quote s).

Several other sequences are recognized and transformed in a similar +way. Longer prefixes take precedence over short ones:

 

'

 adds 

quote

 

`

 adds 

quasiquote

 

,

 adds 

unquote

 

,@

 adds 

unquote-splicing

 

#'

 adds 

syntax

 

#`

 adds 

quasisyntax

 

#,

 adds 

unsyntax

 

#,@

 adds 

unsyntax-splicing

Examples:

 'apple

 reads equal to 

(list 'quote 'apple)

 `(1 ,2)

 reads equal to 

(list 'quasiquote (list 1 (list 'unquote 2)))

The `, ,, and ,@ forms are disabled when +the read-accept-quasiquote parameter is set to +#f, in which case the exn:fail:read exception is raised instead.

1.3.9 Reading Comments

A ; starts a line comment. When the reader +encounters ;, it skips past all characters until the +next linefeed (ASCII 10), carriage return (ASCII 13), next-line +(Unicode 133), line-separator (Unicode 8232), +or paragraph-separator (Unicode 8233) character.

A #| starts a nestable block comment. When the +reader encounters #|, it skips past all characters +until a closing |#. Pairs of matching #| and +|# can be nested.

A #; starts an S-expression comment. When the +reader encounters #;, it recursively reads one datum, and +then discards it (continuing on to the next datum for the read +result).

A #!  (which is #! followed by a space) +or #!/ starts a line comment that can be +continued to the next line by ending a line with \. This +form of comment normally appears at the beginning of a Unix script +file.

Examples:

 ; comment

 reads equal to 

nothing

 #| a |# 1

 reads equal to 

1

 #| #| a |# 1 |# 2

 reads equal to 

2

 #;1 2

 reads equal to 

2

 #!/bin/sh

 reads equal to 

nothing

 #! /bin/sh

 reads equal to 

nothing

1.3.10 Reading Vectors

When the reader encounters a #(, #[, or +#{, it starts parsing a vector; see Vectors for +information on vectors. A #fl in place of # +starts an flvector, but is not allowed in read-syntax mode; +see Flonum Vectors for information on flvectors. +A #fx in place of # +starts an fxvector, but is not allowed in read-syntax mode; +see Fixnum Vectors for information on fxvectors. +The #[, #{, #fl[, #fl{, +#fx[, and #fx{ forms can be disabled through +the read-square-bracket-as-paren and +read-curly-brace-as-paren parameters.

The elements of the vector are recursively read until a matching +), ], or } is found, just as for +lists (see Reading Pairs and Lists). A delimited . is not +allowed among the vector elements. In the case of flvectors, +the recursive read for element is implicitly prefixed with #i +and must produce a flonum. In the case of fxvectors, +the recursive read for element is implicitly prefixed with #e +and must produce a fixnum.

An optional vector length can be specified between #, #fl, #fx and +(, [, or {. The size is specified +using a sequence of decimal digits, and the number of elements +provided for the vector must be no more than the specified size. If +fewer elements are provided, the last provided element is used for the +remaining vector slots; if no elements are provided, then 0 +is used for all slots.

In read-syntax mode, each recursive read for vector +elements is also in read-syntax mode, so that the wrapped +vector’s elements are also wrapped as syntax objects, and the vector is +immutable.

Examples:

 #(1 apple 3)

 reads equal to 

(vector 1 'apple 3)

 #3("apple" "banana")

 reads equal to 

(vector "apple" "banana" "banana")

 #3()

 reads equal to 

(vector 0 0 0)

1.3.11 Reading Structures

When the reader encounters a #s(, #s[, or +#s{, it starts parsing an instance of a prefab +structure type; see Structures for information on +structure types. The #s[ and #s{ forms +can be disabled through the read-square-bracket-as-paren and +read-curly-brace-as-paren parameters.

The elements of the structure are recursively read until a matching +), ], or } is found, just as for lists +(see Reading Pairs and Lists). A single delimited . is not +allowed among the elements, but two .s can be used as in a +list for an infix conversion.

The first element is used as the structure descriptor, and it must +have the form (when quoted) of a possible argument to +make-prefab-struct; in the simplest case, it can be a +symbol. The remaining elements correspond to field values within the +structure.

In read-syntax mode, the structure type must not have any +mutable fields. The structure’s elements are read in +read-syntax mode, so that the wrapped structure’s elements +are also wrapped as syntax objects.

If the first structure element is not a valid prefab structure +type key, or if the number of provided fields is inconsistent with the +indicated prefab structure type, the exn:fail:read exception is raised.

1.3.12 Reading Hash Tables

A #hash starts an immutable hash-table constant +with key matching based on equal?. The characters after +hash must parse as a list of pairs (see +Reading Pairs and Lists) with a specific use of delimited .: +it must appear between the elements of each pair in the list and +nowhere in the sequence of list elements. The first element of each +pair is used as the key for a table entry, and the second element of +each pair is the associated value.

A #hashalw starts a hash table like +#hash, except that it constructs a hash table based on +equal-always? instead of equal?.

A #hasheq starts a hash table like +#hash, except that it constructs a hash table based on +eq? instead of equal?.

A #hasheqv starts a hash table like +#hash, except that it constructs a hash table based on +eqv? instead of equal?.

In all cases, the table is constructed by adding each mapping to the + hash table from left to right, so later mappings can hide earlier + mappings if the keys are equivalent.

Examples, where make-... stands for make-immutable-hash:

 #hash()

 reads equal to 

(make-... '())

 #hasheq()

 reads equal to 

(make-...eq '())

 #hash(("a" . 5))

 reads equal to 

(make-... '(("a" . 5)))

 #hasheq((a . 5) (b . 7))

 reads equal to 

(make-...eq '((b . 7) (a . 5)))

 #hasheq((a . 5) (a . 7))

 reads equal to 

(make-...eq '((a . 7)))

1.3.13 Reading Boxes

When the reader encounters a #&, it starts +parsing a box; see Boxes for information on boxes. The +content of the box is determined by recursively reading the next +datum.

In read-syntax mode, the recursive read for the box content +is also in read-syntax mode, so that the wrapped box’s +content is also wrapped as a syntax object, and the box is immutable.

Examples:

 #&17

 reads equal to 

(box 17)

1.3.14 Reading Characters

+Characters in The Racket Guide introduces the syntax of characters.

A #\ starts a character constant, which has +one of the following forms:

  • #\nul or #\null: NUL (ASCII 0); the next character must not be alphabetic.

  • #\backspace: backspace (ASCII 8); the next character must not be alphabetic.

  • #\tab: tab (ASCII 9); the next character must not be alphabetic.

  • #\newline or #\linefeed: linefeed (ASCII 10); the next character must not be alphabetic.

  • #\vtab: vertical tab (ASCII 11); the next character must not be alphabetic.

  • #\page: page break (ASCII 12); the next character must not be alphabetic.

  • #\return: carriage return (ASCII 13); the next character must not be alphabetic.

  • #\space: space (ASCII 32); the next character must not be alphabetic.

  • #\rubout: delete (ASCII 127); the next character must not be alphabetic.

  • #\digit8{3,3}: +Unicode for the octal number specified by three octal digits—as in string escapes (see +Reading Strings), but constrained to exactly three digits.

  • #\udigit16{1,4}: +Unicode for the hexadecimal number specified by digit16{1,4}, as in string escapes (see +Reading Strings).

  • #\Udigit16{1,8}: +like #\u, but with up to eight hexadecimal digits (although +only six digits are actually useful).

  • #\c: the character c, as long +as #\c and the characters following it +do not match any of the previous cases, as long as +c or the +character after c is not +alphabetic, and as long as +c is not an octal digit or is not followed by an +octal digit (i.e., two octal digits commit to a third).

Examples:

 #\newline

 reads equal to 

(integer->char 10)

 #\n

 reads equal to 

(integer->char 110)

 #\u3BB

 reads equal to 

(integer->char 955)

 #\λ

 reads equal to 

(integer->char 955)

1.3.15 Reading Keywords

A #: starts a keyword. The parsing of a keyword +after the #: is the same as for a symbol, including +case-folding in case-insensitive mode, except that the part after +#: is never parsed as a number. The resulting keyword is +interned.

Examples:

 #:Apple

 reads equal to 

(string->keyword "Apple")

 #:1

 reads equal to 

(string->keyword "1")

1.3.16 Reading Regular Expressions

A #rx or #px starts a +regular expression. The characters immediately after #rx or +#px must parse as a string or byte string (see +Reading Strings). A #rx prefix starts a regular +expression as would be constructed by regexp, #px +as constructed by pregexp, #rx# as constructed by +byte-regexp, and #px# as constructed by +byte-pregexp. The resulting regular expression is interned in +read-syntax mode.

Examples:

 #rx".*"

 reads equal to 

(regexp ".*")

 #px"[\\s]*"

 reads equal to 

(pregexp "[\\s]*")

 #rx#".*"

 reads equal to 

(byte-regexp #".*")

 #px#"[\\s]*"

 reads equal to 

(byte-pregexp #"[\\s]*")

1.3.17 Reading Graph Structure

A #digit10{1,8}= tags the following datum for reference via +#digit10{1,8}#, which allows the reader to produce a datum that +has graph structure.

In read mode, for a specific digit10{1,8} in a single read +result, each #digit10{1,8}# reference is replaced by the datum read for +the corresponding #digit10{1,8}=; the definition #digit10{1,8}= also +produces just the datum after it. A #digit10{1,8}= definition can appear +at most once, and a #digit10{1,8}= definition must appear before a +#digit10{1,8}# reference appears, otherwise the exn:fail:read exception is raised. +If the read-accept-graph parameter is set to #f, then +#digit10{1,8}= or #digit10{1,8}# triggers a exn:fail:read +exception.

In read-syntax mode, graph structure is parsed the same way +as in read mode. However, since syntax objects made +from plain S-expressions may not contain cycles, each #digit10{1,8}= +definition and #digit10{1,8}# reference is replaced with a +placeholder in the result that contains the referenced value. +Since such syntax objects are not directly useful (they cannot be +marshaled to compiled code and are therefore rejected by the default +compilation handler), parsing of graph structure in +read-syntax mode is controlled by the separate +read-syntax-accept-graph parameter, which is initially set +to #f.

Although a comment parsed via #; discards the datum +afterward, #digit10{1,8}= definitions in the discarded datum +still can be referenced by other parts of the reader input, as long as +both the comment and the reference are grouped together by some other +form (i.e., some recursive read); a top-level #; comment +neither defines nor uses graph tags for other top-level forms.

Examples:

 (#1=100 #1# #1#)

 reads equal to 

(list 100 100 100)

 #0=(1 . #0#)

 reads equal to 

(let* ([ph (make-placeholder #f)]
       [v (cons 1 ph)])
  (placeholder-set! ph v)
  (make-reader-graph v))

Changed in version 8.4.0.8 of package base: Added support for reading graph structure +in read-syntax mode if enabled by +read-syntax-accept-graph.

1.3.18 Reading via an Extension

+Reader Extensions in The Racket Guide introduces reader extension.

When the reader encounters #reader, it loads +an external reader procedure and applies it to the current input +stream.

The reader recursively reads the next datum after #reader, +and passes it to the procedure that is the value of the +current-reader-guard parameter; the result is used as a +module path. The module path is passed to dynamic-require +with either 'read or 'read-syntax (depending on +whether the reader is in read or read-syntax +mode) while holding the registry lock via +namespace-call-with-registry-lock. +The module is loaded in a root namespace of the +current namespace.

The arity of the resulting procedure determines whether it accepts +extra source-location information: a read procedure +accepts either one argument (an input port) or five, and a +read-syntax procedure accepts either two arguments (a +name value and an input port) or six. In either case, the four +optional arguments are the reader’s module path (as a syntax object in +read-syntax mode) followed by the line (positive exact +integer or #f), column (non-negative exact integer or +#f), and position (positive exact integer or #f) of +the start of the #reader form. The input port is the one +whose stream contained #reader, where the stream position is +immediately after the recursively read module path.

The procedure should produce a datum result. If the result is a +syntax object in read mode, then it is converted to a datum +using syntax->datum; if the result is not a syntax object in +read-syntax mode, then it is converted to one using +datum->syntax. See also Reader-Extension Procedures for +information on the procedure’s results.

If the read-accept-reader parameter is set to +#f, then if the reader encounters #reader, the +exn:fail:read exception is raised.

+The #lang Shorthand in The Racket Guide introduces #lang.

The #lang reader form is similar to +#reader, but more constrained: the #lang must be +followed by a single space (ASCII 32), and then a non-empty sequence +of alphanumeric ASCII, +, -, _, and/or +/ characters terminated by +whitespace or an end-of-file. The +sequence must not start or end with /. A sequence +#lang name is equivalent to either +#reader (submod name reader) or +#reader name/lang/reader, where the +former is tried first guarded by a module-declared? +check (but after filtering by +current-reader-guard, so both are passed to the +value of current-reader-guard if the latter is used). Note +that the terminating whitespace (if any) is not consumed before the +external reading procedure is called.

+Defining new #lang Languages in The Racket Guide introduces the creation languages for #lang.

Finally, #! is an alias for #lang +followed by a space when #! is followed by alphanumeric +ASCII, +, -, or _. Use of this alias +is discouraged except as needed to construct programs that conform to +certain grammars, such as that of R6RS +[Sperber07].

The syntax/module-reader library provides a +domain-specific language for writing language readers.

By convention, #lang normally appears at the beginning of a +file, possibly after comment forms, to specify the syntax of a module.

If the read-accept-reader or read-accept-lang +parameter is set to #f, then if the reader encounters +#lang or equivalent #!, the exn:fail:read exception is raised.

Changed in version 8.2.0.2 of package base: Changed reader-module loading for #reader +and #lang to hold the current namespace +registry’s lock.

1.3.19 Reading with C-style Infix-Dot Notation

When the read-cdot parameter is set to #t, +then a variety of changes occur in the reader.

First, symbols can no longer include the character ., unless +the . is quoted with | or \.

Second, numbers can no longer include the character ., +unless the number is prefixed with #e, #i, +#b, #o, #d, #x, or an +equivalent prefix as discussed in Reading Numbers. If these +numbers are followed by a . intended to be read as a C-style +infix dot, then a delimiter must precede the ..

Finally, after reading any datum x, the reader will consume +whitespace, BOM characters, and comments to look for zero or more sequences of a +. followed by another datum y. It will then group +x and y with '#%dot so that +x.y reads equal to reading (#%dot x y).

If x.y has another . after it, the reader will +accumulate more .-separated datums, grouping them from +left-to-right. For example, x.y.z reads equal to reading +(#%dot (#%dot x y) z).

In read-syntax mode, the '#%dot symbol has the +source location information of the . character and the +entire list has the source location information spanning from the +start of x to the end of y.

1.3.19.1 S-Expression Reader Language

 #lang s-exp package: base

+Using #lang s-exp in The Racket Guide introduces the s-exp meta-language.

The s-exp “language” is a kind of meta-language. It +reads the S-expression that follows #lang s-exp and +uses it as the language of a module form. It also reads all +remaining S-expressions until an end-of-file, using them for the body +of the generated module.

That is,

#lang s-exp module-path
form ...

is equivalent to

(module name-id module-path
  form ...)

where name-id is derived from the source input port’s name: +if the port name is a filename path, the filename without its +directory path and extension is used for name-id, otherwise +name-id is anonymous-module.

1.3.19.2 Chaining Reader Language

 #lang reader package: base

+Using #lang reader in The Racket Guide introduces the reader meta-language.

The reader “language” is a kind of meta-language. It +reads the S-expression that follows #lang reader +and uses it as a module path (relative to the module being read) that +effectively takes the place of reader. In other words, +the reader meta-language generalizes the syntax of the +module specified after #lang to be a module path, and without +the implicit addition of /lang/reader to the path.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/readtables.html b/clones/docs.racket-lang.org/reference/readtables.html new file mode 100644 index 00000000..545a6114 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/readtables.html @@ -0,0 +1,97 @@ + +13.7.1 Readtables
13.7.1 Readtables

The dispatch table in Delimiters and Dispatch +corresponds to the default readtable. By creating a new +readtable and installing it via the current-readtable +parameter, the reader’s behavior can be extended.

A readtable is consulted at specific times by the reader:

  • when looking for the start of a datum;

  • when determining how to parse a datum that starts with +#;

  • when looking for a delimiter to terminate a symbol or number;

  • when looking for an opener (such as (), closer (such +as )), or . after the first character parsed as +a sequence for a pair, list, vector, or hash table; or

  • when looking for an opener after #n in a +vector of specified length n.

The readtable is ignored at other times. In particular, after parsing +a character that is mapped to the default behavior of ;, the +readtable is ignored until the comment’s terminating newline is +discovered. Similarly, the readtable does not affect string parsing +until a closing double-quote is found. Meanwhile, if a character is +mapped to the default behavior of (, then it starts sequence +that is closed by any character that is mapped to a closing parenthesis +). An apparent exception is that the default parsing of +| quotes a symbol until a matching character is found, but +the parser is simply using the character that started the quote; it +does not consult the readtable.

For many contexts, #f identifies the default readtable. In +particular, #f is the initial value for the +current-readtable parameter, which causes the reader to +behave as described in The Reader.

procedure

(readtable? v)  boolean?

  v : any/c
Returns #t if v is a readtable, #f +otherwise.

procedure

(make-readtable readtable key mode action ...)  readtable?

  readtable : (or/c readtable? #f)
  key : (or/c char? #f)
  mode : 
(or/c 'terminating-macro
      'non-terminating-macro
      'dispatch-macro
      char?)
  action : 
(or/c procedure?
      readtable?
      #f)
Creates a new readtable that is like readtable (which can be +#f to indicate the default readtable), +except that the reader’s behavior is modified for each +key according to the given mode and +action. The ... for make-readtable applies +to all three of key, mode, and action; in +other words, the total number of arguments to make-readtable +must be 1 modulo 3.

The possible combinations for key, mode, and +action are as follows:

  • char 'terminating-macro proc causes +char to be parsed as a delimiter, and an +unquoted/uncommented char in the input string triggers a +call to the reader macro proc; the activity of +proc is described further below. Conceptually, characters +like ;, (, and ) are mapped to +terminating reader macros in the default readtable.

  • char 'non-terminating-macro proc like +the 'terminating-macro variant, but char is not +treated as a delimiter, so it can be used in the middle of an +identifier or number. Conceptually, # is mapped to a +non-terminating macro in the default readtable.

  • char 'dispatch-macro proc like the +'non-terminating-macro variant, but for char only +when it follows a # (or, more precisely, when the character +follows one that has been mapped to the behavior of # +in the default readtable).

  • char like-char readtable causes +char to be parsed in the same way that like-char +is parsed in readtable, where readtable can be +#f to indicate the default readtable. (The mapping of +char does not apply after #, which is configured +separately via 'dispatch-macro.) Mapping a character to +the same actions as | in the default reader means that the +character starts quoting for symbols, and the same character +terminates the quote; in contrast, mapping a character to the same +action as a " means that the character starts a string, but +the string is still terminated with a closing ". Finally, +mapping a character to an action in the default readtable means that +the character’s behavior is sensitive to parameters that affect the +original character; for example, mapping a character to the same +action as a curly brace { in the default readtable means +that the character is disallowed when the +read-curly-brace-as-paren parameter is set to #f.

  • #f 'non-terminating-macro proc +replaces the macro used to parse characters with no specific mapping: +i.e., the characters (other than # or |) that can +start a symbol or number with the default readtable.

If multiple 'dispatch-macro mappings are provided for a +single char, all but the last one are ignored. Similarly, if +multiple non-'dispatch-macro mappings are provided for a +single char, all but the last one are ignored.

A reader macro proc must accept six arguments, and it can +optionally accept two arguments. The first two arguments are always +the character that triggered the reader macro and the input port for +reading. When the reader macro is triggered by read-syntax +(or read-syntax/recursive), the procedure is passed four +additional arguments that represent a source location for +already-consumed character(s): the source name, a line number or +#f, a column number or #f, and a position or +#f. When the reader macro is triggered by read (or +read/recursive), the procedure is passed only two arguments +if it accepts two arguments, otherwise it is passed six arguments +where the third is always #f. See Reader-Extension Procedures +for information on the procedure’s results.

A reader macro normally reads characters from the given input port to +produce a value to be used as the “reader macro-expansion” of the +consumed characters. The reader macro might produce a special-comment +value (see Special Comments) to cause the consumed +character to be treated as whitespace, and it might use +read/recursive or read-syntax/recursive.

procedure

(readtable-mapping readtable char)

  
(or/c char?
      'terminating-macro
      'non-terminating-macro)
(or/c #f procedure?)
(or/c #f procedure?)
  readtable : readtable?
  char : char?
Produces information about the mappings in readtable for +char. The result is three values:

  • either a character (mapping to the same behavior as the +character in the default readtable), 'terminating-macro, or +'non-terminating-macro; this result reports the main (i.e., +non-'dispatch-macro) mapping for char. When the result +is a character, then char is mapped to the same behavior as the +returned character in the default readtable.

  • either #f or a reader-macro procedure; the result is a +procedure when the first result is 'terminating-macro or +'non-terminating-macro.

  • either #f or a reader-macro procedure; the result is a +procedure when the character has a 'dispatch-macro mapping in +readtable to override the default dispatch behavior.

Note that reader-macro procedures for the default readtable are not +directly accessible. To invoke default behaviors, use +read/recursive or read-syntax/recursive with a +character and the #f readtable.

Examples:
; Provides raise-read-error and raise-read-eof-error
> (require syntax/readerr)
> (define (skip-whitespace port)
    ; Skips whitespace characters, sensitive to the current
    ; readtable's definition of whitespace
    (let ([ch (peek-char port)])
      (unless (eof-object? ch)
        ; Consult current readtable:
        (let-values ([(like-ch/sym proc dispatch-proc)
                      (readtable-mapping (current-readtable) ch)])
          ; If like-ch/sym is whitespace, then ch is whitespace
          (when (and (char? like-ch/sym)
                     (char-whitespace? like-ch/sym))
            (read-char port)
            (skip-whitespace port))))))
> (define (skip-comments read-one port src)
    ; Recursive read, but skip comments and detect EOF
    (let loop ()
      (let ([v (read-one)])
        (cond
         [(special-comment? v) (loop)]
         [(eof-object? v)
          (let-values ([(l c p) (port-next-location port)])
            (raise-read-eof-error
             "unexpected EOF in tuple" src l c p 1))]
         [else v]))))
> (define (parse port read-one src)
    ; First, check for empty tuple
    (skip-whitespace port)
    (if (eq? #\> (peek-char port))
        null
        (let ([elem (read-one)])
          (if (special-comment? elem)
              ; Found a comment, so look for > again
              (parse port read-one src)
              ; Non-empty tuple:
              (cons elem
                    (parse-nonempty port read-one src))))))
> (define (parse-nonempty port read-one src)
    ; Need a comma or closer
    (skip-whitespace port)
    (case (peek-char port)
      [(#\>) (read-char port)
       ; Done
       null]
      [(#\,) (read-char port)
       ; Read next element and recur
       (cons (skip-comments read-one port src)
             (parse-nonempty port read-one src))]
      [else
       ; Either a comment or an error; grab location (in case
       ; of error) and read recursively to detect comments
       (let-values ([(l c p) (port-next-location port)]
                    [(v) (read-one)])
         (cond
          [(special-comment? v)
           ; It was a comment, so try again
           (parse-nonempty port read-one src)]
          [else
           ; Wasn't a comment, comma, or closer; error
           ((if (eof-object? v)
                raise-read-eof-error
                raise-read-error)
            "expected `,` or `>`" src l c p 1)]))]))
> (define (make-delims-table)
    ; Table to use for recursive reads to disallow delimiters
    ;  (except those in sub-expressions)
    (letrec ([misplaced-delimiter
              (case-lambda
               [(ch port) (misplaced-delimiter ch port #f #f #f #f)]
               [(ch port src line col pos)
                (raise-read-error
                 (format "misplaced `~a` in tuple" ch)
                 src line col pos 1)])])
      (make-readtable (current-readtable)
                      #\, 'terminating-macro misplaced-delimiter
                      #\> 'terminating-macro misplaced-delimiter)))
> (define (wrap l)
    `(make-tuple (list ,@l)))
> (define parse-open-tuple
    (case-lambda
     [(ch port)
      ; read mode
      (wrap (parse port
                   (lambda ()
                     (read/recursive port #f
                                     (make-delims-table)))
                   (object-name port)))]
     [(ch port src line col pos)
      ; read-syntax mode
      (datum->syntax
       #f
       (wrap (parse port
                    (lambda ()
                      (read-syntax/recursive src port #f
                                             (make-delims-table)))
                    src))
       (let-values ([(l c p) (port-next-location port)])
         (list src line col pos (and pos (- p pos)))))]))
> (define tuple-readtable
    (make-readtable #f #\< 'terminating-macro parse-open-tuple))
> (parameterize ([current-readtable tuple-readtable])
    (read (open-input-string "<1 , 2 , \"a\">")))

'(make-tuple (list 1 2 "a"))

> (parameterize ([current-readtable tuple-readtable])
    (read (open-input-string
           "< #||# 1 #||# , #||# 2 #||# , #||# \"a\" #||# >")))

'(make-tuple (list 1 2 "a"))

> (define tuple-readtable+
    (make-readtable tuple-readtable
                    #\* 'terminating-macro (lambda a
                                             (make-special-comment #f))
                    #\_ #\space #f))
> (parameterize ([current-readtable tuple-readtable+])
    (read (open-input-string "< * 1 __,__  2 __,__ * \"a\" * >")))

'(make-tuple (list 1 2 "a"))

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/regexp.html b/clones/docs.racket-lang.org/reference/regexp.html new file mode 100644 index 00000000..34567e2e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/regexp.html @@ -0,0 +1,329 @@ + +4.8 Regular Expressions

4.8 Regular Expressions

+Regular Expressions in The Racket Guide introduces regular expressions.

Regular expressions are specified as strings or byte +strings, using the same pattern language as either the Unix utility +egrep or Perl. A string-specified pattern produces a character +regexp matcher, and a byte-string pattern produces a byte regexp +matcher. If a character regexp is used with a byte string or input +port, it matches UTF-8 encodings (see Encodings and Locales) of +matching character streams; if a byte regexp is used with a character +string, it matches bytes in the UTF-8 encoding of the string.

A regular expression that is represented as a string or byte string +can be compiled to a regexp value, which can be used more +efficiently by functions such as regexp-match compared to the +string or byte string form. The regexp and +byte-regexp procedures convert a string or byte string +(respectively) into a regexp value using a syntax of regular +expressions that is most compatible to egrep. The +pregexp and byte-pregexp procedures produce a regexp +value using a slightly different syntax of regular expressions that is +more compatible with Perl.

Two regexp values are equal? if they have the same +source, use the same pattern language, and are both character regexps +or both byte regexps.

A literal or printed regexp value starts with #rx or +#px. See Reading Regular Expressions + for information on reading + regular expressions and Printing Regular Expressions + for information on printing regular expressions. Regexp +values produced by the default reader are interned in +read-syntax mode.

On the BC variant of Racket, +the internal size of a regexp value is limited to 32 kilobytes; this +limit roughly corresponds to a source string with 32,000 literal +characters or 5,000 operators.

4.8.1 Regexp Syntax

The following syntax specifications describe the content of a string +that represents a regular expression. The syntax of the corresponding +string may involve extra escape characters. For example, the regular +expression (.*)\1 can be represented with the string +"(.*)\\1" or the regexp constant #rx"(.*)\\1"; the +\ in the regular expression must be escaped to include it +in a string or regexp constant.

The regexp and pregexp syntaxes share a common core:

 

regexp

 ::= 

pces

 

Match pces

 

 

|

regexp|regexp

 

Match either regexp, try left first

 ex1

 

pces

 ::= 

 

Match empty

 

 

|

pcepces

 

Match pce followed by pces

 

pce

 ::= 

repeat

 

Match repeat, longest possible

 ex3

 

 

|

repeat?

 

Match repeat, shortest possible

 ex6

 

 

|

atom

 

Match atom exactly once

 

repeat

 ::= 

atom*

 

Match atom 0 or more times

 ex3

 

 

|

atom+

 

Match atom 1 or more times

 ex4

 

 

|

atom?

 

Match atom 0 or 1 times

 ex5

 

atom

 ::= 

(regexp)

 

Match sub-expression regexp and report

 ex11

 

 

|

[rng]

 

Match any character in rng

 ex2

 

 

|

[^rng]

 

Match any character not in rng

 ex12

 

 

|

.

 

Match any (except newline in multi mode)

 ex13

 

 

|

^

 

Match start (or after newline in multi mode)

 ex14

 

 

|

$

 

Match end (or before newline in multi mode)

 ex15

 

 

|

literal

 

Match a single literal character

 ex1

 

 

|

(?mode:regexp)

 

Match regexp using mode

 ex35

 

 

|

(?>regexp)

 

Match regexp, only first possible

 

 

|

look

 

Match empty if look matches

 

 

|

(?tstpces|pces)

 

Match 1st pces if tst, else 2nd pces

 ex36

 

 

|

(?tstpces)

 

Match pces if tst, empty if not tst

 

 

|

\ at end of pattern

 

Match the nul character (ASCII 0)

 

rng

 ::= 

]

 

rng contains ] only

 ex27

 

 

|

-

 

rng contains - only

 ex28

 

 

|

mrng

 

rng contains everything in mrng

 

 

|

mrng-

 

rng contains - and everything in mrng

 

mrng

 ::= 

]lrng

 

mrng contains ] and everything in lrng

 ex29

 

 

|

-lrng

 

mrng contains - and everything in lrng

 ex29

 

 

|

lirng

 

mrng contains everything in lirng

 

lirng

 ::= 

riliteral

 

lirng contains a literal character

 

 

|

riliteral-rliteral

 

lirng contains Unicode range inclusive

 ex22

 

 

|

lirnglrng

 

lirng contains everything in both

 

lrng

 ::= 

^

 

lrng contains ^

 ex30

 

 

|

rliteral-rliteral

 

lrng contains Unicode range inclusive

 

 

|

^lrng

 

lrng contains ^ and more

 

 

|

lirng

 

lrng contains everything in lirng

 

look

 ::= 

(?=regexp)

 

Match if regexp matches

 ex31

 

 

|

(?!regexp)

 

Match if regexp doesn't match

 ex32

 

 

|

(?<=regexp)

 

Match if regexp matches preceding

 ex33

 

 

|

(?<!regexp)

 

Match if regexp doesn't match preceding

 ex34

 

tst

 ::= 

(n)

 

True if nth ( has a match

 

 

|

look

 

True if look matches

 ex36

 

mode

 ::= 

 

Like the enclosing mode

 

 

|

modei

 

Like mode, but case-insensitive

 ex35

 

 

|

mode-i

 

Like mode, but sensitive

 

 

|

modes

 

Like mode, but not in multi mode

 

 

|

mode-s

 

Like mode, but in multi mode

 

 

|

modem

 

Like mode, but in multi mode

 

 

|

mode-m

 

Like mode, but not in multi mode

The following completes the grammar for regexp, which treats +{ and } as literals, \ as a +literal within ranges, and \ as a literal producer +outside of ranges.

 

literal

 ::= 

Any character except (, ), *, +, ?, [, ., ^, \, or |

 

 

|

\aliteral

 

Match aliteral

 ex21

 

aliteral

 ::= 

Any character

 

riliteral

 ::= 

Any character except ], -, or ^

 

rliteral

 ::= 

Any character except ] or -

The following completes the grammar for pregexp, which uses +{ and } bounded repetition and uses +\ for meta-characters both inside and outside of ranges.

 

repeat

 ::= 

...

 

...

 

 

|

atom{n}

 

Match atom exactly n times

 ex7

 

 

|

atom{n,}

 

Match atom n or more times

 ex8

 

 

|

atom{,m}

 

Match atom between 0 and m times

 ex9

 

 

|

atom{n,m}

 

Match atom between n and m times

 ex10

 

 

|

atom{}

 

Match atom 0 or more times

 

atom

 ::= 

...

 

...

 

 

|

\n

 

Match latest reported match for nth (

 ex16

 

 

|

class

 

Match any character in class

 

 

|

\b

 

Match \w* boundary

 ex17

 

 

|

\B

 

Match where \b does not

 ex18

 

 

|

\p{property}

 

Match (UTF-8 encoded) in property

 ex19

 

 

|

\P{property}

 

Match (UTF-8 encoded) not in property

 ex20

 

literal

 ::= 

Any character except (, ), *, +, ?, [, ], {, }, ., ^, \, or |

 

 

|

\aliteral

 

Match aliteral

 ex21

 

aliteral

 ::= 

Any character except a-z, A-Z, 0-9

 

lirng

 ::= 

...

 

...

 

 

|

class

 

lirng contains all characters in class

 

 

|

posix

 

lirng contains all characters in posix

 ex26

 

 

|

\eliteral

 

lirng contains eliteral

 

riliteral

 ::= 

Any character except ], \, -, or ^

 

rliteral

 ::= 

Any character except ], \, or -

 

eliteral

 ::= 

Any character except a-z, A-Z

 

class

 ::= 

\d

 

Contains 0-9

 ex23

 

 

|

\D

 

Contains characters not in \d

 

 

|

\w

 

Contains a-z, A-Z, 0-9, _

 ex24

 

 

|

\W

 

Contains characters not in \w

 

 

|

\s

 

Contains space, tab, newline, formfeed, return

 ex25

 

 

|

\S

 

Contains characters not in \s

 

posix

 ::= 

[:alpha:]

 

Contains a-z, A-Z

 

 

|

[:upper:]

 

Contains A-Z

 

 

|

[:lower:]

 

Contains a-z

 ex26

 

 

|

[:digit:]

 

Contains 0-9

 

 

|

[:xdigit:]

 

Contains 0-9, a-f, A-F

 

 

|

[:alnum:]

 

Contains a-z, A-Z, 0-9

 

 

|

[:word:]

 

Contains a-z, A-Z, 0-9, _

 

 

|

[:blank:]

 

Contains space and tab

 

 

|

[:space:]

 

Contains space, tab, newline, formfeed, return

 

 

|

[:graph:]

 

Contains all ASCII characters that use ink

 

 

|

[:print:]

 

Contains space, tab, and ASCII ink users

 

 

|

[:cntrl:]

 

Contains all characters with scalar value < 32

 

 

|

[:ascii:]

 

Contains all ASCII characters

 

property

 ::= 

category

 

Includes all characters in category

 

 

|

^category

 

Includes all characters not in category

In case-insensitive mode, a backreference of the form +\n matches case-insensitively only with respect to +ASCII characters.

The Unicode categories follow.

 

category

 ::= 

Ll

 

Letter, lowercase

 ex19

 

 

|

Lu

 

Letter, uppercase

 

 

|

Lt

 

Letter, titlecase

 

 

|

Lm

 

Letter, modifier

 

 

|

L&

 

Union of Ll, Lu, Lt, and Lm

 

 

|

Lo

 

Letter, other

 

 

|

L

 

Union of L& and Lo

 

 

|

Nd

 

Number, decimal digit

 

 

|

Nl

 

Number, letter

 

 

|

No

 

Number, other

 

 

|

N

 

Union of Nd, Nl, and No

 

 

|

Ps

 

Punctuation, open

 

 

|

Pe

 

Punctuation, close

 

 

|

Pi

 

Punctuation, initial quote

 

 

|

Pf

 

Punctuation, final quote

 

 

|

Pc

 

Punctuation, connector

 

 

|

Pd

 

Punctuation, dash

 

 

|

Po

 

Punctuation, other

 

 

|

P

 

Union of Ps, Pe, Pi, Pf, Pc, Pd, and Po

 

 

|

Mn

 

Mark, non-spacing

 

 

|

Mc

 

Mark, spacing combining

 

 

|

Me

 

Mark, enclosing

 

 

|

M

 

Union of Mn, Mc, and Me

 

 

|

Sc

 

Symbol, currency

 

 

|

Sk

 

Symbol, modifier

 

 

|

Sm

 

Symbol, math

 

 

|

So

 

Symbol, other

 

 

|

S

 

Union of Sc, Sk, Sm, and So

 

 

|

Zl

 

Separator, line

 

 

|

Zp

 

Separator, paragraph

 

 

|

Zs

 

Separator, space

 

 

|

Z

 

Union of Zl, Zp, and Zs

 

 

|

Cc

 

Other, control

 

 

|

Cf

 

Other, format

 

 

|

Cs

 

Other, surrogate

 

 

|

Cn

 

Other, not assigned

 

 

|

Co

 

Other, private use

 

 

|

C

 

Union of Cc, Cf, Cs, Cn, and Co

 

 

|

.

 

Union of all Unicode categories

Examples:
> (regexp-match #rx"a|b" "cat") ; ex1

'("a")

> (regexp-match #rx"[at]" "cat") ; ex2

'("a")

> (regexp-match #rx"ca*[at]" "caaat") ; ex3

'("caaat")

> (regexp-match #rx"ca+[at]" "caaat") ; ex4

'("caaat")

> (regexp-match #rx"ca?t?" "ct") ; ex5

'("ct")

> (regexp-match #rx"ca*?[at]" "caaat") ; ex6

'("ca")

> (regexp-match #px"ca{2}" "caaat") ; ex7, uses #px

'("caa")

> (regexp-match #px"ca{2,}t" "catcaat") ; ex8, uses #px

'("caat")

> (regexp-match #px"ca{,2}t" "caaatcat") ; ex9, uses #px

'("cat")

> (regexp-match #px"ca{1,2}t" "caaatcat") ; ex10, uses #px

'("cat")

> (regexp-match #rx"(c*)(a*)" "caat") ; ex11

'("caa" "c" "aa")

> (regexp-match #rx"[^ca]" "caat") ; ex12

'("t")

> (regexp-match #rx".(.)." "cat") ; ex13

'("cat" "a")

> (regexp-match #rx"^a|^c" "cat") ; ex14

'("c")

> (regexp-match #rx"a$|t$" "cat") ; ex15

'("t")

> (regexp-match #px"c(.)\\1t" "caat") ; ex16, uses #px

'("caat" "a")

> (regexp-match #px".\\b." "cat in hat") ; ex17, uses #px

'("t ")

> (regexp-match #px".\\B." "cat in hat") ; ex18, uses #px

'("ca")

> (regexp-match #px"\\p{Ll}" "Cat") ; ex19, uses #px

'("a")

> (regexp-match #px"\\P{Ll}" "cat!") ; ex20, uses #px

'("!")

> (regexp-match #rx"\\|" "c|t") ; ex21

'("|")

> (regexp-match #rx"[a-f]*" "cat") ; ex22

'("ca")

> (regexp-match #px"[a-f\\d]*" "1cat") ; ex23, uses #px

'("1ca")

> (regexp-match #px" [\\w]" "cat hat") ; ex24, uses #px

'(" h")

> (regexp-match #px"t[\\s]" "cat\nhat") ; ex25, uses #px

'("t\n")

> (regexp-match #px"[[:lower:]]+" "Cat") ; ex26, uses #px

'("at")

> (regexp-match #rx"[]]" "c]t") ; ex27

'("]")

> (regexp-match #rx"[-]" "c-t") ; ex28

'("-")

> (regexp-match #rx"[]a[]+" "c[a]t") ; ex29

'("[a]")

> (regexp-match #rx"[a^]+" "ca^t") ; ex30

'("a^")

> (regexp-match #rx".a(?=p)" "cat nap") ; ex31

'("na")

> (regexp-match #rx".a(?!t)" "cat nap") ; ex32

'("na")

> (regexp-match #rx"(?<=n)a." "cat nap") ; ex33

'("ap")

> (regexp-match #rx"(?<!c)a." "cat nap") ; ex34

'("ap")

> (regexp-match #rx"(?i:a)[tp]" "cAT nAp") ; ex35

'("Ap")

> (regexp-match #rx"(?(?<=c)a|b)+" "cabal") ; ex36

'("ab")

4.8.2 Additional Syntactic Constraints

In addition to matching a grammar, regular expressions must meet two +syntactic restrictions:

  • In a repeat other than atom?, +the atom must not match an empty sequence.

  • In a (?<=regexp) or +(?<!regexp), +the regexp must match a bounded sequence only.

These constraints are checked syntactically by the following type +system. A type [n, m] corresponds to an expression that +matches between n and m characters. In the rule for +(Regexp), N means the number such +that the opening parenthesis is the Nth opening parenthesis for +collecting match reports. Non-emptiness is inferred for a +backreference pattern, \N, so that a +backreference can be used for repetition patterns; in the case of +mutual dependencies among backreferences, the inference chooses the +fixpoint that maximizes non-emptiness. Finiteness is not inferred for +backreferences (i.e., a backreference is assumed to match an +arbitrarily large sequence). No syntactic constraint prohibits a +backreference within the group that it references, although such self +references might create a pattern with no possible matches (as in the +case of (.\1), although (^.|\1){2} matches an +input that starts with the same two characters).

 regexp1 : [n1, m1]   regexp2 : [n2, m2] 

 regexp1|regexp2 : [min(n1, n2), max(m1, m2)] 

 

 pce : [n1, m1]   pces : [n2, m2] 

 pcepces : [n1+n2, m1+m2] 

 

 repeat : [n, m] 

 repeat? : [0, m] 

   

 atom : [n, m]   n > 0 

 atom* : [0, ∞] 

 

 atom : [n, m]   n > 0 

 atom+ : [1, ∞] 

   

 atom : [n, m] 

 atom? : [0, m] 

 

 atom : [n, m]   n > 0 

 atom{n} : [n*n, m*n] 

 

 atom : [n, m]   n > 0 

 atom{n,} : [n*n, ∞] 

 

 atom : [n, m]   n > 0 

 atom{,m} : [0, m*m] 

 

 atom : [n, m]   n > 0 

 atom{n,m} : [n*n, m*m] 

 

 regexp : [n, m] 

 (regexp) : [n, m]   αN=n 

 

 regexp : [n, m] 

 (?mode:regexp) : [n, m] 

 

 regexp : [n, m] 

 (?=regexp) : [0, 0] 

   

 regexp : [n, m] 

 (?!regexp) : [0, 0] 

 

 regexp : [n, m]   m < ∞ 

 (?<=regexp) : [0, 0] 

   

 regexp : [n, m]   m < ∞ 

 (?<!regexp) : [0, 0] 

 

 regexp : [n, m] 

 (?>regexp) : [n, m] 

 

 tst : [n0, m0]   pces1 : [n1, m1]   pces2 : [n2, m2] 

 (?tstpces1|pces2) : [min(n1, n2), max(m1, m2)] 

 

 tst : [n0, m0]   pces : [n1, m1] 

 (?tstpces) : [0, m1] 

 

(n) : N, ∞]

   

[rng] : [1, 1]

   

[^rng] : [1, 1]

 

. : [1, 1]

   

^ : [0, 0]

   

$ : [0, 0]

 

literal : [1, 1]

   

\n : N, ∞]

   

class : [1, 1]

 

\b : [0, 0]

   

\B : [0, 0]

 

\p{property} : [1, 6]

   

\P{property} : [1, 6]

4.8.3 Regexp Constructors

procedure

(regexp? v)  boolean?

  v : any/c
Returns #t if v is a regexp value created by +regexp or pregexp, #f otherwise.

procedure

(pregexp? v)  boolean?

  v : any/c
Returns #t if v is a regexp value created by +pregexp (not regexp), #f otherwise.

procedure

(byte-regexp? v)  boolean?

  v : any/c
Returns #t if v is a regexp value created by +byte-regexp or byte-pregexp, #f otherwise.

procedure

(byte-pregexp? v)  boolean?

  v : any/c
Returns #t if v is a regexp value created by +byte-pregexp (not byte-regexp), #f +otherwise.

procedure

(regexp str)  regexp?

  str : string?
(regexp str handler)  any
  str : string?
  handler : (or/c #f (string? -> any))
Takes a string representation of a regular expression (using the +syntax in Regexp Syntax) and compiles it into a regexp +value. Other regular expression procedures accept either a string or a +regexp value as the matching pattern. If a regular expression string +is used multiple times, it is faster to compile the string once to a +regexp value and use it for repeated matches instead of using the +string each time.

If handler is provided and not #f, it is called and +its result is returned when str is not a valid representation +of a regular expression; the argument to handler is a string +that describes the problem with str. If handler is +#f or not provided, then exn:fail:contract exception is raised.

The object-name procedure returns +the source string for a regexp value.

Examples:
> (regexp "ap*le")

#rx"ap*le"

> (object-name #rx"ap*le")

"ap*le"

> (regexp "+" (λ (s) (list s)))

'("`+` follows nothing in pattern")

Changed in version 6.5.0.1 of package base: Added the handler argument.

procedure

(pregexp str)  pregexp?

  str : string?
(pregexp str handler)  any
  str : string?
  handler : (or/c #f (string? -> any))
Like regexp, except that it uses a slightly different syntax +(see Regexp Syntax). The result can be used with +regexp-match, etc., just like the result from +regexp.

Examples:
> (pregexp "ap*le")

#px"ap*le"

> (regexp? #px"ap*le")

#t

> (pregexp "+" (λ (s) (vector s)))

'#("`+` follows nothing in pattern")

Changed in version 6.5.0.1 of package base: Added the handler argument.

procedure

(byte-regexp bstr)  byte-regexp?

  bstr : bytes?
(byte-regexp bstr handler)  any
  bstr : bytes?
  handler : (or/c #f (bytes? -> any))
Takes a byte-string representation of a regular expression (using the +syntax in Regexp Syntax) and compiles it into a +byte-regexp value.

If handler is provided, it is called and its result is returned +if str is not a valid representation of a regular expression.

The object-name procedure +returns the source byte string for a regexp value.

Examples:
> (byte-regexp #"ap*le")

#rx#"ap*le"

> (object-name #rx#"ap*le")

#"ap*le"

> (byte-regexp "ap*le")

byte-regexp: contract violation

  expected: bytes?

  given: "ap*le"

> (byte-regexp #"+" (λ (s) (list s)))

'("`+` follows nothing in pattern")

Changed in version 6.5.0.1 of package base: Added the handler argument.

procedure

(byte-pregexp bstr)  byte-pregexp?

  bstr : bytes?
(byte-pregexp bstr handler)  any
  bstr : bytes?
  handler : (or/c #f (bytes? -> any))
Like byte-regexp, except that it uses a slightly different +syntax (see Regexp Syntax). The result can be used with +regexp-match, etc., just like the result from +byte-regexp.

Examples:
> (byte-pregexp #"ap*le")

#px#"ap*le"

> (byte-pregexp #"+" (λ (s) (vector s)))

'#("`+` follows nothing in pattern")

Changed in version 6.5.0.1 of package base: Added the handler argument.

procedure

(regexp-quote str [case-sensitive?])  string?

  str : string?
  case-sensitive? : any/c = #t
(regexp-quote bstr [case-sensitive?])  bytes?
  bstr : bytes?
  case-sensitive? : any/c = #t
Produces a string or byte string suitable for use with regexp +to match the literal sequence of characters in str or +sequence of bytes in bstr. If case-sensitive? is +true (the default), the resulting regexp matches letters in +str or bytes case-sensitively, otherwise it matches +case-insensitively.

Examples:
> (regexp-match "." "apple.scm")

'("a")

> (regexp-match (regexp-quote ".") "apple.scm")

'(".")

procedure

(regexp-max-lookbehind pattern)  exact-nonnegative-integer?

  pattern : (or/c regexp? byte-regexp?)
Returns the maximum number of bytes that pattern may consult +before the starting position of a match to determine the match. For +example, the pattern (?<=abc)d consults three bytes +preceding a matching d, while e(?<=a..)d consults +two bytes before a matching ed. A ^ pattern may +consult a preceding byte to determine whether the current position is +the start of the input or of a line.

4.8.4 Regexp Matching

procedure

(regexp-match pattern 
  input 
  [start-pos 
  end-pos 
  output-port 
  input-prefix]) 
  
(if (and (or (string? pattern) (regexp? pattern))
         (or (string? input) (path? input)))
    (or/c #f (cons/c string? (listof (or/c string? #f))))
    (or/c #f (cons/c bytes?  (listof (or/c bytes?  #f)))))
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  output-port : (or/c output-port? #f) = #f
  input-prefix : bytes? = #""
Attempts to match pattern (a string, byte string, +regexp value, or byte-regexp value) once to a portion of +input. The matcher finds a portion of input that +matches and is closest to the start of the input (after +start-pos).

If input is a path, it is converted to a byte string with +path->bytes if pattern is a byte string or a +byte-based regexp. Otherwise, input is converted to a string +with path->string.

The optional start-pos and end-pos arguments select +a portion of input for matching; the default is the entire +string or the stream up to an end-of-file. When input is a +string, start-pos is a character position; when +input is a byte string, then start-pos is a byte +position; and when input is an input port, start-pos +is the number of bytes to skip before starting to match. The +end-pos argument can be #f, which corresponds to the +end of the string or an end-of-file in the stream; otherwise, it is a +character or byte position, like start-pos. If input +is an input port, and if an end-of-file is reached before +start-pos bytes are skipped, then the match fails.

In pattern, a start-of-string ^ refers to the first +position of input after start-pos, assuming that +input-prefix is #"". The end-of-input $ +refers to the end-posth position or (in the case of an input +port) an end-of-file, whichever comes first.

The input-prefix specifies bytes that effectively precede +input for the purposes of ^ and other look-behind +matching. For example, a #"" prefix means that ^ +matches at the beginning of the stream, while a #"\n" +input-prefix means that a start-of-line ^ can match +the beginning of the input, while a start-of-file ^ cannot.

If the match fails, #f is returned. If the match succeeds, a +list containing strings or byte string, and possibly #f, is +returned. The list contains strings only if input is a string +and pattern is not a byte regexp. Otherwise, the list +contains byte strings (substrings of the UTF-8 encoding of +input, if input is a string).

The first [byte] string in a result list is the portion of +input that matched pattern. If two portions of +input can match pattern, then the match that starts +earliest is found.

Additional [byte] strings are returned in the list if pattern +contains parenthesized sub-expressions (but not when the opening +parenthesis is followed by ?). Matches for the +sub-expressions are provided in the order of the opening parentheses +in pattern. When sub-expressions occur in branches of an +| “or” pattern, in a * “zero or more” +pattern, or other places where the overall pattern can succeed without +a match for the sub-expression, then a #f is returned for the +sub-expression if it did not contribute to the final match. When a +single sub-expression occurs within a * “zero or more” +pattern or other multiple-match positions, then the rightmost match +associated with the sub-expression is returned in the list.

If the optional output-port is provided as an output port, +the part of input from its beginning (not start-pos) +that precedes the match is written to the port. All of input +up to end-pos is written to the port if no match is +found. This functionality is most useful when input is an +input port.

When matching an input port, a match failure reads up to +end-pos bytes (or end-of-file), even if pattern +begins with a start-of-string ^; see also +regexp-try-match. On success, all bytes up to and including +the match are eventually read from the port, but matching proceeds by +first peeking bytes from the port (using peek-bytes-avail!), +and then (re‑)reading matching bytes to discard them after the match +result is determined. Non-matching bytes may be read and discarded +before the match is determined. The matcher peeks in blocking mode +only as far as necessary to determine a match, but it may peek extra +bytes to fill an internal buffer if immediately available (i.e., +without blocking). Greedy repeat operators in pattern, such +as * or +, tend to force reading the entire +content of the port (up to end-pos) to determine a match.

If the input port is read simultaneously by another thread, or if the +port is a custom port with inconsistent reading and peeking procedures +(see Custom Ports), then the bytes that are peeked and +used for matching may be different than the bytes read and discarded +after the match completes; the matcher inspects only the peeked +bytes. To avoid such interleaving, use regexp-match-peek +(with a progress-evt argument) followed by +port-commit-peeked.

Examples:
> (regexp-match #rx"x." "12x4x6")

'("x4")

> (regexp-match #rx"y." "12x4x6")

#f

> (regexp-match #rx"x." "12x4x6" 3)

'("x6")

> (regexp-match #rx"x." "12x4x6" 3 4)

#f

> (regexp-match #rx#"x." "12x4x6")

'(#"x4")

> (regexp-match #rx"x." "12x4x6" 0 #f (current-output-port))

12

'("x4")

> (regexp-match #rx"(-[0-9]*)+" "a-12--345b")

'("-12--345" "-345")

procedure

(regexp-match* pattern 
  input 
  [start-pos 
  end-pos 
  input-prefix 
  #:match-select match-select 
  #:gap-select? gap-select]) 
  
(if (and (or (string? pattern) (regexp? pattern))
         (or (string? input) (path? input)))
    (listof (or/c string? (listof (or/c #f string?))))
    (listof (or/c bytes? (listof (or/c #f bytes?)))))
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  input-prefix : bytes? = #""
  match-select : 
(or/c (list? . -> . (or/c any/c list?))
      #f)
 = car
  gap-select : any/c = #f
Like regexp-match, but the result is a list of strings or +byte strings corresponding to a sequence of matches of +pattern in input.

The pattern is used in order to find matches, where each +match attempt starts at the end of the last match, and ^ is +allowed to match the beginning of the input (if input-prefix +is #"") only for the first match. Empty matches are handled +like other matches, returning a zero-length string or byte sequence +(they are more useful in making this a complement of +regexp-split), but pattern is restricted from +matching an empty sequence immediately after an empty match.

If input contains no matches (in the range start-pos +to end-pos), null is returned. Otherwise, each item +in the resulting list is a distinct substring or byte sequence from +input that matches pattern. The end-pos +argument can be #f to match to the end of input +(which corresponds to an end-of-file if input is an input +port).

Examples:
> (regexp-match* #rx"x." "12x4x6")

'("x4" "x6")

> (regexp-match* #rx"x*" "12x4x6")

'("" "" "x" "" "x" "" "")

match-select specifies the collected results. The default of +car means that the result is the list of matches without +returning parenthesized sub-patterns. It can be given as a ‘selector’ +function which chooses an item from a list, or it can choose a list of +items. For example, you can use cdr to get a list of lists +of parenthesized sub-patterns matches, or values (as an +identity function) to get the full matches as well. (Note that the +selector must choose an element of its input list or a list of +elements, but it must not inspect its input as they can be either a +list of strings or a list of position pairs. Furthermore, the +selector must be consistent in its choice(s).)

Examples:
> (regexp-match* #rx"x(.)" "12x4x6" #:match-select cadr)

'("4" "6")

> (regexp-match* #rx"x(.)" "12x4x6" #:match-select values)

'(("x4" "4") ("x6" "6"))

In addition, specifying gap-select as a non-#f value +will make the result an interleaved list of the matches as well as the +separators between them matches, starting and ending with a separator. +In this case, match-select can be given as #f to +return only the separators, making such uses equivalent to +regexp-split.

Examples:
> (regexp-match* #rx"x(.)" "12x4x6" #:match-select cadr #:gap-select? #t)

'("12" "4" "" "6" "")

> (regexp-match* #rx"x(.)" "12x4x6" #:match-select #f #:gap-select? #t)

'("12" "" "")

procedure

(regexp-try-match pattern 
  input 
  [start-pos 
  end-pos 
  output-port 
  input-prefix]) 
  (or/c #f (cons/c bytes? (listof (or/c bytes? #f))))
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  output-port : (or/c output-port? #f) = #f
  input-prefix : bytes? = #""
Like regexp-match on input ports, except that if the match +fails, no characters are read and discarded from in.

This procedure is especially useful with a pattern that +begins with a start-of-string ^ or with a non-#f +end-pos, since each limits the amount of peeking into the +port. Otherwise, beware that a large portion of the stream may be +peeked (and therefore pulled into memory) before the match succeeds or +fails.

procedure

(regexp-match-positions pattern 
  input 
  [start-pos 
  end-pos 
  output-port 
  input-prefix]) 
  
(or/c (cons/c (cons/c exact-nonnegative-integer?
                      exact-nonnegative-integer?)
              (listof (or/c (cons/c exact-integer?
                                    exact-integer?)
                            #f)))
      #f)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  output-port : (or/c output-port? #f) = #f
  input-prefix : bytes? = #""
Like regexp-match, but returns a list of number pairs (and +#f) instead of a list of strings. Each pair of numbers refers +to a range of characters or bytes in input. If the result for +the same arguments with regexp-match would be a list of byte +strings, the resulting ranges correspond to byte ranges; in that case, +if input is a character string, the byte ranges correspond to +bytes in the UTF-8 encoding of the string.

Range results are returned in a substring- and +subbytes-compatible manner, independent of +start-pos. In the case of an input port, the returned +positions indicate the number of bytes that were read, including +start-pos, before the first matching byte.

Examples:
> (regexp-match-positions #rx"x." "12x4x6")

'((2 . 4))

> (regexp-match-positions #rx"x." "12x4x6" 3)

'((4 . 6))

> (regexp-match-positions #rx"(-[0-9]*)+" "a-12--345b")

'((1 . 9) (5 . 9))

Range results after the first one can include negative numbers if +input-prefix is non-empty and if pattern includes a +lookbehind pattern. Such ranges start in the input-prefix +instead of input. More generally, when start-pos is +positive, then range results that are less than start-pos +start in input-prefix.

Examples:
> (regexp-match-positions #rx"(?<=(.))." "a" 0 #f #f #"x")

'((0 . 1) (-1 . 0))

> (regexp-match-positions #rx"(?<=(..))." "a" 0 #f #f #"x")

#f

> (regexp-match-positions #rx"(?<=(..))." "_a" 1 #f #f #"x")

#f

Although input-prefix is always a byte string, when the +returned positions are string indices and they refer to a portion of +input-prefix, then they correspond to a UTF-8 decoding of +a tail of input-prefix.

Examples:
> (bytes-length (string->bytes/utf-8 "λ"))

2

> (regexp-match-positions #rx"(?<=(.))." "a" 0 #f #f (string->bytes/utf-8 "λ"))

'((0 . 1) (-1 . 0))

procedure

(regexp-match-positions* pattern 
  input 
  [start-pos 
  end-pos 
  input-prefix 
  #:match-select match-select]) 
  
(or/c (listof (cons/c exact-nonnegative-integer?
                      exact-nonnegative-integer?))
      (listof (listof (or/c #f (cons/c exact-nonnegative-integer?
                                       exact-nonnegative-integer?)))))
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  input-prefix : bytes? = #""
  match-select : (list? . -> . (or/c any/c list?)) = car
Like regexp-match-positions, but returns multiple matches +like regexp-match*.

Examples:
> (regexp-match-positions* #rx"x." "12x4x6")

'((2 . 4) (4 . 6))

> (regexp-match-positions* #rx"x(.)" "12x4x6" #:match-select cadr)

'((3 . 4) (5 . 6))

Note that unlike regexp-match*, there is no +#:gap-select? input keyword, as this information can be easily +inferred from the resulting matches.

procedure

(regexp-match? pattern    
  input    
  [start-pos    
  end-pos    
  output-port    
  input-prefix])  boolean?
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  output-port : (or/c output-port? #f) = #f
  input-prefix : bytes? = #""
Like regexp-match, but returns merely #t when the +match succeeds, #f otherwise.

Examples:
> (regexp-match? #rx"x." "12x4x6")

#t

> (regexp-match? #rx"y." "12x4x6")

#f

procedure

(regexp-match-exact? pattern input)  boolean?

  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path?)
Like regexp-match?, but #t is only returned when the +first found match is to the entire content of input.

Examples:
> (regexp-match-exact? #rx"x." "12x4x6")

#f

> (regexp-match-exact? #rx"1.*x." "12x4x6")

#t

Beware that regexp-match-exact? can return #f if +pattern generates a partial match for input first, even if +pattern could also generate a complete match. To check if there is any +match of pattern that covers all of input, use +rexexp-match? with ^(?:pattern)$ +instead.

Examples:
> (regexp-match-exact? #rx"a|ab" "ab")

#f

> (regexp-match? #rx"^(?:a|ab)$" "ab")

#t

The (?:) grouping is necessary because concatenation has +lower precedence than alternation; the regular expression without it, +^a|ab$, matches any input that either starts with +a or ends with ab.

Example:
> (regexp-match? #rx"^a|ab$" "123ab")

#t

procedure

(regexp-match-peek pattern 
  input 
  [start-pos 
  end-pos 
  progress 
  input-prefix]) 
  
(or/c (cons/c bytes? (listof (or/c bytes? #f)))
      #f)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  progress : (or/c evt #f) = #f
  input-prefix : bytes? = #""
Like regexp-match on input ports, but only peeks bytes from +input instead of reading them. Furthermore, instead of +an output port, the last optional argument is a progress event for +input (see port-progress-evt). If progress +becomes ready, then the match stops peeking from input +and returns #f. The progress argument can be +#f, in which case the peek may continue with inconsistent +information if another process meanwhile reads from +input.

Examples:
> (define p (open-input-string "a abcd"))
> (regexp-match-peek ".*bc" p)

'(#"a abc")

> (regexp-match-peek ".*bc" p 2)

'(#"abc")

> (regexp-match ".*bc" p 2)

'(#"abc")

> (peek-char p)

#\d

> (regexp-match ".*bc" p)

#f

> (peek-char p)

#<eof>

procedure

(regexp-match-peek-positions pattern 
  input 
  [start-pos 
  end-pos 
  progress 
  input-prefix]) 
  
(or/c (cons/c (cons/c exact-nonnegative-integer?
                      exact-nonnegative-integer?)
              (listof (or/c (cons/c exact-nonnegative-integer?
                                    exact-nonnegative-integer?)
                            #f)))
      #f)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  progress : (or/c evt #f) = #f
  input-prefix : bytes? = #""
Like regexp-match-positions on input ports, but only peeks +bytes from input instead of reading them, and with a +progress argument like regexp-match-peek.

procedure

(regexp-match-peek-immediate pattern 
  input 
  [start-pos 
  end-pos 
  progress 
  input-prefix]) 
  
(or/c (cons/c bytes? (listof (or/c bytes? #f)))
      #f)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  progress : (or/c evt #f) = #f
  input-prefix : bytes? = #""
Like regexp-match-peek, but it attempts to match only bytes +that are available from input without blocking. The +match fails if not-yet-available characters might be used to match +pattern.

procedure

(regexp-match-peek-positions-immediate pattern 
  input 
  [start-pos 
  end-pos 
  progress 
  input-prefix]) 
  
(or/c (cons/c (cons/c exact-nonnegative-integer?
                      exact-nonnegative-integer?)
              (listof (or/c (cons/c exact-nonnegative-integer?
                                    exact-nonnegative-integer?)
                            #f)))
      #f)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  progress : (or/c evt #f) = #f
  input-prefix : bytes? = #""
Like regexp-match-peek-positions, but it attempts to match +only bytes that are available from input without +blocking. The match fails if not-yet-available characters might be +used to match pattern.

procedure

(regexp-match-peek-positions* pattern 
  input 
  [start-pos 
  end-pos 
  input-prefix 
  #:match-select match-select]) 
  
(or/c (listof (cons/c exact-nonnegative-integer?
                      exact-nonnegative-integer?))
      (listof (listof (or/c #f (cons/c exact-nonnegative-integer?
                                       exact-nonnegative-integer?)))))
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  input-prefix : bytes? = #""
  match-select : (list? . -> . (or/c any/c list?)) = car
Like regexp-match-peek-positions, but returns multiple matches like +regexp-match-positions*.

procedure

(regexp-match/end pattern 
  input 
  [start-pos 
  end-pos 
  output-port 
  input-prefix 
  count]) 
  
(if (and (or (string? pattern) (regexp? pattern))
         (or/c (string? input) (path? input)))
    (or/c #f (cons/c string? (listof (or/c string? #f))))
    (or/c #f (cons/c bytes?  (listof (or/c bytes?  #f)))))
(or/c #f bytes?)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  output-port : (or/c output-port? #f) = #f
  input-prefix : bytes? = #""
  count : exact-nonnegative-integer? = 1
Like regexp-match, but with a second result: a byte +string of up to count bytes that correspond to the input +(possibly including the input-prefix) leading to the end of +the match; the second result is #f if no match is found.

The second result can be useful as an input-prefix for +attempting a second match on input starting from the end of +the first match. In that case, use regexp-max-lookbehind +to determine an appropriate value for count.

procedure

(regexp-match-positions/end pattern 
  input 
  [start-pos 
  end-pos 
  input-prefix 
  count]) 
  
(listof (cons/c exact-nonnegative-integer?
                exact-nonnegative-integer?))
(or/c #f bytes?)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? path? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  input-prefix : bytes? = #""
  count : exact-nonnegative-integer? = 1

procedure

(regexp-match-peek-positions/end pattern 
  input 
  [start-pos 
  end-pos 
  progress 
  input-prefix 
  count]) 
  
(or/c (cons/c (cons/c exact-nonnegative-integer?
                      exact-nonnegative-integer?)
              (listof (or/c (cons/c exact-nonnegative-integer?
                                    exact-nonnegative-integer?)
                            #f)))
      #f)
(or/c #f bytes?)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  progress : (or/c evt #f) = #f
  input-prefix : bytes? = #""
  count : exact-nonnegative-integer? = 1

procedure

(regexp-match-peek-positions-immediate/end pattern 
  input 
  [start-pos 
  end-pos 
  progress 
  input-prefix 
  count]) 
  
(or/c (cons/c (cons/c exact-nonnegative-integer?
                      exact-nonnegative-integer?)
              (listof (or/c (cons/c exact-nonnegative-integer?
                                    exact-nonnegative-integer?)
                            #f)))
      #f)
(or/c #f bytes?)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : input-port?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  progress : (or/c evt #f) = #f
  input-prefix : bytes? = #""
  count : exact-nonnegative-integer? = 1
Like regexp-match-positions, etc., but with a second result +like regexp-match/end.

4.8.5 Regexp Splitting

procedure

(regexp-split pattern 
  input 
  [start-pos 
  end-pos 
  input-prefix]) 
  
(if (and (or (string? pattern) (regexp? pattern))
         (string? input))
    (cons/c string? (listof string?))
    (cons/c bytes? (listof bytes?)))
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes? input-port?)
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  input-prefix : bytes? = #""
The complement of regexp-match*: the result is a list of +strings (if pattern is a string or character regexp and +input is a string) or byte strings (otherwise) from +input that are separated by matches to +pattern. Adjacent matches are separated with "" or +#"". Zero-length matches are treated the same as for +regexp-match*.

If input contains no matches (in the range start-pos +to end-pos), the result is a list containing input’s +content (from start-pos to end-pos) as a single +element. If a match occurs at the beginning of input (at +start-pos), the resulting list will start with an empty +string or byte string, and if a match occurs at the end (at +end-pos), the list will end with an empty string or byte +string. The end-pos argument can be #f, in which +case splitting goes to the end of input (which corresponds to +an end-of-file if input is an input port).

Examples:
> (regexp-split #rx" +" "12  34")

'("12" "34")

> (regexp-split #rx"." "12  34")

'("" "" "" "" "" "" "")

> (regexp-split #rx"" "12  34")

'("" "1" "2" " " " " "3" "4" "")

> (regexp-split #rx" *" "12  34")

'("" "1" "2" "" "3" "4" "")

> (regexp-split #px"\\b" "12, 13 and 14.")

'("" "12" ", " "13" " " "and" " " "14" ".")

> (regexp-split #rx" +" "")

'("")

4.8.6 Regexp Substitution

procedure

(regexp-replace pattern 
  input 
  insert 
  [input-prefix]) 
  
(if (and (or (string? pattern) (regexp? pattern))
         (string? input))
    string?
    bytes?)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes?)
  insert : 
(or/c string? bytes?
      ((string?) () #:rest (listof string?) . ->* . string?)
      ((bytes?) () #:rest (listof bytes?) . ->* . bytes?))
  input-prefix : bytes? = #""
Performs a match using pattern on input, and then +returns a string or byte string in which the matching portion of +input is replaced with insert. If pattern +matches no part of input, then input is returned +unmodified.

The insert argument can be either a (byte) string, or a +function that returns a (byte) string. In the latter case, the +function is applied on the list of values that regexp-match +would return (i.e., the first argument is the complete match, and then +one argument for each parenthesized sub-expression) to obtain a +replacement (byte) string.

If pattern is a string or character regexp and input +is a string, then insert must be a string or a procedure that +accept strings, and the result is a string. If pattern is a +byte string or byte regexp, or if input is a byte string, +then insert as a string is converted to a byte string, +insert as a procedure is called with a byte string, and the +result is a byte string.

If insert contains &, then & +is replaced with the matching portion of input before it is +substituted into the match’s place. If insert contains +\n for some integer n, then it is +replaced with the nth matching sub-expression from +input. A & and \0 are aliases. If +the nth sub-expression was not used in the match, or if +n is greater than the number of sub-expressions in +pattern, then \n is replaced with the +empty string.

To substitute a literal & or \, use +\& and \\, respectively, in +insert. A \$ in insert is +equivalent to an empty sequence; this can be used to terminate a +number n following \. If a \ in +insert is followed by anything other than a digit, +&, \, or $, then the \ +by itself is treated as \0.

Note that the \ described in the previous paragraphs is a +character or byte of insert. To write such an insert +as a Racket string literal, an escaping \ is needed +before the \. For example, the Racket constant +"\\1" is \1.

Examples:
> (regexp-replace #rx"mi" "mi casa" "su")

"su casa"

> (regexp-replace #rx"mi" "mi casa" string-upcase)

"MI casa"

> (regexp-replace #rx"([Mm])i ([a-zA-Z]*)" "Mi Casa" "\\1y \\2")

"My Casa"

> (regexp-replace #rx"([Mm])i ([a-zA-Z]*)" "mi cerveza Mi Mi Mi"
                  "\\1y \\2")

"my cerveza Mi Mi Mi"

> (regexp-replace #rx"x" "12x4x6" "\\\\")

"12\\4x6"

> (display (regexp-replace #rx"x" "12x4x6" "\\\\"))

12\4x6

procedure

(regexp-replace* pattern    
  input    
  insert    
  [start-pos    
  end-pos    
  input-prefix])  (or/c string? bytes?)
  pattern : (or/c string? bytes? regexp? byte-regexp?)
  input : (or/c string? bytes?)
  insert : 
(or/c string? bytes?
      ((string?) () #:rest (listof string?) . ->* . string?)
      ((bytes?) () #:rest (listof bytes?) . ->* . bytes?))
  start-pos : exact-nonnegative-integer? = 0
  end-pos : (or/c exact-nonnegative-integer? #f) = #f
  input-prefix : bytes? = #""
Like regexp-replace, except that every instance of +pattern in input is replaced with insert, +instead of just the first match. The result is input only if +there are no matches, start-pos is 0, and +end-pos is #f or the length of input. +Only non-overlapping instances of +pattern in input are replaced, so instances of +pattern within inserted strings are not replaced +recursively. Zero-length matches are treated the same as in +regexp-match*.

The optional start-pos and end-pos arguments select +a portion of input for matching; the default is the entire +string or the stream up to an end-of-file.

Examples:
> (regexp-replace* #rx"([Mm])i ([a-zA-Z]*)" "mi cerveza Mi Mi Mi"
                   "\\1y \\2")

"my cerveza My Mi Mi"

> (regexp-replace* #rx"([Mm])i ([a-zA-Z]*)" "mi cerveza Mi Mi Mi"
                   (lambda (all one two)
                     (string-append (string-downcase one) "y"
                                    (string-upcase two))))

"myCERVEZA myMI Mi"

> (regexp-replace* #px"\\w" "hello world" string-upcase 0 5)

"HELLO world"

> (display (regexp-replace* #rx"x" "12x4x6" "\\\\"))

12\4\6

Changed in version 8.1.0.7 of package base: Changed to return input when no +replacements are performed.

procedure

(regexp-replaces input replacements)  (or/c string? bytes?)

  input : (or/c string? bytes?)
  replacements : 
(listof
 (list/c (or/c string? bytes? regexp? byte-regexp?)
         (or/c string? bytes?
             ((string?) () #:rest (listof string?) . ->* . string?)
             ((bytes?) () #:rest (listof bytes?) . ->* . bytes?))))
Performs a chain of regexp-replace* operations, where each +element in replacements specifies a replacement as a +(list pattern replacement). The replacements are done in +order, so later replacements can apply to previous insertions.

Examples:
> (regexp-replaces "zero-or-more?"
                   '([#rx"-" "_"] [#rx"(.*)\\?$" "is_\\1"]))

"is_zero_or_more"

> (regexp-replaces "zero-or-more?"
                   '([#rx"e" "o"] [#rx"o" "oo"]))

"zooroo-oor-mooroo?"

procedure

(regexp-replace-quote str)  string?

  str : string?
(regexp-replace-quote bstr)  bytes?
  bstr : bytes?
Produces a string suitable for use as the third argument to +regexp-replace to insert the literal sequence of characters +in str or bytes in bstr as a replacement. +Concretely, every \ and & in str or +bstr is protected by a quoting \.

Examples:
> (regexp-replace #rx"UT" "Go UT!" "A&M")

"Go AUTM!"

> (regexp-replace #rx"UT" "Go UT!" (regexp-replace-quote "A&M"))

"Go A&M!"

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/repl-module.html b/clones/docs.racket-lang.org/reference/repl-module.html new file mode 100644 index 00000000..51902178 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/repl-module.html @@ -0,0 +1,6 @@ + +14.13 The racket/repl Library

14.13 The racket/repl Library

 (require racket/repl) package: base

The racket/repl provides the same +read-eval-print-loop binding as racket/base, but +with even fewer internal dependencies than racket/base. It is +loaded in some situations on startup, as described in +Initialization.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/require.html b/clones/docs.racket-lang.org/reference/require.html new file mode 100644 index 00000000..e82a3b2b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/require.html @@ -0,0 +1,394 @@ + +3.2 Importing and Exporting: require and provide

3.2 Importing and Exporting: require and provide

+Imports: require in The Racket Guide introduces require.

syntax

(require require-spec ...)

 
require-spec = module-path
  | (only-in require-spec id-maybe-renamed ...)
  | (except-in require-spec id ...)
  | (prefix-in prefix-id require-spec)
  | (rename-in require-spec [orig-id bind-id] ...)
  | (combine-in require-spec ...)
  | (relative-in module-path require-spec ...)
  | (only-meta-in phase-level require-spec ...)
  | (only-space-in space require-spec ...)
  | (for-syntax require-spec ...)
  | (for-template require-spec ...)
  | (for-label require-spec ...)
  | (for-meta phase-level require-spec ...)
  | (for-space space require-spec ...)
  | derived-require-spec
     
module-path = root-module-path
  | (submod root-module-path submod-path-element ...)
  | (submod "." submod-path-element ...)
  | (submod ".." submod-path-element ...)
     
root-module-path = (quote id)
  | rel-string
  | (lib rel-string ...+)
  | id
  | (file string)
  | (planet id)
  | (planet string)
  | 
(planet rel-string
        (user-string pkg-string vers)
        rel-string ...)
     
submod-path-element = id
  | ".."
     
id-maybe-renamed = id
  | [orig-id bind-id]
     
phase-level = exact-integer
  | #f
     
space = id
  | #f
     
vers = 
  | nat
  | nat minor-vers
     
minor-vers = nat
  | (nat nat)
  | (= nat)
  | (+ nat)
  | (- nat)
In a top-level context, require instantiates +modules (see Modules and Module-Level Variables). In a top-level +context or module context, expansion of require +visits modules (see Module Expansion, Phases, and Visits). In both contexts and +both evaluation and expansion, require introduces bindings +into a namespace or a module (see Introducing Bindings). A +require form in a expression context or +internal-definition context is a syntax error.

A require-spec designates a particular set of identifiers to +be bound in the importing context. Each identifier is mapped to a +particular export of a particular module; the identifier to bind may +be different from the symbolic name of the originally exported +identifier. Each identifier also binds at a particular phase +level and in a binding space.

No identifier can be bound multiple times in a given combination of +phase level and binding space by an import, unless +all of the bindings refer to the same +original definition in the same module. In a module context, +an identifier can be either imported or defined for a given +phase level and binding space, but not both.

The syntax of require-spec can be extended via +define-require-syntax, and when multiple +require-specs are specified in a require, the +bindings of each require-spec are visible for expanding later +require-specs. The pre-defined forms (as exported by +racket/base) are as follows:

module-path

Imports all exported bindings from the +named module, using the export name for the local identifiers. +(See below for information on module-path.) The lexical +context of the module-path form determines the context of +the introduced identifiers, adding a space scope for exports +in a particular binding space, and in each export’s +phase level.

If any identifier provided by module-path has a symbol form +that is uninterned, the identifier is not imported (i.e., it +is impossible to import a binding for an uninterned symbol). This +restriction is intended to avoid compilation differences depending +on whether a module has been saved to a file or not (see +Printing Compiled Code).

syntax

(only-in require-spec id-maybe-renamed ...)

Like require-spec, but constrained to those exports for +which the identifiers to bind match id-maybe-renamed: as +id or as orig-id in [orig-id bind-id]. If +the id or orig-id of any id-maybe-renamed +is not in the set that require-spec describes, a syntax +error is reported.

Examples:
> (require (only-in racket/tcp
                    tcp-listen
                    [tcp-accept my-accept]))
> tcp-listen

#<procedure:tcp-listen>

> my-accept

#<procedure:tcp-accept>

> tcp-accept

tcp-accept: undefined;

 cannot reference an identifier before its definition

  in module: top-level

syntax

(except-in require-spec id ...)

Like +require-spec, but omitting those imports for which +ids are the identifiers to bind; if any id is not +in the set that require-spec describes, a syntax error is +reported.

Examples:
> (require (except-in racket/tcp
                      tcp-listen))
> tcp-accept

#<procedure:tcp-accept>

> tcp-listen

tcp-listen: undefined;

 cannot reference an identifier before its definition

  in module: top-level

syntax

(prefix-in prefix-id require-spec)

Like +require-spec, but adjusting each identifier to be bound by +prefixing it with prefix-id. The lexical context of the +prefix-id is ignored, and instead preserved from the +identifiers before prefixing.

Examples:
> (require (prefix-in tcp: racket/tcp))
> tcp:tcp-accept

#<procedure:tcp-accept>

> tcp:tcp-listen

#<procedure:tcp-listen>

syntax

(rename-in require-spec [orig-id bind-id] ...)

Like require-spec, but replacing the identifier to +bind orig-id with bind-id; if any +orig-id is not in the set that require-spec +describes, a syntax error is reported.

Examples:
> (require (rename-in racket/tcp
                      (tcp-accept accept)
                      (tcp-listen listen)))
> accept

#<procedure:tcp-accept>

> listen

#<procedure:tcp-listen>

syntax

(combine-in require-spec ...)

The union of the require-specs. If two or more imports from the +require-specs have the same identifier name but they do not refer to +the same original binding, a syntax error is reported.

Examples:
> (require (combine-in (only-in racket/tcp tcp-accept)
                       (only-in racket/tcp tcp-listen)))
> tcp-accept

#<procedure:tcp-accept>

> tcp-listen

#<procedure:tcp-listen>

syntax

(relative-in module-path require-spec ...)

Like the union of the require-specs, but each +relative module path in a require-spec is treated +as relative to module-path instead of the enclosing +context.

The require transformer that implements relative-in +sets current-require-module-path to adjust module paths +in the require-specs.

syntax

(only-meta-in phase-level require-spec ...)

Like the combination of require-specs, but removing any +binding that is not for phase-level, where #f for +phase-level corresponds to the label phase level.

The following example imports bindings only at phase level 1, +the transform phase:

> (module nest racket
    (provide (for-syntax meta-eggs)
             (for-meta 1 meta-chicks)
             num-eggs)
    (define-for-syntax meta-eggs 2)
    (define-for-syntax meta-chicks 3)
    (define num-eggs 2))
> (require (only-meta-in 1 'nest))
> (define-syntax (desc stx)
    (printf "~s ~s\n" meta-eggs meta-chicks)
    #'(void))
> (desc)

2 3

> num-eggs

num-eggs: undefined;

 cannot reference an identifier before its definition

  in module: top-level

The following example imports only bindings at phase level 0, the +normal phase.

> (require (only-meta-in 0 'nest))
> num-eggs

2

syntax

(only-space-in space require-spec ...)

Like the combination of require-specs, but removing any +binding that is not provided for the binding space identifier by +spacewhich is normally an identifier, but #f for +space corresponds to the default binding space.

Added in version 8.2.0.3 of package base.

(for-meta phase-level require-spec ...)

Like the combination of +require-specs, but the bindings specified by +each require-spec are shifted by phase-level. The +label phase level corresponds to #f, and a shifting +combination that involves #f produces #f.

Examples:
> (module nest racket
    (provide num-eggs)
    (define num-eggs 2))
> (require (for-meta 0 'nest))
> num-eggs

2

> (require (for-meta 1 'nest))
> (define-syntax (roost stx)
    (datum->syntax stx num-eggs))
> (roost)

2

(for-syntax require-spec ...)

Same as +(for-meta 1 require-spec ...).

(for-template require-spec ...)

Same as +(for-meta -1 require-spec ...).

(for-label require-spec ...)

Same as +(for-meta #f require-spec ...). If an identifier in any of the +require-specs is bound at more than one phase level, a syntax error +is reported.

(for-space space require-spec ...)

Like the combination of +require-specs, but the bindings specified by +each require-spec are moved to the binding space +specified by spacewhich is normally an identifier, +but #f for space corresponds to the +default binding space.

A binding is moved to the new space by removing the scope for the +space originally implied by require-spec, if any, and +adding the scope for space, if any.

Added in version 8.2.0.3 of package base.

derived-require-spec

See define-require-syntax +for information on expanding the set of require-spec +forms.

+Module Paths in The Racket Guide introduces module paths.

A module-path identifies a module, either a root module or +a submodule that is declared lexically within another module. +A root module is identified either through a concrete +name in the form of an identifier, or through an indirect name that +can trigger automatic loading of the module declaration. Except for +the (quote id) case below, the actual resolution +of a root module path is up to the current +module name resolver (see +current-module-name-resolver), and the description below +corresponds to the default module name resolver.

(quote id)

Refers to a submodule previously declared with the name +id or a module previously declared interactively with the name +id. When id refers to a submodule, (quote id) +is equivalent to (submod "." id).

Examples:
; a module declared interactively as test:
> (require 'test)

rel-string

A path relative to the containing source (as +determined by current-load-relative-directory or +current-directory). Regardless of the current platform, +rel-string is always parsed as a Unix-format relative path: +/ is the path delimiter (multiple adjacent /s are +not allowed), .. accesses the parent +directory, and . accesses the current directory. The path +cannot be empty or contain a leading or trailing slash, path elements +before than the last one cannot include a file suffix (i.e., a +. in an element other than . or ..), +and the only allowed characters are ASCII letters, ASCII digits, +-, +, _, ., /, and +%. Furthermore, a % is allowed only when followed +by two lowercase hexadecimal digits, and the digits must form a +number that is not the ASCII value of a letter, digit, -, ++, or _.

The % provision is intended to support a +one-to-one encoding of arbitrary strings as path elements (after +UTF-8 encoding). Such encodings are not decoded to arrive at a +filename, but instead preserved in the file access.

If rel-string ends with a ".ss" suffix, it is +converted to a ".rkt" suffix. The compiled-load +handler may reverse that conversion if a ".rkt" file does +not exist and a ".ss" exists.

Examples:
; a module named "x.rkt" in the same
; directory as the enclosing module's file:
> (require "x.rkt")
; a module named "x.rkt" in the parent directory
; of the enclosing module file's directory:
> (require "../x.rkt")

syntax

(lib rel-string ...+)

A path to a module installed into +a collection (see Libraries and Collections). The rel-strings in +lib are constrained similar to the plain rel-string +case, with the additional constraint that a rel-string +cannot contain . or .. directory indicators.

The specific interpretation of the path depends on the number and +shape of the rel-strings:

  • If a single rel-string is provided, and if it +consists of a single element (i.e., no /) with no file +suffix (i.e., no .), then rel-string names a +collection, and "main.rkt" is the library file name.

    Examples:
    ; the main swindle library:
    > (require (lib "swindle"))
    ; the same:
    > (require (lib "swindle/main.rkt"))

  • If a single rel-string is provided, and if it +consists of multiple /-separated elements, then each +element up to the last names a collection, subcollection, +etc., and the last element names a file. If the last element has +no file suffix, ".rkt" is added, while a ".ss" +suffix is converted to ".rkt".

    Examples:
    ; "turbo.rkt" from the "swindle" collection:
    > (require (lib "swindle/turbo"))
    ; the same:
    > (require (lib "swindle/turbo.rkt"))
    ; the same:
    > (require (lib "swindle/turbo.ss"))

  • If a single rel-string is provided, and if it +consists of a single element with a file suffix (i.e, +with a .), then rel-string names a file within +the "mzlib" collection. A ".ss" +suffix is converted to ".rkt". (This convention is for +compatibility with older version of Racket.)

    Examples:
    ; "tar.rkt" module from the "mzlib" collection:
    > (require (lib "tar.ss"))

  • Otherwise, when multiple rel-strings are provided, +the first rel-string is effectively moved after the +others, and all rel-strings are appended with / +separators. The resulting path names a collection, then +subcollection, etc., ending with a file name. No suffix is added +automatically, but a ".ss" suffix is converted to +".rkt". (This convention is for compatibility with older +version of Racket.)

    Examples:
    ; "tar.rkt" module from the "mzlib" collection:
    > (require (lib "tar.ss" "mzlib"))

id

A shorthand for a lib form with a single +rel-string whose characters are the same as in the symbolic +form of id. In addition to the constraints of a lib +rel-string, id must not contain ..

Example:
> (require racket/tcp)

syntax

(file string)

Similar to the plain rel-string +case, but string is a path—possibly absolute—using the +current platform’s path conventions and expand-user-path. +A ".ss" suffix is converted to ".rkt".

Example:
> (require (file "~/tmp/x.rkt"))

syntax

(planet id)

(planet string)
(planet rel-string (user-string pkg-string vers)
        rel-string ...)
Specifies a library available via the PLaneT server.

The first form is a shorthand for the last one, where the id’s +character sequence must match the following spec grammar:

 

spec

 ::= 

owner / pkg lib

 

owner

 ::= 

elem

 

pkg

 ::= 

elem  |  elem : version

 

version

 ::= 

int  |  int : minor

 

minor

 ::= 

int  |  <= int  |  >= int  |  = int

 

  |  

int - int

 

lib

 ::= 

empty  |  / path

 

path

 ::= 

elem  |  elem / path

and where an elem is a non-empty sequence of characters +that are ASCII letters, ASCII digits, -, +, +_, or % followed by lowercase hexadecimal digits +(that do not encode one of the other allowed characters), and an +int is a non-empty sequence of ASCII digits. As this +shorthand is expended, a ".plt" extension is added to +pkg, and a ".rkt" extension is added to +path; if no path is included, "main.rkt" +is used in the expansion.

A (planet string) form is like a (planet id) form +with the identifier converted to a string, except that the +string can optionally end with a file extension (i.e., a +.) for a path. A ".ss" file extension is +converted to ".rkt".

In the more general last form of a planet module path, the +rel-strings are similar to the lib form, except +that the (user-string pkg-string vers) names a +PLaneT-based package instead of a collection. A version +specification can include an optional major and minor version, where +the minor version can be a specific number or a constraint: +(nat nat) specifies an inclusive range, (= nat) specifies an exact match, +(+ nat) specifies a minimum +version and is equivalent to just nat, and +(- nat) specifies a maximum +version. The =, +, and - +identifiers in a minor-version constraint are recognized +symbolically.

Examples:
; "main.rkt" in package "farm" by "mcdonald":
> (require (planet mcdonald/farm))
; "main.rkt" in version >= 2.0 of "farm" by "mcdonald":
> (require (planet mcdonald/farm:2))
; "main.rkt" in version >= 2.5 of "farm" by "mcdonald":
> (require (planet mcdonald/farm:2:5))
; "duck.rkt" in version >= 2.5 of "farm" by "mcdonald":
> (require (planet mcdonald/farm:2:5/duck))

syntax

(submod root-module-path submod-path-element ...)

(submod "." submod-path-element ...)
(submod ".." submod-path-element ...)
Identifies a submodule within the module specified by root-module-path +or relative to the current module in the case of (submod "." ....), +where (submod ".." submod-path-element ...) is equivalent to +(submod "." ".." submod-path-element ...). +Submodules have symbolic names, and a sequence of identifiers as submod-path-elements +determine a path of successively nested submodules with the given names. +A ".." as a submod-path-element names the enclosing module +of a submodule, and it’s intended for use in (submod "." ....) +and (submod ".." ....) forms.

As require prepares to handle a sequence of +require-specs, it logs a “prefetch” message to the +current logger at the 'info level, using the name +'module-prefetch, and including message data that is a list +of two elements: a list of module paths that appear to be +imported, and a directory path to use for relative module paths. The +logged list of module paths may be incomplete, but a compilation +manager can use approximate prefetch information to start on +compilations in parallel.

Changed in version 6.0.1.10 of package base: Added prefetch logging.

syntax

(local-require require-spec ...)

Like require, but for use in a internal-definition context to +import just into the local context. Only bindings from phase +level 0 are imported.

Examples:
> (let ()
    (local-require racket/control)
    fcontrol)

#<procedure:fcontrol>

> fcontrol

fcontrol: undefined;

 cannot reference an identifier before its definition

  in module: top-level

+Exports: provide in The Racket Guide introduces provide.

syntax

(provide provide-spec ...)

 
provide-spec = id
  | (all-defined-out)
  | (all-from-out module-path ...)
  | (rename-out [orig-id export-id] ...)
  | (except-out provide-spec provide-spec ...)
  | (prefix-out prefix-id provide-spec)
  | (struct-out id)
  | (combine-out provide-spec ...)
  | (protect-out provide-spec ...)
  | (for-meta phase-level provide-spec ...)
  | (for-syntax provide-spec ...)
  | (for-template provide-spec ...)
  | (for-label provide-spec ...)
  | (for-space space provide-spec ...)
  | derived-provide-spec
     
phase-level = exact-integer
  | #f
     
space = id
  | #f
Declares exports from a module. A provide form must appear in +a module context or a module-begin context.

A provide-spec indicates one or more bindings to provide. +For each exported binding, the external name is a symbol that can be +different from the symbolic form of the identifier that is bound +within the module. Also, each export is drawn from a particular +phase level and exported at the same phase level; by +default, the relevant phase level is the number of +begin-for-syntax forms that enclose the provide +form. Finally, each export is drawn from a binding space +and exported at the same binding space.

The syntax of provide-spec can be extended by bindings to +provide transformers or provide pre-transformers, such +as via define-provide-syntax, but the pre-defined forms are +as follows.

id

Exports id, which must be bound +within the module (i.e., either defined or imported) at the relevant +phase level and binding space. The symbolic form of +id is used as the +external name, and the symbolic form of the defined or imported +identifier must match (otherwise, the external name could be +ambiguous).

Examples:
> (module nest racket
    (provide num-eggs)
    (define num-eggs 2))
> (require 'nest)
> num-eggs

2

If id has a transformer binding to a rename +transformer, then the transformer affects the exported binding. See +make-rename-transformer for more information.

Exports all identifiers that are +defined at the relevant phase level within the +exporting module, and that have the same lexical context as the +(all-defined-out) form, excluding bindings to rename +transformers where the target identifier has the +'not-provide-all-defined syntax property. The +external name for each identifier is the symbolic form of the +identifier. Only identifiers accessible from the lexical context of +the (all-defined-out) form are included; that is, +macro-introduced imports are not re-exported, unless the +(all-defined-out) form was introduced at the same time.

Examples:
> (module nest racket
    (provide (all-defined-out))
    (define num-eggs 2))
> (require 'nest)
> num-eggs

2

syntax

(all-from-out module-path ...)

Exports all identifiers +that are imported into the exporting module using a +require-spec built on each module-path (see +Importing and Exporting: require and provide) with no phase-level shift. The symbolic +name for export is derived from the name that is bound within the +module, as opposed to the symbolic name of the export from each +module-path. Only identifiers accessible from the lexical +context of the module-path are included; that is, +macro-introduced imports are not re-exported, unless the +module-path was introduced at the same time.

Examples:
> (module nest racket
    (provide num-eggs)
    (define num-eggs 2))
> (module hen-house racket
    (require 'nest)
    (provide (all-from-out 'nest)))
> (require 'hen-house)
> num-eggs

2

syntax

(rename-out [orig-id export-id] ...)

Exports each +orig-id, which must be bound within the module at +the relevant phase level and binding space. +The symbolic name for each export is +export-id instead of orig-id.

Examples:
> (module nest racket
    (provide (rename-out [count num-eggs]))
    (define count 2))
> (require 'nest)
> num-eggs

2

> count

count: undefined;

 cannot reference an identifier before its definition

  in module: top-level

syntax

(except-out provide-spec provide-spec ...)

Like the +first provide-spec, but omitting the bindings listed in each +subsequent provide-spec. If one of the latter bindings is +not included in the initial provide-spec, a syntax error is +reported. The symbolic export name information in the latter +provide-specs is ignored; only the bindings are used.

Examples:
> (module nest racket
    (provide (except-out (all-defined-out)
                         num-chicks))
    (define num-eggs 2)
    (define num-chicks 3))
> (require 'nest)
> num-eggs

2

> num-chicks

num-chicks: undefined;

 cannot reference an identifier before its definition

  in module: top-level

syntax

(prefix-out prefix-id provide-spec)

Like provide-spec, but with each symbolic export name from +provide-spec prefixed with prefix-id.

Examples:
> (module nest racket
    (provide (prefix-out chicken: num-eggs))
    (define num-eggs 2))
> (require 'nest)
> chicken:num-eggs

2

syntax

(struct-out id)

Exports the bindings associated with a +structure type id. Typically, id is bound with +(struct id ....); more generally, id must have a +transformer binding of structure-type information at the relevant +phase level; see Structure Type Transformer Binding. Furthermore, for +each identifier mentioned in the structure-type information, the +enclosing module must define or import one identifier that is +free-identifier=?. If the structure-type information +includes a super-type identifier, and if the identifier has a +transformer binding of structure-type information, the +accessor and mutator bindings of the super-type are not +included by struct-out for export.

Examples:
> (module nest racket
    (provide (struct-out egg))
    (struct egg (color wt)))
> (require 'nest)
> (egg-color (egg 'blue 10))

'blue

syntax

(combine-out provide-spec ...)

The union of the +provide-specs.

Examples:
> (module nest racket
    (provide (combine-out num-eggs num-chicks))
    (define num-eggs 2)
    (define num-chicks 1))
> (require 'nest)
> num-eggs

2

> num-chicks

1

syntax

(protect-out provide-spec ...)

Like the union of the +provide-specs, except that the exports are protected: +requiring modules may refer to these bindings, but may not extract +these bindings from macro expansions or access them via eval without +access privileges. +For more details, see Code Inspectors. The provide-spec must specify only +bindings that are defined within the exporting module.

Examples:
> (module nest racket
    (provide num-eggs (protect-out num-chicks))
    (define num-eggs 2)
    (define num-chicks 3))
> (define weak-inspector (make-inspector (current-code-inspector)))
> (define (weak-eval x)
    (parameterize ([current-code-inspector weak-inspector])
      (define weak-ns (make-base-namespace))
      (namespace-attach-module (current-namespace)
                               ''nest
                               weak-ns)
      (parameterize ([current-namespace weak-ns])
        (namespace-require ''nest)
        (eval x))))
> (require 'nest)
> (list num-eggs num-chicks)

'(2 3)

> (weak-eval 'num-eggs)

2

> (weak-eval 'num-chicks)

?: access disallowed by code inspector to protected variable

  from module: 'nest

  at: num-chicks

See also Code Inspectors for Trusted and Untrusted Code.

(for-meta phase-level provide-spec ...)

Like the union of the +provide-specs, but adjusted to apply to the phase +level specified by phase-level relative to the current +phase level (where #f corresponds to the label phase +level). In particular, an id or rename-out form +as a provide-spec refers to a binding at +phase-level relative to the current level, an +all-defined-out exports only definitions at +phase-level relative to the current phase level, and an +all-from-out exports bindings imported with a shift by +phase-level.

Examples:
> (module nest racket
    (begin-for-syntax
     (define eggs 2))
    (define chickens 3)
    (provide (for-syntax eggs)
             chickens))
> (require 'nest)
> (define-syntax (test-eggs stx)
    (printf "Eggs are ~a\n" eggs)
    #'0)
> (test-eggs)

Eggs are 2

0

> chickens

3

> (module broken-nest racket
    (define eggs 2)
    (define chickens 3)
    (provide (for-syntax eggs)
             chickens))

eval:7:0: provide: provided identifier is not defined or

required

  at: eggs

  in: (provide (for-syntax eggs) chickens)

> (module nest2 racket
    (begin-for-syntax
     (define eggs 2))
    (provide (for-syntax eggs)))
> (require (for-meta 2 racket/base)
           (for-syntax 'nest2))
> (define-syntax (test stx)
    (define-syntax (show-eggs stx)
      (printf "Eggs are ~a\n" eggs)
      #'0)
    (begin
      (show-eggs)
      #'0))

Eggs are 2

> (test)

0

(for-syntax provide-spec ...)

Same as +(for-meta 1 provide-spec ...).

(for-template provide-spec ...)

Same as +(for-meta -1 provide-spec ...).

(for-label provide-spec ...)

Same as +(for-meta #f provide-spec ...).

(for-space space provide-spec ...)

Like the union of the +provide-specs, but adjusted to apply to the binding space +specified by spacewhere space is either an identifier +or #f for the default binding space. In particular, an id +or rename-out form as a provide-spec refers to a binding +in space, an all-defined-out exports only definitions in +space, and an all-from-out exports bindings imported into space.

When providing a binding for a non-default binding space, normally a +module should also provide a binding for the default binding space, +where the default-space binding represents the intended meaning of +the identifier. When a module later imports the same name in +different spaces from modules that adhere to this convention, then if +the two modules also (re)export the same binding for the name in the +default space, the imports are likely consistent. If the two modules +export different bindings for the name in the default space, then +attempting to import both modules will trigger an error about +conflicting imports, and a programmer can explicitly resolve the +mismatch.

Added in version 8.2.0.3 of package base.

derived-provide-spec

See define-provide-syntax +for information on expanding the set of provide-spec forms.

Each export specified within a module must have a distinct symbolic +export name, though the same binding can be specified with the +multiple symbolic names.

syntax

(for-meta phase-level require-spec ...)

See require and provide. +

syntax

(for-syntax require-spec ...)

See require and provide.

syntax

(for-template require-spec ...)

See require and provide. +

syntax

(for-label require-spec ...)

See require and provide. +

syntax

(for-space space require-spec ...)

See require and provide.

syntax

(#%require raw-require-spec ...)

 
raw-require-spec = phaseless-spec
  | (for-meta phase-level raw-require-spec ...)
  | (for-syntax raw-require-spec ...)
  | (for-template raw-require-spec ...)
  | (for-label raw-require-spec ...)
  | (just-meta phase-level raw-require-spec ...)
  | (portal portal-id content)
     
phase-level = exact-integer
  | #f
     
phaseless-spec = spaceless-spec
  | (for-space space phaseless-spec ...)
  | (just-space space spaceless-spec ...)
     
space = id
  | #f
     
spaceless-spec = raw-module-path
  | (only raw-module-path id ...)
  | (prefix prefix-id raw-module-path)
  | (all-except raw-module-path id ...)
  | 
(prefix-all-except prefix-id
                   raw-module-path id ...)
  | (rename raw-module-path local-id exported-id)
     
raw-module-path = raw-root-module-path
  | (submod raw-root-module-path id ...+)
  | (submod "." id ...+)
     
raw-root-module-path = (quote id)
  | rel-string
  | (lib rel-string ...)
  | id
  | (file string)
  | 
(planet rel-string
        (user-string pkg-string vers ...))
  | literal-path
The primitive import form, to which require expands. A +raw-require-spec is similar to a require-spec in a +require form, except that the syntax is more constrained, not +composable, and not extensible. Also, sub-form names like +for-syntax and lib are recognized +symbolically, instead of via bindings. Some nested constraints are not +formalized in the grammar above:

  • a just-meta form cannot appear within a +just-meta form;

  • a for-meta, for-syntax, +for-template, or for-label form +cannot appear within a for-meta, +for-syntax, for-template, or +for-label form; and

  • a for-space form cannot appear within a +for-space form.

  • a portal form cannot appear within a +just-meta form.

Except for the portal form, each +raw-require-spec corresponds to the obvious +require-spec, but the rename sub-form has the +identifiers in reverse order compared to rename-in.

For most raw-require-specs, the lexical context of the +raw-require-spec determines the context of introduced +identifiers. The exception is the rename sub-form, +where the lexical context of the local-id is preserved.

A literal-path as a raw-root-module-path corresponds +to a path in the sense of path?. Since path values are never +produced by read-syntax, they appear only in programmatically +constructed expressions. They also appear naturally as arguments to +functions such as namespace-require, with otherwise take a +quoted raw-module-spec.

The portal form provides a way to define portal +syntax at any phase level. A (portal portal-id content), defines portal-id to portal syntax with +content effectively quoted to serve as its content.

Changed in version 8.2.0.3 of package base: Added for-space +and just-space.
Changed in version 8.3.0.8: Added portal.

syntax

(#%provide raw-provide-spec ...)

 
raw-provide-spec = phaseless-spec
  | (for-meta phase-level phaseless-spec ...)
  | (for-syntax phaseless-spec ...)
  | (for-label phaseless-spec ...)
  | (protect raw-provide-spec ...)
     
phase-level = exact-integer
  | #f
     
phaseless-spec = spaceless-spec
  | (for-space space spaceless-spec ...)
  | (protect phaseless-spec ...)
     
space = id
  | #f
     
spaceless-spec = id
  | (rename local-id export-id)
  | (struct struct-id (field-id ...))
  | (all-from raw-module-path)
  | (all-from-except raw-module-path id ...)
  | (all-defined)
  | (all-defined-except id ...)
  | (prefix-all-defined prefix-id)
  | (prefix-all-defined-except prefix-id id ...)
  | (protect spaceless-spec ...)
  | (expand (id . datum))
  | (expand (id . datum) orig-form)
The primitive export form, to which provide expands. A +raw-module-path is as for #%require. A +protect sub-form cannot appear within a +protect sub-form.

Like #%require, the sub-form keywords for #%provide +are recognized symbolically, and nearly every +raw-provide-spec has an obvious equivalent +provide-spec via provide, with the exception of the +struct and expand sub-forms.

A (struct struct-id (field-id ...)) +sub-form expands to struct-id, +make-struct-id, +struct:struct-id, +struct-id?, +struct-id-field-id for each +field-id, and +set-struct-id-field-id! +for each field-id. The lexical context of the +struct-id is used for all generated identifiers.

Unlike #%require, the #%provide form is +macro-extensible via an explicit expand sub-form; the +(id . datum) part is locally expanded as an expression (even +though it is not actually an expression), stopping when a +begin form is produced; if the expansion result is +(begin raw-provide-spec ...), it is spliced in place of the +expand form, otherwise a syntax error is reported. +If an orig-form part is provided, then it is used instead of the +#%provide form when raising syntax errors, such as a +“provide identifier is not defined” error. The expand +sub-form is not normally used directly; it provides a hook for +implementing provide and provide transformers.

The all-from and all-from-except forms +re-export only identifiers that are accessible in lexical context of +the all-from or all-from-except form +itself. That is, macro-introduced imports are not re-exported, unless +the all-from or all-from-except form was +introduced at the same time. Similarly, all-defined and +its variants export only definitions accessible from the lexical +context of the spaceless-spec form.

Changed in version 8.2.0.3 of package base: Added for-space.
Changed in version 8.2.0.5: Added orig-form support +to expand.

3.2.1 Additional require Forms

The bindings documented in this section are provided by the racket/require library, not racket/base or racket.

The following forms support more complex selection and manipulation of +sets of imported identifiers.

syntax

(matching-identifiers-in regexp require-spec)

Like require-spec, but including only imports whose names + match regexp. The regexp must be a literal regular + expression (see Regular Expressions).

Examples:
> (module zoo racket/base
    (provide tunafish swordfish blowfish
             monkey lizard ant)
    (define tunafish 1)
    (define swordfish 2)
    (define blowfish 3)
    (define monkey 4)
    (define lizard 5)
    (define ant 6))
> (require racket/require)
> (require (matching-identifiers-in #rx"\\w*fish" 'zoo))
> tunafish

1

> swordfish

2

> blowfish

3

> monkey

monkey: undefined;

 cannot reference an identifier before its definition

  in module: top-level

syntax

(subtract-in require-spec subtracted-spec ...)

Like require-spec, but omitting those imports that would be + imported by one of the subtracted-specs.

Examples:
> (module earth racket
    (provide land sea air)
    (define land 1)
    (define sea 2)
    (define air 3))
> (module mars racket
    (provide aliens)
    (define aliens 4))
> (module solar-system racket
    (require 'earth 'mars)
    (provide (all-from-out 'earth)
             (all-from-out 'mars)))
> (require racket/require)
> (require (subtract-in 'solar-system 'earth))
> land

land: undefined;

 cannot reference an identifier before its definition

  in module: top-level

> aliens

4

syntax

(filtered-in proc-expr require-spec)

Applies an arbitrary transformation on the import names (as strings) +of require-spec. The proc-expr must evaluate at +expansion time to a single-argument procedure, which is applied on +each of the names from require-spec. For each name, the +procedure must return either a string for the import’s new name or +#f to exclude the import.

For example, +
(require (filtered-in
          (lambda (name)
            (and (regexp-match? #rx"^[a-z-]+$" name)
                 (regexp-replace #rx"-" (string-titlecase name) "")))
          racket/base))
imports only bindings from racket/base that match the +pattern #rx"^[a-z-]+$", and it converts the names to “camel case.”

syntax

(path-up rel-string ...)

Specifies paths to modules named by the rel-strings similar +to using the rel-strings directly, except that if a required +module file is not found relative to the enclosing source, it is +searched for in the parent directory, and then in the grand-parent +directory, etc., all the way to the root directory. The discovered +path relative to the enclosing source becomes part of the expanded +form.

This form is useful in setting up a “project environment.” For +example, using the following "config.rkt" file in the root +directory of your project: +
#lang racket/base
(require racket/require-syntax
         (for-syntax "utils/in-here.rkt"))
 
(provide utils-in)
(define-require-syntax utils-in in-here-transformer)
and using "utils/in-here.rkt" under the same root directory: +
#lang racket/base
(require racket/runtime-path)
(provide in-here-transformer)
(define-runtime-path here ".")
(define (in-here-transformer stx)
  (syntax-case stx ()
    [(_ sym)
     (identifier? #'sym)
     (let ([path (build-path here (format "~a.rkt" (syntax-e #'sym)))])
       (datum->syntax stx `(file ,(path->string path)) stx))]))
then path-up works for any other module under the project + directory to find "config.rkt": +
(require racket/require
         (path-up "config.rkt")
         (utils-in foo))
Note that the order of requires in the example is important, as each of +the first two bind the identifier used in the following.

An alternative in this scenario is to use path-up directly to +find the utility module: +
(require racket/require
         (path-up "utils/foo.rkt"))
but then sub-directories that are called +"utils" override the one in the project’s root. +In other words, the previous method requires only a single unique name.

syntax

(multi-in subs ...+)

 
subs = sub-path
  | (sub-path ...)
     
sub-path = rel-string
  | id
Specifies multiple files to be required from a hierarchy of +directories or collections. The set of required module paths is computed +as the Cartesian product of the subs groups, where each +sub-path is combined with other sub-paths in order +using a / separator. A sub-path as a subs +is equivalent to (sub-path). All sub-paths in a given +multi-in form must be either strings or identifiers.

Examples:

(require (multi-in racket (dict list)))

   is equivalent to 

(require racket/dict racket/list)

 

(require (multi-in "math" "matrix" "utils.rkt"))

   is equivalent to 

(require "math/matrix/utils.rkt")

 

(require (multi-in "utils" ("math.rkt" "matrix.rkt")))

   is equivalent to 

(require "utils/math.rkt" "utils/matrix.rkt")

 

(require (multi-in ("math" "matrix") "utils.rkt"))

   is equivalent to 

(require "math/utils.rkt" "matrix/utils.rkt")

 

(require (multi-in ("math" "matrix") ("utils.rkt" "helpers.rkt")))

   is equivalent to 

(require "math/utils.rkt" "math/helpers.rkt"
         "matrix/utils.rkt" "matrix/helpers.rkt")

3.2.2 Additional provide Forms

The bindings documented in this section are provided by the racket/provide library, not racket/base or racket.

syntax

(matching-identifiers-out regexp provide-spec)

Like +provide-spec, but including only exports of bindings with +an external name that matches regexp. The regexp +must be a literal regular expression (see Regular Expressions).

syntax

(filtered-out proc-expr provide-spec)

Analogous to filtered-in, but for filtering and renaming +exports.

For example, +
(provide (filtered-out
          (lambda (name)
            (and (regexp-match? #rx"^[a-z-]+$" name)
                 (regexp-replace
                  #rx"-" (string-titlecase name) "")))
          (all-defined-out)))
exports only bindings that match the + pattern #rx"^[a-z-]+$", and it converts the names to “camel case.”

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/running-sa.html b/clones/docs.racket-lang.org/reference/running-sa.html new file mode 100644 index 00000000..c3fa534f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/running-sa.html @@ -0,0 +1,336 @@ + +18.1 Running Racket or GRacket

18.1 Running Racket or GRacket

The core Racket run-time system is available in two main variants:

  • Racket, which provides the primitives libraries on which +racket/base is implemented. On Unix and Mac +OS, the executable is called +racket. On Windows, the executable is +called Racket.exe.

  • GRacket, which is a GUI variant of racket to the degree +that the system distinguishes them. On Unix, the executable +is called gracket, and single-instance flags +and X11-related flags are handled and communicated specially to +the racket/gui/base library. On Windows, the +executable is called GRacket.exe, and it is a +GUI application (as opposed to a console application) that +implements single-instance support. On Mac OS, the +gracket script launches GRacket.app.

18.1.1 Initialization

On start-up, the top-level environment contains no bindings—not even +#%app for function application. Primitive modules with names +that start with #% are defined, but they are not meant +for direct use, and the set of such modules can change. For example, +the '#%kernel module is eventually used to bootstrap +the implementation of racket/base.

The first action of Racket or GRacket is to initialize +current-library-collection-paths to the result of +(find-library-collection-paths pre-extras extras), where +pre-extras is normally null and extras +are extra directory paths provided in order in the command line with +-S/--search. An executable created from the Racket or +GRacket executable can embed paths used as pre-extras.

Racket and GRacket next require racket/init +and racket/gui/init, respectively, but only if the +command line does not specify a require flag +(-t/--require, -l/--lib, or +-u/--require-script) before any eval, +load, or read-eval-print-loop flag (-e/--eval, +-f/--load, -r/--script, -m/--main, +or -i/--repl). The initialization library can be changed +with the -I configuration option. The +configure-runtime submodule of the initialization library or the +'configure-runtime property of the initialization library’s +language is used before the library is instantiated; see +Language Run-Time Configuration.

After potentially loading the initialization module, expression +evals, files loads, and module requires are +executed in the order that they are provided on the command line. If +any raises an uncaught exception, then the remaining evals, +loads, and requires are skipped. If the first +require precedes any eval or load so that +the initialization library is skipped, then the configure-runtime +submodule of the required module or the +'configure-runtime property of the required module’s library +language is used before the module is instantiated; see +Language Run-Time Configuration.

After running all command-line expressions, files, and modules, Racket +or GRacket then starts a read-eval-print loop for interactive +evaluation if no command line flags are provided other than +configuration options. For Racket, the read-eval-print loop is +run by calling read-eval-print-loop from +racket/repl. For GRacket, the read-eval-print loop is +run by calling graphical-read-eval-print-loop from +racket/gui/base. If any command-line argument is +provided that is not a configuration option, then the +read-eval-print-loop is not started, unless the -i/--repl +flag is provided on the command line to +specifically re-enable it.

In addition, just before the read-eval-print loop +is started, Racket runs racket/interactive +and GRacket runs racket/gui/interactive, unless a different +interactive file is specified in the the installation’s "config.rktd" +file found in (find-config-dir), or the file "interactive.rkt" +is found in (find-system-path 'addon-dir). If the +-q/--no-init-file flag is specified on the command line, +then no interactive file is run.

Finally, before Racket or GRacket exits, it calls the procedure that +is the current value of executable-yield-handler in the main +thread, unless the -V/--no-yield command-line flag is +specified. Requiring racket/gui/base sets this parameter call +(racket 'yield).

Changed in version 6.7 of package base: Run racket/interactive file +rather than directly running (find-system-path 'init-file).
Changed in version 6.90.0.30: Run a read-eval-print loop by +using racket/repl or racket/gui/base +instead of racket/base or racket/gui/init.

18.1.2 Exit Status

The default exit status for a Racket or GRacket process is non-zero if +an error occurs during a command-line eval (via -e, +etc.), load (via -f, -r, etc.), or +require (via -l, -t, etc.)—or, more generally, +if the abort handler of the prompt surrounding those evalutions +is called—but only when no +read-eval-print loop is started. Otherwise, the default exit status is +0.

In all cases, a call to exit (when the default exit +handler is in place) can end the process with a specific status +value.

18.1.3 Init Libraries

 (require racket/init) package: base
The +racket/init library is the default start-up +library for Racket. It re-exports the +racket, racket/enter and +racket/help libraries, and it sets +current-print to use pretty-print.

The racket/interactive is the default start +up library when the REPL begins. It is not run if the +-q/--no-init-file is specified. The interactive +file can be changed by modifying 'interactive-file in the +"config.rktd" file found in +(find-config-dir). Alternative, if the file +"interactive.rkt" exists in +(find-system-path 'addon-dir) it is run rather +than the installation wide interactive module.
The default interactive module starts xrepl and +runs the (find-system-path 'init-file) file in the users home directory. A +different interactive file can keep this behavior by +requiring racket/interactive.

Added in version 6.7 of package base.

The +racket/language-info library provides a +get-info function that takes any value and returns +another function; the returned function takes a key value and a +default value, and it returns '(#(racket/runtime-config configure #f)) if the key is 'configure-runtime or the +default value otherwise.

+See also Module-Handling Configuration in The Racket Guide.

The vector '#(racket/language-info get-info #f) is suitable +for attaching to a module as its language info to get the same +language information as the racket/base language.

The +racket/runtime-config library provides a +configure function that takes any value +and sets print-as-expression +to #t.

The vector #(racket/runtime-config configure #f) is suitable +as a member of a list of runtime-configuration specification (as +returned by a module’s language-information function for the key +'configure-runtime) to obtain the same runtime configuration as +for the racket/base language.

18.1.4 Command Line

The Racket and GRacket executables recognize the following command-line +flags:

  • File and expression options:

    • -e expr or --eval +expr : evals expr. The results of +the evaluation are printed via current-print.

    • -f file or --load +file : loads file; if +file is "-", then expressions are read and +evaluated from standard input.

    • -t file or --require +file : requires file, and then +requires (submod (file "file") main) if available.

    • -l path or --lib +path : requires (lib "path"), and then requires +(submod (lib "path") main) if available.

    • -p package : +requires (planet "package"), +and then + requires (submod (planet "package") main) if available.

    • -r file or --script + file : loads file +Despite its name, --script is not usually +used for Unix scripts. See Scripts for more +information on scripts. + as a script. This flag is like -t file plus + -N file to set the program name and -- + to cause all further command-line elements to be treated as + non-flag arguments.

    • -u file or --require-script +file : requires file as a script; +This flag is like -t file plus -N +file to set the program name and -- to cause +all further command-line elements to be treated as non-flag +arguments.

    • -k n m p : Loads code +embedded in the executable from file position n to +m and from m to p. (On Mac OS, +n, m, and p are relative to a +__PLTSCHEME segment in the executable. On Windows, +they are relative to a resource of type 257 and ID 1. On Unix +using ELF, they are relative to the .rackprog segment +in the executable.) The first range +is loaded in every new place, and any modules declared +in that range are considered predefined in the sense of +module-predefined?. This option is normally embedded +in a stand-alone binary that also embeds Racket code.

    • -Y file n m p : +Like -k n m p, but reading +from file (without any adjustment +for a segment or resource offset).

    • -m or --main : Evaluates a call to +main as bound in the top-level environment. All +of the command-line arguments that are not processed as +options (i.e., the arguments put into +current-command-line-arguments) are passed as +arguments to main. The results of the call are +printed via current-print.

      The call to main is constructed as an +expression (main arg-str ...) where the lexical context of the expression gives +#%app and #%datum bindings as +#%plain-app and #%datum, but the lexical +context of main is the top-level environment.

  • Interaction options:

  • Configuration options:

    • -y or --make : Enables automatic +generation and update of compiled ".zo" files for +modules loaded in the initial namespace. Specifically, the +result of +(make-compilation-manager-load/use-compiled-handler) +is installed as the compiled-load handler before other +module-loading actions. Caution: This flag is intended +for use in interactive settings; using it in a script is +probably a bad idea, because concurrent invocations of the +script may collide attempting to update compiled files, or +there may be filesystem-permission issues. Using +-c/--no-compiled cancels the effect of +-y/--make.

    • -c or --no-compiled : Disables loading +of compiled ".zo" files, by initializing +use-compiled-file-paths to null. +Use judiciously: this effectively ignores the content of all +"compiled" subdirectories, so that any used modules are +compiled on the fly—even racket/base and +its dependencies—which leads to prohibitively expensive +run times.

    • -q or --no-init-file : Skips loading +(find-system-path 'init-file) for +-i/--repl.

    • -z or --text-repl : GRacket only; changes +-i/--repl to use +textual-read-eval-print-loop instead of +graphical-read-eval-print-loop.

    • -I path : Sets (lib "path") as the path to require to initialize +the namespace, unless namespace initialization is disabled. Using +this flag can effectively set the language for the read-eval-print +loop and other top-level evaluation.

    • -X dir or --collects +dir : Sets dir as the path to the main +collection of libraries by making (find-system-path 'collects-dir) produce dir. If dir is an +empty string, then (find-system-path 'collects-dir) +returns ".", but +current-library-collection-paths is initialized to +the empty list, and use-collection-link-paths is +initialized to #f.

    • -S dir or --search +dir : Adds dir to the default library +collection search path after the main collection directory. If +the -S/--dir flag is supplied multiple times, the +search order is as supplied.

    • -G dir or --config +dir : Sets the directory that is returned by +(find-system-path 'config-dir).

    • -A dir or --addon +dir : Sets the directory that is returned by +(find-system-path 'addon-dir).

    • -U or --no-user-path : Omits +user-specific paths in the search for collections, C +libraries, etc. by initializing the +use-user-specific-search-paths parameter to +#f.

    • -A dir or --addon +dir : Sets the directory that is returned by +(find-system-path 'addon-dir).

    • -R paths or --compiled +paths : Sets the initial value of the +current-compiled-file-roots parameter, overriding +any PLTCOMPILEDROOTS setting. The paths +argument is parsed in the same way as PLTCOMPILEDROOTS +(see current-compiled-file-roots).

    • -C or --cross : Select cross-platform +build mode, causing (system-type 'cross) to report +'force, and sets the current configuration of +(find-system-path 'config-dir) and +(find-system-path 'collects-dir) to be the results of +(find-system-path 'host-config-dir) and +(find-system-path 'host-collects-dir), respectively. +If -C or --cross is provided multiple +times, only the first instance has an effect.

    • -N file or --name +file : sets the name of the executable as reported +by (find-system-path 'run-file) to +file.

    • -E file or --exe +file : sets the name of the executable as reported +by (find-system-path 'exec-file) to +file.

    • -J name or --wm-class +name : GRacket, Unix only; sets the WM_CLASS +program class to name (while the WM_CLASS +program name is derived from the executable name or a +-N/--name argument).

    • -j or --no-jit : Disables the +native-code just-in-time compiler by setting the +eval-jit-enabled parameter to #f.

    • -M or --compile-any : Enables +machine-independent bytecode by setting the +current-compile-target-machine parameter to +#f.

    • -d or --no-delay : Disables on-demand +parsing of compiled code and syntax objects by setting the +read-on-demand-source parameter to #f.

    • -b or --binary : Requests binary mode, +instead of text mode, for the process’s input, out, and error +ports. This flag currently has no effect, because binary mode +is always used.

    • -W levels or --warn +levels : Sets the logging level for writing events to +the original error port. The possible level values +are the same as for the PLTSTDERR environment +variable. See Logging for more information.

    • -O levels or --stdout +levels : Sets the logging level for writing events to +the original output port. The possible level values +are the same as for the PLTSTDOUT environment +variable. See Logging for more information.

    • -L levels or --syslog +levels : Sets the logging level for writing events to +the system log. The possible level values +are the same as for the PLTSYSLOG environment +variable. See Logging for more information.

  • Meta options:

    • -Z : The argument following this flag is ignored. +This flag can be handy in some impoverished scripting environments +to replace or cancel another command-line argument.

    • -- : No argument following this flag is itself used +as a flag.

    • -h or --help : Shows information about +the command-line flags and start-up process and exits, +ignoring all other flags.

If at least one command-line argument is provided, and if the first +one after any configuration option is not a flag, then a +-u/--require-script flag is implicitly added before the +first non-flag argument.

If no command-line arguments are supplied other than +configuration options, then the -i/--repl flag is +effectively added.

For GRacket on Unix, the follow flags are recognized when they appear +at the beginning of the command line, and they count as configuration +options (i.e., they do not disable the read-eval-print loop or prevent +the insertion of -u/--require-script):

  • -display display : Sets the X11 display +to use.

  • -geometry arg, -bg +arg, -background arg, +-fg arg, -foreground +arg, -fn arg, -font +arg, -iconic, -name +arg, -rv, -reverse, ++rv, -selectionTimeout arg, +-synchronous, -title arg, +-xnllanguage arg, or -xrm +arg : Standard X11 arguments that are mostly ignored +but accepted for compatibility with other X11 programs. The +-synchronous flag behaves in the usual +way.

  • -singleInstance : If an existing GRacket is already +running on the same X11 display, if it was started on a +machine with the same hostname, and if it was started with the +same name as reported by (find-system-path 'run-file)possibly set with the -N/--name +command-line argument—then all non-option command-line +arguments are treated as filenames and sent to the existing +GRacket instance via the application file handler (see +application-file-handler).

Similarly, on Mac OS, a leading switch starting with +-psn_ is treated as a special configuration option. It +indicates that Finder started the application, so the current input, +output, and error output are redirected to a GUI window.

Multiple single-letter switches (the ones preceded by a single +-) can be collapsed into a single switch by concatenating +the letters, as long as the first switch is not --. The +arguments for each switch are placed after the collapsed switches (in +the order of the switches). For example,

  -ifve file expr

and

  -i -f file -v -e expr

are equivalent. If a collapsed -- appears before other collapsed +switches in the same collapsed set, it is implicitly moved to the end +of the collapsed set.

Extra arguments following the last option are available from the +current-command-line-arguments parameter.

Changed in version 6.90.0.17 of package base: Added -O/--stdout.
Changed in version 7.1.0.5: Added -M/--compile-any.
Changed in version 7.8.0.6: Added -Z.
Changed in version 8.0.0.10: Added -E.
Changed in version 8.0.0.11: Added -Y.
Changed in version 8.4.0.1: Added -y/--make.

18.1.5 Language Run-Time Configuration

+See also Module-Handling Configuration in The Racket Guide.

A module can have a configure-runtime submodule that is +dynamic-required before the module itself when a module is +the main module of a program. Normally, a configure-runtime +submodule is added to a module by the module’s language (i.e., by the +#%module-begin form among a module’s initial +bindings). The body of a configure-runtime submodule +typically sets parameters, possibly including +current-interaction-info.

Alternatively or in addition, an older protocol is in place. +When a module is implemented using #lang, the language after +#lang can specify configuration actions to perform when a +module using the language is the main module of a program. The +language specifies run-time configuration by

  • attaching a 'module-language syntax property to +the module as read from its source (see module and +module-compiled-language-info);

  • having the function indicated by the 'module-language +syntax property recognize the +'configure-runtime key, for which it returns a list of +vectors; each vector must have the form (vector mp name val) where mp is a module path, +name is a symbol, and val is an arbitrary +value; and

  • having each function called as ((dynamic-require mp name) val) configure the run-time environment, typically by +setting parameters such as current-print.

A 'configure-runtime query returns a list of vectors, instead +of directly configuring the environment, so that the indicated modules +to be bundled with a program when creating a stand-alone executable; +see raco exe: Creating Stand-Alone Executables in +raco: Racket Command-Line Tools.

For information on defining a new #lang language, see +syntax/module-reader.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/running.html b/clones/docs.racket-lang.org/reference/running.html new file mode 100644 index 00000000..60cb227c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/running.html @@ -0,0 +1,2 @@ + +18 Running Racket
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/runtime.html b/clones/docs.racket-lang.org/reference/runtime.html new file mode 100644 index 00000000..94a1833e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/runtime.html @@ -0,0 +1,113 @@ + +15.8 Environment and Runtime Information

15.8 Environment and Runtime Information

procedure

(system-type [mode])

  (or/c symbol? string? bytes? exact-positive-integer? vector? #f)
  mode : 
(or/c 'os 'os* 'arch 'word 'vm 'gc 'link 'machine 'target-machine
      'so-suffix 'so-mode 'fs-change 'cross)
   = 'os
Returns information about the operating system, build mode, or machine +for a running Racket. (Installation tools should use cross-system-type, +instead, to support cross-installation.)

In 'os mode, + the possible symbol results are:

  • 'unix

  • 'windows

  • 'macosx

Prior to the introduction of 'os* and +'arch modes, (system-library-subpath #f) could be +used to obtain this information somewhat indirectly.

In 'os* mode, the result is similar to 'os +mode, but refined to a specific operating system, such as +'linux or 'freebsd, instead of a generic +'unix classification.

In 'arch mode, the result is a symbol representing an +architecture. Possible results include 'x86_64, 'i386, +'aarch64, 'arm (32-bit), and 'ppc (32-bit).

In 'word mode, the result is either 32 or +64 to indicate whether Racket is running as a 32-bit program +or 64-bit program.

See Racket Virtual Machine Implementations for more information +about the 'vm and 'gc mode results.

In 'vm mode, +the possible symbol results are (see also Implementations):

  • 'racket

  • 'chez-scheme

In 'gc mode, +the possible symbol results are (see also Implementations):

In 'link mode, the possible symbol results are:

  • 'static (Unix)

  • 'shared (Unix)

  • 'dll (Windows)

  • 'framework (Mac OS)

Future ports of Racket may expand the list of 'os, 'os*, +'arch, 'vm, 'gc, and 'link results.

In 'machine mode, then the result is a string, which +contains further details about the current machine in a +platform-specific format.

In 'target-machine mode, the result is a symbol for +the running Racket’s native bytecode format, or it is #f if +there is no native format other than the machine-independent format. +If the result is a symbol, then compile-target-machine? returns +#t when applied to the symbol; see also +current-compile-target-machine.

In 'so-suffix mode, then the result is a byte string +that represents the file extension used for shared objects on the +current platform. The byte string starts with a period, so it is +suitable as a second argument to path-replace-suffix.

In 'so-mode mode, then the result is 'local +if foreign libraries should be opened in “local” mode by default +(as on most platforms) or 'global if foreign libraries +should be opened in “global” mode.

In 'fs-change mode, the result is an immutable vector +of four elements. Each element is either #f or a symbol, +where a symbol indicates the presence of a property and #f +indicates the absence of a property. The possible symbols, in order, +are:

  • 'supported filesystem-change-evt +can produce a filesystem change event to monitor filesystem changes; +if this symbol is not first in the vector, all other vector elements +are #f

  • 'scalable resources consumed by a +filesystem change event are effectively limited only by +available memory, as opposed to file-descriptor limits; this property +is #f on Mac OS and BSD variants of Unix

  • 'low-latency creation and checking of a +filesystem change event is practically instantaneous; this +property is #f on Linux

  • 'file-level a filesystem change +event can track changes at the level of a file, as opposed to the +file’s directory; this property is #f on Windows

In 'cross mode, the result reports whether +cross-platform build mode has been selected (through the -C or +--cross argument to racket; see Command Line). +The possible symbols are:

  • 'infer infer cross-platform mode based on +whether (system-type) and (cross-system-type) report +the same symbol

  • 'force use cross-platform mode, even if the +current and target system types are the same, because the current and target +executables can be different

Changed in version 6.8.0.2 of package base: Added 'vm mode.
Changed in version 6.9.0.1: Added 'cross mode.
Changed in version 7.1.0.6: Added 'target-machine mode.
Changed in version 7.9.0.6: Added 'os* and 'arch modes.

Returns a string to identify the current user’s language and +country.

On Unix and Mac OS, the string is five characters: two lowercase +ASCII letters for the language, an underscore, and two uppercase ASCII +letters for the country. On Windows, the string can be arbitrarily +long, but the language and country are in English (all ASCII letters +or spaces) separated by an underscore.

On Unix, the result is determined by checking the +LC_ALL, LC_TYPE, and +LANG environment variables, in that order (and the +result is used if the environment variable’s value starts with two +lowercase ASCII letters, an underscore, and two uppercase ASCII +letters, followed by either nothing or a period). On Windows and +Mac OS, the result is determined by system calls.

procedure

(system-library-subpath [mode])  path?

  mode : (or/c 'cgc '3m 'cs #f) = (system-type 'gc)
Returns a relative directory path. This string can be used to build +paths to system-specific files. For example, when Racket is running +on Solaris on a Sparc architecture, the subpath starts +"sparc-solaris", while the subpath for Windows on an i386 +architecture starts "win32\\i386".

The optional mode argument specifies the relevant +garbage-collection variant, which one of the possible results of +(system-type 'gc): 'cgc, '3m, or 'cs. It can also +be #f, in which case the result is independent of the +garbage-collection variant.

Installation tools should use cross-system-library-subpath, +instead, to support cross-installation.

Changed in version 7.0 of package base: Added 'cs mode.

procedure

(version)  (and/c string? immutable?)

Returns an immutable string indicating the currently executing version of +Racket.

procedure

(banner)  (and/c string? immutable?)

Returns an immutable string for Racket’s start-up banner text (or the +banner text for an embedding program, such as GRacket). The banner string +ends with a newline.

A parameter that is initialized with command-line arguments when +Racket starts (not including any command-line arguments that were +treated as flags for the system).

On Unix and Mac OS, command-line arguments are provided to the +Racket process as byte strings. The arguments are converted to +strings using bytes->string/locale and +#\uFFFD as the encoding-error character.

A parameter that provides a hint about how much space to reserve for a +newly created thread’s local variables. The actual space used by a +computation is affected by JIT compilation, but it is +otherwise platform-independent.

procedure

(vector-set-performance-stats! results [thd])  void?

  results : 
(and/c vector?
       (not/c immutable?))
  thd : (or/c thread? #f) = #f
Sets elements in results to report current performance +statistics. If thd is not #f, a particular set of +thread-specific statistics are reported, otherwise a different set of +global (within the current place) statistics are reported.

For global statistics, up to 12 elements are set in the vector, +starting from the beginning. If results has n elements +where n < 12, then the n elements are set to the first +n performance-statistics values. The reported statistics values +are as follows, in the order that they are set within +results:

  • 0: The same value as returned by +current-process-milliseconds.

  • 1: The same value as returned +by current-milliseconds.

  • 2: The same value as returned +by current-gc-milliseconds.

  • 3: The number of garbage collections performed since +start-up within the current place.

  • 4: The number of thread context switches performed since +start-up.

  • 5: The number of internal stack overflows handled since +start-up.

  • 6: The number of threads currently scheduled for +execution (i.e., threads that are running, not suspended, and not +unscheduled due to a synchronization).

  • 7: The number of syntax objects read from compiled code +since start-up.

  • 8: The number of hash-table searches performed. When +this counter reaches the maximum value of a fixnum, it +overflows to the most negative fixnum.

  • 9: The number of additional hash slots searched to +complete hash searches (using double hashing). When this counter +reaches the maximum value of a fixnum, it overflows to the +most negative fixnum.

  • 10: The number of bytes allocated for machine code +that is not reported by current-memory-use.

  • 11: The peak number of allocated bytes just +before a garbage collection.

For thread-specific statistics, up to 4 elements are set in the +vector:

  • 0: #t if the thread is running, #f +otherwise (same result as thread-running?).

  • 1: #t if the thread has terminated, +#f otherwise (same result as thread-dead?).

  • 2: #t if the thread is currently blocked on a +synchronizable event (or sleeping for some number of milliseconds), +#f otherwise.

  • 3: The number of bytes currently in use for the +thread’s continuation.

Changed in version 6.1.1.8 of package base: Added vector position 11 for global statistics.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/security.html b/clones/docs.racket-lang.org/reference/security.html new file mode 100644 index 00000000..851c8177 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/security.html @@ -0,0 +1,2 @@ + +14 Reflection and Security
 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/securityguards.html b/clones/docs.racket-lang.org/reference/securityguards.html new file mode 100644 index 00000000..57f2aa0b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/securityguards.html @@ -0,0 +1,59 @@ + +14.6 Security Guards

14.6 Security Guards

procedure

(security-guard? v)  boolean?

  v : any/c
Returns #t if v is a security guard value as created +by make-security-guard, #f otherwise.

A security guard provides a set of access-checking +procedures to be called when a thread initiates access of a file, +directory, or network connection through a primitive procedure. For +example, when a thread calls open-input-file, the thread’s +current security guard is consulted to check whether the thread is +allowed read access to the file. If access is granted, the thread +receives a port that it may use indefinitely, regardless of changes to +the security guard (although the port’s custodian could shut down the +port; see Custodians).

A thread’s current security guard is determined by the +current-security-guard parameter. Every security guard has a +parent, and a parent’s access procedures are called whenever a child’s +access procedures are called. Thus, a thread cannot increase its own +access arbitrarily by installing a new guard. The initial security +guard enforces no access restrictions other than those enforced by the +host platform.

procedure

(make-security-guard parent    
  file-guard    
  network-guard    
  [link-guard])  security-guard?
  parent : security-guard?
  file-guard : 
(symbol?
 (or/c path? #f)
 (listof symbol?)
 . -> . any)
  network-guard : 
(symbol?
 (or/c (and/c string? immutable?) #f)
 (or/c (integer-in 1 65535) #f)
 (or/c 'server 'client)
 . -> . any)
  link-guard : (or/c (symbol? path? path? . -> . any) #f) = #f
Creates a new security guard as child of parent.

The file-guard procedure must accept three arguments:

  • a symbol for the primitive procedure that triggered the access +check, which is useful for raising an exception to deny access.

  • a path (see Paths) or #f for +pathless queries, such as (current-directory), +(filesystem-root-list), and (find-system-path symbol). A path provided to file-guard is not expanded or +otherwise normalized before checking access; it may be a relative +path, for example.

  • a list containing one or more of the following + symbols:

    • 'read read a file or directory

    • 'write modify or create a file or +directory

    • 'execute execute a file

    • 'delete delete a file or directory

    • 'exists determine whether a file or +directory exists, or that a path string is well-formed

    The 'exists symbol is never combined with other symbols in +the last argument to file-guard, but any other combination is +possible. When the second argument to file-guard is #f, +the last argument always contains only 'exists.

The network-guard procedure must accept four arguments:

  • a symbol for the primitive operation that triggered the access +check, which is useful for raising an exception to deny access.

  • an immutable string representing the target hostname for a +client connection or the accepting hostname for a listening server; +#f for a listening server or UDP socket that accepts +connections at all of the host’s address; or #f an unbound +UDP socket.

  • an exact integer between 1 and 65535 +(inclusive) representing the port number, or #f for an +unbound UDP socket. In the case of a client connection, the port +number is the target port on the server. For a listening server, the +port number is the local port number.

  • a symbol, either 'client or +'server, indicating whether the check is for the +creation of a client connection or a listening server. The opening of +an unbound UDP socket is identified as a 'client connection; +explicitly binding the socket is identified as a 'server +action.

The link-guard argument can be #f or a procedure of +three arguments:

  • a symbol for the primitive procedure that triggered the access +check, which is useful for raising an exception to deny access.

  • a complete path (see Paths) representing the +file to create as link.

  • a path representing the content of the link, which may be +relative the second-argument path; this path is not expanded or +otherwise normalized before checking access.

If link-guard is #f, then a default +procedure is used that always raises exn:fail.

The return value of file-guard, network-guard, or +link-guard is ignored. To deny access, the procedure must +raise an exception or otherwise escape from the context of the +primitive call. If the procedure returns, the parent’s corresponding +procedure is called on the same inputs, and so on up the chain of +security guards.

The file-guard, network-guard, and +link-guard procedures are invoked in the thread that called +the access-checked primitive. Breaks may or may not be enabled (see +Breaks). Full continuation jumps are blocked going +into or out of the file-guard or network-guard call +(see Prompts, Delimited Continuations, and Barriers).

A parameter that determines the current security guard that controls +access to the filesystem and network.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/semaphore.html b/clones/docs.racket-lang.org/reference/semaphore.html new file mode 100644 index 00000000..150f09ab --- /dev/null +++ b/clones/docs.racket-lang.org/reference/semaphore.html @@ -0,0 +1,52 @@ + +11.2.3 Semaphores
11.2.3 Semaphores

A semaphore has an internal counter; when this counter is +zero, the semaphore can block a thread’s execution (through +semaphore-wait) until another thread increments the counter +(using semaphore-post). The maximum value for a semaphore’s +internal counter is platform-specific, but always at least +10000.

A semaphore’s counter is updated in a single-threaded manner, so that +semaphores can be used for reliable synchronization. Semaphore waiting +is fair: if a thread is blocked on a semaphore and the +semaphore’s internal value is non-zero infinitely often, then the +thread is eventually unblocked.

In addition to its use with semaphore-specific procedures, a semaphore +can be used as a synchronizable event (see Events). +A semaphore is ready for synchronization when +semaphore-wait would not block. Upon synchronization, the +semaphore’s counter is decremented, and the synchronization result of a semaphore is the semaphore itself.

procedure

(semaphore? v)  boolean?

  v : any/c
Returns #t if v is a semaphore, +#f otherwise.

procedure

(make-semaphore [init])  semaphore?

  init : exact-nonnegative-integer? = 0
Creates and returns a new semaphore with the counter initially set to +init. If init is larger than a semaphore’s maximum +internal counter value, the exn:fail exception is raised.

procedure

(semaphore-post sema)  void?

  sema : semaphore?
Increments the +semaphore’s internal counter and returns #<void>. If the +semaphore’s internal counter has already reached its maximum value, +the exn:fail exception is raised.

procedure

(semaphore-wait sema)  void?

  sema : semaphore?
Blocks until the +internal counter for semaphore sema is non-zero. When the +counter is non-zero, it is decremented and semaphore-wait +returns #<void>.

procedure

(semaphore-try-wait? sema)  boolean?

  sema : semaphore?
Like +semaphore-wait, but semaphore-try-wait? never blocks +execution. If sema’s internal counter is zero, +semaphore-try-wait? returns #f immediately without +decrementing the counter. If sema’s counter is positive, it +is decremented and #t is returned.

procedure

(semaphore-wait/enable-break sema)  void?

  sema : semaphore?
Like +semaphore-wait, but breaking is enabled (see +Breaks) while waiting on sema. If +breaking is disabled when semaphore-wait/enable-break is +called, then either the semaphore’s counter is decremented or the +exn:break exception is raised, but not both.

procedure

(semaphore-peek-evt sema)  semaphore-peek-evt?

  sema : semaphore?
Creates and +returns a new synchronizable event (for use with sync, for +example) that is ready for synchronization when sema is ready, +but synchronizing +the event does not decrement sema’s internal count. +The synchronization result of a semaphore-peek event is the semaphore-peek event itself.

procedure

(semaphore-peek-evt? v)  boolean?

  v : any/c
Returns #t if v is a semaphore wrapper produced by +semaphore-peek-evt, #f otherwise.

procedure

(call-with-semaphore sema    
  proc    
  [try-fail-thunk]    
  arg ...)  any
  sema : semaphore?
  proc : procedure?
  try-fail-thunk : (or/c (-> any) #f) = #f
  arg : any/c
Waits on sema using semaphore-wait, calls +proc with all args, and then posts to +sema. A continuation barrier blocks full continuation jumps +into or out of proc (see Prompts, Delimited Continuations, and Barriers), but +escape jumps are allowed, and sema is posted on escape. If +try-fail-thunk is provided and is not #f, then +semaphore-try-wait? is called on sema instead of +semaphore-wait, and try-fail-thunk is called if the +wait fails.

procedure

(call-with-semaphore/enable-break sema    
  proc    
  [try-fail-thunk]    
  arg ...)  any
  sema : semaphore?
  proc : procedure?
  try-fail-thunk : (or/c (-> any) #f) = #f
  arg : any/c
Like call-with-semaphore, except that +semaphore-wait/enable-break is used with sema in +non-try mode. When try-fail-thunk is provided and not +#f, then breaks are enabled around the use of +semaphore-try-wait? on sema.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/sequences.html b/clones/docs.racket-lang.org/reference/sequences.html new file mode 100644 index 00000000..eeeaf41a --- /dev/null +++ b/clones/docs.racket-lang.org/reference/sequences.html @@ -0,0 +1,282 @@ + +4.16.1 Sequences
4.16.1 Sequences

+Sequence Constructors in The Racket Guide introduces sequences.

A sequence encapsulates an ordered collection of values. +The elements of a sequence can be extracted with one of the +for syntactic forms, with the procedures returned by +sequence-generate, or by converting the sequence into a +stream.

The sequence datatype overlaps with many other datatypes. Among +built-in datatypes, the sequence datatype includes the following:

An exact number k that is a non-negative +integer acts as a sequence similar to (in-range k), +except that k by itself is not a stream.

Custom sequences can be defined using structure type properties. The +easiest method to define a custom sequence is to use the +gen:stream generic interface. Streams are a suitable +abstraction for data structures that are directly iterable. For +example, a list is directly iterable with first and +rest. On the other hand, vectors are not directly iterable: +iteration has to go through an index. For data structures that are not +directly iterable, the iterator for the data structure can +be defined to be a stream (e.g., a structure containing the index of a +vector).

For example, unrolled linked lists (represented as a list of vectors) +themselves do not fit the stream abstraction, but have index-based +iterators that can be represented as streams:

Examples:
> (struct unrolled-list-iterator (idx lst)
    #:methods gen:stream
    [(define (stream-empty? iter)
       (define lst (unrolled-list-iterator-lst iter))
       (or (null? lst)
           (and (>= (unrolled-list-iterator-idx iter)
                    (vector-length (first lst)))
                (null? (rest lst)))))
     (define (stream-first iter)
       (vector-ref (first (unrolled-list-iterator-lst iter))
                   (unrolled-list-iterator-idx iter)))
     (define (stream-rest iter)
       (define idx (unrolled-list-iterator-idx iter))
       (define lst (unrolled-list-iterator-lst iter))
       (if (>= idx (sub1 (vector-length (first lst))))
           (unrolled-list-iterator 0 (rest lst))
           (unrolled-list-iterator (add1 idx) lst)))])
> (define (make-unrolled-list-iterator ul)
    (unrolled-list-iterator 0 (unrolled-list-lov ul)))
> (struct unrolled-list (lov)
    #:property prop:sequence
    make-unrolled-list-iterator)
> (define ul1 (unrolled-list '(#(cracker biscuit) #(cookie scone))))
> (for/list ([x ul1]) x)

'(cracker biscuit cookie scone)

The prop:sequence property provides more flexibility in +specifying iteration, such as when a pre-processing step is needed to +prepare the data for iteration. The make-do-sequence +function creates a sequence given a thunk that returns procedures to +implement a sequence, and the prop:sequence property can be +associated with a structure type to implement its implicit conversion +to a sequence.

For most sequence types, extracting elements from a sequence has no +side-effect on the original sequence value; for example, extracting +the sequence of elements from a list does not change the list. For +other sequence types, each extraction implies a side effect; for +example, extracting the sequence of bytes from a port causes the bytes +to be read from the port. A sequence’s state may either span all uses +of the sequence, as for a port, or it may be confined to each distinct +time that a sequence is initiated by a for form, +sequence->stream, sequence-generate, or +sequence-generate*. Concretely, the thunk passed to +make-do-sequence is called to initiate the sequence +each time the sequence is used. Accordingly, different sequences behave +differently when they are initiated multiple times.

> (define (double-initiate s1)
    ; initiate the sequence twice
    (define-values (more?.1 next.1) (sequence-generate s1))
    (define-values (more?.2 next.2) (sequence-generate s1))
    ; alternate fetching from sequence via the two initiations
    (list (next.1) (next.2) (next.1) (next.2)))
> (double-initiate (open-input-string "abcdef"))

'(97 98 99 100)

> (double-initiate (list 97 98 99 100))

'(97 97 98 98)

> (double-initiate (in-naturals 97))

'(97 97 98 98)

Also, subsequent elements in a sequence may be “consumed” just by calling the +first result of sequence-generate, even if the second +result is never called.

> (define (double-initiate-and-use-more? s1)
    ; initiate the sequence twice
    (define-values (more?.1 next.1) (sequence-generate s1))
    (define-values (more?.2 next.2) (sequence-generate s1))
    ; alternate fetching from sequence via the two initiations
    ; but this time call `more?` in between
    (list (next.1) (more?.1) (next.2) (more?.2)
          (next.1) (more?.1) (next.2) (more?.2)))
> (double-initiate-and-use-more? (open-input-string "abcdef"))

'(97 #t 99 #t 98 #t 100 #t)

In this example, the state embedded in the first call to sequence-generate +“takes” the 98 just by virtue of the invocation of more?.1.

Individual elements of a sequence typically correspond to single +values, but an element may also correspond to multiple values. For +example, a hash table generates two values—a key and its value—for +each element in the sequence.

4.16.1.1 Sequence Predicate and Constructors

procedure

(sequence? v)  boolean?

  v : any/c
Returns #t if v can be used as a sequence, + #f otherwise.

Examples:
> (sequence? 42)

#t

> (sequence? '(a b c))

#t

> (sequence? "word")

#t

> (sequence? #\x)

#f

procedure

(in-range end)  stream?

  end : real?
(in-range start end [step])  stream?
  start : real?
  end : real?
  step : real? = 1
Returns a sequence (that is also a stream) whose elements are +numbers. The single-argument case (in-range end) is +equivalent to (in-range 0 end 1). The first number in the +sequence is start, and each successive element is generated +by adding step to the previous element. The sequence stops +before an element that would be greater or equal to end if +step is non-negative, or less or equal to end if +step is negative.
An in-range application can provide better performance for number iteration when it appears directly in a for clause.

Example: gaussian sum
> (for/sum ([x (in-range 10)]) x)

45

Example: sum of even numbers
> (for/sum ([x (in-range 0 100 2)]) x)

2450

When given zero as step, in-range returns an infinite +sequence. It may also return infinite sequences when step is a very +small number, and either step or the sequence elements are +floating-point numbers.

procedure

(in-inclusive-range start end [step])  stream?

  start : real?
  end : real?
  step : real? = 1
Similar to in-range, but the sequence stopping condition is changed so that +the last element is allowed to be equal to end.
An in-inclusive-range application can provide better performance for number iteration when it appears directly in a for clause.

Examples:
> (sequence->list (in-inclusive-range 7 11))

'(7 8 9 10 11)

> (sequence->list (in-inclusive-range 7 11 2))

'(7 9 11)

> (sequence->list (in-inclusive-range 7 10 2))

'(7 9)

Added in version 8.0.0.13 of package base.

procedure

(in-naturals [start])  stream?

  start : exact-nonnegative-integer? = 0
Returns an infinite sequence (that is also a stream) of exact +integers starting with start, where each element is one +more than the preceding element.
An in-naturals application can provide better performance for integer iteration when it appears directly in a for clause.

Example:
> (for/list ([k (in-naturals)]
             [x (in-range 10)])
    (list k x))

'((0 0) (1 1) (2 2) (3 3) (4 4) (5 5) (6 6) (7 7) (8 8) (9 9))

procedure

(in-list lst)  stream?

  lst : list?
Returns a sequence (that is also a stream) that is equivalent + to using lst directly as a sequence. +

See Pairs and Lists for information on using lists as +sequences.

An in-list application can provide better performance for list iteration when it appears directly in a for clause.
See for for information on the reachability of list elements +during an iteration.

Example:
> (for/list ([x (in-list '(3 1 4))])
    `(,x ,(* x x)))

'((3 9) (1 1) (4 16))

Changed in version 6.7.0.4 of package base: Improved element-reachability guarantee for lists in for.

procedure

(in-mlist mlst)  sequence?

  mlst : mlist?
Returns a sequence equivalent to mlst. Although the +expectation is that mlst is mutable list, in-mlist +initially checks only whether mlst is a mutable pair or null, +since it could change during iteration. +

See Mutable Pairs and Lists for information on using mutable lists as +sequences.

An in-mlist application can provide better performance for mutable list iteration when it appears directly in a for clause.

Example:
> (for/list ([x (in-mlist (mcons "RACKET" (mcons "LANG" '())))])
    (string-length x))

'(6 4)

procedure

(in-vector vec [start stop step])  sequence?

  vec : vector?
  start : exact-nonnegative-integer? = 0
  stop : (or/c exact-integer? #f) = #f
  step : (and/c exact-integer? (not/c zero?)) = 1
Returns a sequence equivalent to vec when no optional +arguments are supplied.

See Vectors for information on using vectors as +sequences.

The optional arguments start, stop, and +step are analogous to in-range, except that a +#f value for stop is equivalent to +(vector-length vec). That is, the first element in the +sequence is (vector-ref vec start), and each successive +element is generated by adding step to index of the +previous element. The sequence stops before an index that would be +greater or equal to end if step is non-negative, +or less or equal to end if step is negative.

If start is not a valid index, then the +exn:fail:contract exception is raised, except when start, stop, and +(vector-length vec) are equal, in which case the result is an +empty sequence.

Examples:
> (for ([x (in-vector (vector 1) 1)]) x)
> (for ([x (in-vector (vector 1) 2)]) x)

in-vector: starting index is out of range

  starting index: 2

  valid range: [0, 0]

  vector: '#(1)

> (for ([x (in-vector (vector) 0 0)]) x)
> (for ([x (in-vector (vector 1) 1 1)]) x)

If stop is not in [-1, (vector-length vec)], +then the exn:fail:contract exception is raised.

If start is less than +stop and step is negative, then the +exn:fail:contract exception is raised. Similarly, if start +is more than stop and step is positive, then the +exn:fail:contract exception is raised.

An in-vector application can provide better performance for vector iteration when it appears directly in a for clause.

Examples:
> (define (histogram vector-of-words)
    (define a-hash (make-hash))
    (for ([word (in-vector vector-of-words)])
      (hash-set! a-hash word (add1 (hash-ref a-hash word 0))))
    a-hash)
> (histogram #("hello" "world" "hello" "sunshine"))

'#hash(("hello" . 2) ("sunshine" . 1) ("world" . 1))

procedure

(in-string str [start stop step])  sequence?

  str : string?
  start : exact-nonnegative-integer? = 0
  stop : (or/c exact-integer? #f) = #f
  step : (and/c exact-integer? (not/c zero?)) = 1
Returns a sequence equivalent to str when no optional +arguments are supplied.

See Strings for information on using strings as +sequences.

The optional arguments start, stop, and +step are as in in-vector.

An in-string application can provide better performance for string iteration when it appears directly in a for clause.

Examples:
> (define (line-count str)
    (for/sum ([ch (in-string str)])
      (if (char=? #\newline ch) 1 0)))
> (line-count "this string\nhas\nthree \nnewlines")

3

procedure

(in-bytes bstr [start stop step])  sequence?

  bstr : bytes?
  start : exact-nonnegative-integer? = 0
  stop : (or/c exact-integer? #f) = #f
  step : (and/c exact-integer? (not/c zero?)) = 1
Returns a sequence equivalent to bstr when no optional +arguments are supplied.

See Byte Strings for information on using byte strings as +sequences.

The optional arguments start, stop, and +step are as in in-vector.

An in-bytes application can provide better performance for byte string iteration when it appears directly in a for clause.

Examples:
> (define (has-eof? bs)
    (for/or ([ch (in-bytes bs)])
      (= ch 0)))
> (has-eof? #"this byte string has an \0embedded zero byte")

#t

> (has-eof? #"this byte string does not")

#f

procedure

(in-port [r in])  sequence?

  r : (input-port? . -> . any/c) = read
  in : input-port? = (current-input-port)
Returns a sequence whose elements are produced by calling r +on in until it produces eof.

procedure

(in-input-port-bytes in)  sequence?

  in : input-port?
Returns a sequence equivalent to (in-port read-byte in).

procedure

(in-input-port-chars in)  sequence?

  in : input-port?
Returns a sequence whose elements are read as characters from +in (equivalent to (in-port read-char in)).

procedure

(in-lines [in mode])  sequence?

  in : input-port? = (current-input-port)
  mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'any
Returns a sequence equivalent to +(in-port (lambda (p) (read-line p mode)) in). Note that +the default mode is 'any, whereas the default mode of +read-line is 'linefeed.

procedure

(in-bytes-lines [in mode])  sequence?

  in : input-port? = (current-input-port)
  mode : (or/c 'linefeed 'return 'return-linefeed 'any 'any-one)
   = 'any
Returns a sequence equivalent to +(in-port (lambda (p) (read-bytes-line p mode)) in). Note +that the default mode is 'any, whereas the default mode of +read-bytes-line is 'linefeed.

procedure

(in-hash hash)  sequence?

  hash : hash?
(in-hash hash bad-index-v)  sequence?
  hash : hash?
  bad-index-v : any/c
Returns a sequence equivalent to hash, except when bad-index-v +is supplied.

If bad-index-v is supplied, then bad-index-v is +returned as both the key and the value in the case that the +hash is modified concurrently so that iteration does not have a +valid hash index. Providing bad-index-v is particularly +useful when iterating through a hash table with weakly held keys, since +entries can be removed asynchronously (i.e., after in-hash has +committed to another iteration, but before it can access the entry for the +next iteration).

Examples:
> (define table (hash 'a 1 'b 2))
> (for ([(key value) (in-hash table)])
    (printf "key: ~a value: ~a\n" key value))

key: b value: 2

key: a value: 1

See Hash Tables for information on using hash tables as +sequences.

Changed in version 7.0.0.10 of package base: Added the optional bad-index-v argument.

procedure

(in-hash-keys hash)  sequence?

  hash : hash?
(in-hash-keys hash bad-index-v)  sequence?
  hash : hash?
  bad-index-v : any/c
Returns a sequence whose elements are the keys of hash, using +bad-index-v in the same way as in-hash.

Examples:
> (define table (hash 'a 1 'b 2))
> (for ([key (in-hash-keys table)])
    (printf "key: ~a\n" key))

key: b

key: a

Changed in version 7.0.0.10 of package base: Added the optional bad-index-v argument.

procedure

(in-hash-values hash)  sequence?

  hash : hash?
(in-hash-values hash bad-index-v)  sequence?
  hash : hash?
  bad-index-v : any/c
Returns a sequence whose elements are the values of hash, using +bad-index-v in the same way as in-hash.

Examples:
> (define table (hash 'a 1 'b 2))
> (for ([value (in-hash-values table)])
    (printf "value: ~a\n" value))

value: 2

value: 1

Changed in version 7.0.0.10 of package base: Added the optional bad-index-v argument.

procedure

(in-hash-pairs hash)  sequence?

  hash : hash?
(in-hash-pairs hash bad-index-v)  sequence?
  hash : hash?
  bad-index-v : any/c
Returns a sequence whose elements are pairs, each containing a key +and its value from hash (as opposed to using hash +directly as a sequence to get the key and value as separate values +for each element).

The bad-index-v argument, if supplied, is used in the same +way as by in-hash. When an invalid index is encountered, +the pair in the sequence with have bad-index-v as both its +car and cdr.

Examples:
> (define table (hash 'a 1 'b 2))
> (for ([key+value (in-hash-pairs table)])
    (printf "key and value: ~a\n" key+value))

key and value: (b . 2)

key and value: (a . 1)

Changed in version 7.0.0.10 of package base: Added the optional bad-index-v argument.

procedure

(in-mutable-hash hash)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)

procedure

(in-mutable-hash hash bad-index-v)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)
  bad-index-v : any/c

procedure

(in-mutable-hash-keys hash)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)

procedure

(in-mutable-hash-keys hash bad-index-v)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)
  bad-index-v : any/c

procedure

(in-mutable-hash-values hash)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)

procedure

(in-mutable-hash-values hash bad-index-v)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)
  bad-index-v : any/c

procedure

(in-mutable-hash-pairs hash)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)

procedure

(in-mutable-hash-pairs hash bad-index-v)  sequence?

  hash : (and/c hash? (not/c immutable?) hash-strong?)
  bad-index-v : any/c

procedure

(in-immutable-hash hash)  sequence?

  hash : (and/c hash? immutable?)

procedure

(in-immutable-hash hash bad-index-v)  sequence?

  hash : (and/c hash? immutable?)
  bad-index-v : any/c

procedure

(in-immutable-hash-keys hash)  sequence?

  hash : (and/c hash? immutable?)

procedure

(in-immutable-hash-keys hash bad-index-v)  sequence?

  hash : (and/c hash? immutable?)
  bad-index-v : any/c

procedure

(in-immutable-hash-values hash)  sequence?

  hash : (and/c hash? immutable?)

procedure

(in-immutable-hash-values hash bad-index-v)  sequence?

  hash : (and/c hash? immutable?)
  bad-index-v : any/c

procedure

(in-immutable-hash-pairs hash)  sequence?

  hash : (and/c hash? immutable?)

procedure

(in-immutable-hash-pairs hash bad-index-v)  sequence?

  hash : (and/c hash? immutable?)
  bad-index-v : any/c

procedure

(in-weak-hash hash)  sequence?

  hash : (and/c hash? hash-weak?)

procedure

(in-weak-hash hash bad-index-v)  sequence?

  hash : (and/c hash? hash-weak?)
  bad-index-v : any/c

procedure

(in-weak-hash-keys hash)  sequence?

  hash : (and/c hash? hash-weak?)

procedure

(in-weak-hash-keys hash bad-index-v)  sequence?

  hash : (and/c hash? hash-weak?)
  bad-index-v : any/c

procedure

(in-weak-hash-values hash)  sequence?

  hash : (and/c hash? hash-weak?)

procedure

(in-weak-hash-keys hash bad-index-v)  sequence?

  hash : (and/c hash? hash-weak?)
  bad-index-v : any/c

procedure

(in-weak-hash-pairs hash)  sequence?

  hash : (and/c hash? hash-weak?)

procedure

(in-weak-hash-pairs hash bad-index-v)  sequence?

  hash : (and/c hash? hash-weak?)
  bad-index-v : any/c

procedure

(in-ephemeron-hash hash)  sequence?

  hash : (and/c hash? hash-ephemeron?)

procedure

(in-ephemeron-hash hash bad-index-v)  sequence?

  hash : (and/c hash? hash-ephemeron?)
  bad-index-v : any/c

procedure

(in-ephemeron-hash-keys hash)  sequence?

  hash : (and/c hash? hash-ephemeron?)

procedure

(in-ephemeron-hash-keys hash bad-index-v)  sequence?

  hash : (and/c hash? hash-ephemeron?)
  bad-index-v : any/c

procedure

(in-ephemeron-hash-values hash)  sequence?

  hash : (and/c hash? hash-ephemeron?)

procedure

(in-ephemeron-hash-keys hash bad-index-v)  sequence?

  hash : (and/c hash? hash-ephemeron?)
  bad-index-v : any/c

procedure

(in-ephemeron-hash-pairs hash)  sequence?

  hash : (and/c hash? hash-ephemeron?)

procedure

(in-ephemeron-hash-pairs hash bad-index-v)  sequence?

  hash : (and/c hash? hash-ephemeron?)
  bad-index-v : any/c
Sequence constructors for specific kinds of hash tables. +These may perform better than the analogous in-hash +forms.

Added in version 6.4.0.6 of package base.
Changed in version 7.0.0.10: Added the optional bad-index-v argument.
Changed in version 8.0.0.10: Added ephemeron variants.

procedure

(in-directory [dir use-dir?])  sequence?

  dir : (or/c #f path-string?) = #f
  use-dir? : ((and/c path? complete-path?) . -> . any/c)
   = (lambda (dir-path) #t)
Returns a sequence that produces all of the paths for files, + directories, and links within dir, except for the + contents of any directory for which use-dir? returns + #f. If dir is not + #f, then every produced path starts with dir as + its prefix. If dir is #f, then paths in and + relative to the current directory are produced.

An in-directory sequence traverses nested subdirectories + recursively (filtered by use-dir?). + To generate a sequence that includes only the immediate + content of a directory, use the result of directory-list as + a sequence.

The immediate content of each directory is reported as sorted by + path<?, and the content of a subdirectory is reported + before subsequent paths within the directory.

Examples:
> (current-directory (collection-path "info"))
> (for/list ([f (in-directory)])
     f)

'(#<path:compiled>

  #<path:compiled/main_rkt.dep>

  #<path:compiled/main_rkt.zo>

  #<path:main.rkt>)

> (for/list ([f (in-directory "compiled")])
    f)

'(#<path:main_rkt.dep> #<path:main_rkt.zo>)

> (for/list ([f (in-directory "compiled")])
    f)

'(#<path:compiled/main_rkt.dep> #<path:compiled/main_rkt.zo>)

> (for/list ([f (in-directory #f (lambda (p)
                                   (not (regexp-match? #rx"compiled" p))))])
     f)

'(#<path:main.rkt> #<path:compiled>)

Changed in version 6.0.0.1 of package base: Added use-dir? argument.
Changed in version 6.6.0.4: Added guarantee of sorted results.

procedure

(in-producer producer)  sequence?

  producer : procedure?
(in-producer producer stop arg ...)  sequence?
  producer : procedure?
  stop : any/c
  arg : any/c
Returns a sequence that contains values from sequential calls to +producer, which would usually use some state to do its work.

If a stop value is not given, the sequence goes on +infinitely, and therefore it is common to use it with a finite sequence +or using #:break etc. If a stop value is given, it +is used to identify a value that marks the end of the sequence (and +the stop value is not included in the sequence); +stop can be a predicate that is applied to the results of +producer, or it can be a value that is tested against the +result of with eq?. (The stop argument must be a +predicate if the stop value is itself a function or if +producer returns multiple values.)

If additional args are specified, they are passed to every +call to producer.

Examples:
> (define (counter)
    (define n 0)
    (lambda ([d 1]) (set! n (+ d n)) n))
> (for/list ([x (in-producer (counter))] [y (in-range 4)]) x)

'(1 2 3 4)

> (for/list ([x (in-producer (counter))] #:break (= x 5)) x)

'(1 2 3 4)

> (for/list ([x (in-producer (counter) 5)]) x)

'(1 2 3 4)

> (for/list ([x (in-producer (counter) 5 1/2)]) x)

'(1/2 1 3/2 2 5/2 3 7/2 4 9/2)

> (for/list ([x (in-producer read eof (open-input-string "1 2 3"))]) x)

'(1 2 3)

procedure

(in-value v)  sequence?

  v : any/c
Returns a sequence that produces a single value: v.

This form is mostly useful for let-like bindings in forms +such as for*/listbut a #:do clause form, added +more recently, covers many of the same uses.

procedure

(in-indexed seq)  sequence?

  seq : sequence?
Returns a sequence where each element has two values: the value +produced by seq, and a non-negative exact integer starting +with 0. The elements of seq must be +single-valued.

Example:
> (for ([(ch i) (in-indexed "hello")])
    (printf "The char at position ~a is: ~a\n" i ch))

The char at position 0 is: h

The char at position 1 is: e

The char at position 2 is: l

The char at position 3 is: l

The char at position 4 is: o

procedure

(in-sequences seq ...)  sequence?

  seq : sequence?
Returns a sequence that is made of all input sequences, one after +the other. Each seq is initiated only after the +preceding seq is exhausted. If a single seq is +provided, then seq is returned; otherwise, the elements of +each seq must all have the same number of values.

procedure

(in-cycle seq ...)  sequence?

  seq : sequence?
Similar to in-sequences, but the sequences are repeated in +an infinite cycle, where each seq is initiated +afresh in each iteration. Beware that if no seqs are +provided or if all seqs become empty, then the sequence +produced by in-cycle never returns when an element is +demanded—or even when the sequence is initiated, if all +seqs are initially empty.

procedure

(in-parallel seq ...)  sequence?

  seq : sequence?
Returns a sequence where each element has as many values as the +number of supplied seqs; the values, in order, are the +values of each seq. The elements of each seq must +be single-valued.

procedure

(in-values-sequence seq)  sequence?

  seq : sequence?
Returns a sequence that is like seq, but it combines +multiple values for each element from seq as a list of +elements.

procedure

(in-values*-sequence seq)  sequence?

  seq : sequence?
Returns a sequence that is like seq, but when an element of +seq has multiple values or a single list value, then the +values are combined in a list. In other words, +in-values*-sequence is like in-values-sequence, +except that non-list, single-valued elements are not wrapped in a +list.

procedure

(stop-before seq pred)  sequence?

  seq : sequence?
  pred : (any/c . -> . any)
Returns a sequence that contains the elements of seq (which +must be single-valued), but only until the last element for which +applying pred to the element produces #t, after +which the sequence ends.

procedure

(stop-after seq pred)  sequence?

  seq : sequence?
  pred : (any/c . -> . any)
Returns a sequence that contains the elements of seq (which +must be single-valued), but only until the element (inclusive) for +which applying pred to the element produces #t, +after which the sequence ends.

procedure

(make-do-sequence thunk)  sequence?

  thunk : 
(or/c (-> (values (any/c . -> . any)
                  (any/c . -> . any/c)
                  any/c
                  (or/c (any/c . -> . any/c) #f)
                  (or/c (() () #:rest list? . ->* . any/c) #f)
                  (or/c ((any/c) () #:rest list? . ->* . any/c) #f)))
      (-> (values (any/c . -> . any)
                  (or/c (any/c . -> . any/c) #f)
                  (any/c . -> . any/c)
                  any/c
                  (or/c (any/c . -> . any/c) #f)
                  (or/c (() () #:rest list? . ->* . any/c) #f)
                  (or/c ((any/c) () #:rest list? . ->* . any/c) #f))))
Returns a sequence whose elements are generated by the procedures + and initial value returned by the thunk, which is called to + initiate the sequence. The initiated sequence is defined in + terms of a position, which is initialized to the third + result of the thunk, and the element, which may consist of + multiple values.

The thunk results define the generated elements as follows: +
  • The first result is a pos->element procedure that +takes the current position and returns the value(s) for the +current element.

  • The optional second result is an early-next-pos +procedure that is described further below. Alternatively, the +optional second result can be #f, which is equivalent +to the identity function.

  • The third (or second) result is a next-pos procedure that +takes the current position and returns the next position.

  • The fourth (or third) result is the initial position.

  • The fifth (or fourth) result is a continue-with-pos? function +that takes the current position and returns a true result if the +sequence includes the value(s) for the current position, and +false if the sequence should end instead of including the +value(s). Alternatively, the fifth (or fourth) result can be #f to +indicate that the sequence should always include the current +value(s). This function is checked on each position before +pos->element is used.

  • The sixth (or fifth) result is a continue-with-val? function +that is like the fifth (or fourth) result, but it takes the current element +value(s) instead of the current position. Alternatively, the +sixth (or fifth) result can be #f to indicate that the sequence +should always include the value(s) at the current position.

  • The seventh (or sixth) result is a continue-after-pos+val? +procedure that takes both the current position and the current +element value(s) and determines whether the sequence ends after +the current element is already included in the sequence. +Alternatively, the seventh (or sixth) result can be #f to indicate +that the sequence can always continue after the current +value(s).

The early-next-pos procedure, which is the optional second + result, takes the current position and returns an updated position. + This updated position is used for next-pos and + continue-after-pos+val?, but not with + continue-with-pos? (which uses the original current + position). The intent of early-next-pos is to support a + sequence where the position must be incremented to avoid keeping a + value reachable while a loop processes the sequence value, so + early-next-pos is applied just after + pos->element.

Each of the procedures listed above is called only once per + position. Among the last three procedures, as soon as one of the + procedures returns #f, the sequence ends, and none are + called again. Typically, one of the functions determines the end + condition, and #f is used in place of the other two + functions.

Changed in version 6.7.0.4 of package base: Added support for the optional second result.

Associates a procedure to a structure type that takes an instance of +the structure and returns a sequence. If v is an instance +of a structure type with this property, then (sequence? v) +produces #t.

Using a pre-existing sequence:

Examples:
> (struct my-set (table)
    #:property prop:sequence
    (lambda (s)
      (in-hash-keys (my-set-table s))))
> (define (make-set . xs)
    (my-set (for/hash ([x (in-list xs)])
              (values x #t))))
> (for/list ([c (make-set 'celeriac 'carrot 'potato)])
    c)

'(potato celeriac carrot)

Using make-do-sequence:

Examples:
> (struct train (car next)
    #:property prop:sequence
    (lambda (t)
      (make-do-sequence
       (lambda ()
         (values train-car train-next t
                 (lambda (t) t)
                 (lambda (v) #t)
                 (lambda (t v) #t))))))
> (for/list ([c (train 'engine
                       (train 'boxcar
                              (train 'caboose
                                     #f)))])
    c)

'(engine boxcar caboose)

4.16.1.2 Sequence Conversion

procedure

(sequence->stream seq)  stream?

  seq : sequence?
Coverts a sequence to a stream, which supports the +stream-first and stream-rest operations. Creation +of the stream eagerly initiates the sequence, but the stream +lazily draws elements from the sequence, caching each element so +that stream-first produces the same result each time is +applied to a stream.

If extracting an element from seq involves a side-effect, +then the effect is performed each time that either +stream-first or stream-rest is first used to +access or skip an element.

Note that a sequence itself can have +state, so multiple calls to sequence->stream on the same +seq are not necessarily independent.

Examples:
> (define inport (open-input-bytes (bytes 1 2 3 4 5)))
> (define strm (sequence->stream inport))
> (stream-first strm)

1

> (stream-first (stream-rest strm))

2

> (stream-first strm)

1

> (define strm2 (sequence->stream inport))
> (stream-first strm2)

3

> (stream-first (stream-rest strm2))

4

procedure

(sequence-generate seq)  
(-> boolean?) (-> any)
  seq : sequence?
Initiates a sequence and returns two thunks to extract +elements from the sequence. The first returns #t if more +values are available for the sequence. The second returns the next +element (which may be multiple values) from the sequence; if no more +elements are available, the exn:fail:contract exception is raised.

Note that a sequence itself can have +state, so multiple calls to sequence-generate on the same +seq are not necessarily independent.

Examples:
> (define inport (open-input-bytes (bytes 1 2 3 4 5)))
> (define-values (more? get) (sequence-generate inport))
> (more?)

#t

> (get)

1

> (get)

2

> (define-values (more2? get2) (sequence-generate inport))
> (list (get2) (get2) (get2))

'(3 4 5)

> (more2?)

#f

procedure

(sequence-generate* seq)

  
(or/c list? #f)
(-> (values (or/c list? #f) procedure?))
  seq : sequence?
Like sequence-generate, but avoids state (aside from any +inherent in the sequence) by returning a list of values for the +sequence’s first element—or #f if the sequence is +empty—and a thunk to continue with the sequence; the result of the +thunk is the same as the result of sequence-generate*, but +for the second element of the sequence, and so on. If the thunk is +called when the element result is #f (indicating no further +values in the sequence), the exn:fail:contract exception is raised.

4.16.1.3 Additional Sequence Operations

The bindings documented in this section are provided by the racket/sequence and racket libraries, but not racket/base.

A sequence with no elements.

procedure

(sequence->list s)  list?

  s : sequence?
Returns a list whose elements are the elements of s, each +of which must be a single value. If s is infinite, this +function does not terminate.

Returns the number of elements of s by extracting and +discarding all of them. If s is infinite, this function +does not terminate.

procedure

(sequence-ref s i)  any

  s : sequence?
  i : exact-nonnegative-integer?
Returns the ith element of s (which may be +multiple values).

procedure

(sequence-tail s i)  sequence?

  s : sequence?
  i : exact-nonnegative-integer?
Returns a sequence equivalent to s, except that the first +i elements are omitted.

In case initiating s involves a +side effect, the sequence s is not initiated until +the resulting sequence is initiated, at which point the first +i elements are extracted from the sequence.

procedure

(sequence-append s ...)  sequence?

  s : sequence?
Returns a sequence that contains all elements of each sequence in +the order they appear in the original sequences. The new sequence +is constructed lazily.

If all given ss are streams, the result is also a +stream.

procedure

(sequence-map f s)  sequence?

  f : procedure?
  s : sequence?
Returns a sequence that contains f applied to each element +of s. The new sequence is constructed lazily.

If s is a stream, then the result is also a +stream.

procedure

(sequence-andmap f s)  boolean?

  f : (-> any/c ... boolean?)
  s : sequence?
Returns #t if f returns a true result on every +element of s. If s is infinite and f +never returns a false result, this function does not terminate.

procedure

(sequence-ormap f s)  boolean?

  f : (-> any/c ... boolean?)
  s : sequence?
Returns #t if f returns a true result on some +element of s. If s is infinite and f +never returns a true result, this function does not terminate.

procedure

(sequence-for-each f s)  void?

  f : (-> any/c ... any)
  s : sequence?
Applies f to each element of s. If s is +infinite, this function does not terminate.

procedure

(sequence-fold f i s)  any/c

  f : (-> any/c any/c ... any/c)
  i : any/c
  s : sequence?
Folds f over each element of s with i as +the initial accumulator. If s is infinite, this function +does not terminate. The f function takes the accumulator as +its first argument and the next sequence element as its second.

procedure

(sequence-count f s)  exact-nonnegative-integer?

  f : procedure?
  s : sequence?
Returns the number of elements in s for which f +returns a true result. If s is infinite, this function +does not terminate.

procedure

(sequence-filter f s)  sequence?

  f : (-> any/c ... boolean?)
  s : sequence?
Returns a sequence whose elements are the elements of s for +which f returns a true result. Although the new sequence +is constructed lazily, if s has an infinite number of +elements where f returns a false result in between two +elements where f returns a true result, then operations on +this sequence will not terminate during the infinite sub-sequence.

If s is a stream, then the result is also a +stream.

procedure

(sequence-add-between s e)  sequence?

  s : sequence?
  e : any/c
Returns a sequence whose elements are the elements of s, +but with e between each pair of elements in s. +The new sequence is constructed lazily.

If s is a stream, then the result is also a +stream.

Examples:
> (let* ([all-reds (in-cycle '("red"))]
         [red-and-blues (sequence-add-between all-reds "blue")])
    (for/list ([n (in-range 10)]
               [elt red-and-blues])
      elt))

'("red" "blue" "red" "blue" "red" "blue" "red" "blue" "red" "blue")

> (for ([text (sequence-add-between '("veni" "vidi" "duci") ", ")])
    (display text))

veni, vidi, duci

procedure

(sequence/c [#:min-count min-count]    
  elem/c ...)  contract?
  min-count : (or/c #f exact-nonnegative-integer?) = #f
  elem/c : contract?
Wraps a sequence, +obligating it to produce elements with as many values as there are elem/c contracts, +and obligating each value to satisfy the corresponding elem/c. The +result is not guaranteed to be the same kind of sequence as the original value; +for instance, a wrapped list is not guaranteed to satisfy list?.

If min-count is a number, the stream is required to have at least that many elements in it.

Examples:
> (define/contract predicates
    (sequence/c (-> any/c boolean?))
    (in-list (list integer?
                   string->symbol)))
> (for ([P predicates])
    (printf "~s\n" (P "cat")))

#f

predicates: broke its own contract

  promised: boolean?

  produced: 'cat

  in: an element of

      (sequence/c (-> any/c boolean?))

  contract from: (definition predicates)

  blaming: (definition predicates)

   (assuming the contract is correct)

  at: eval:55:0

> (define/contract numbers&strings
    (sequence/c number? string?)
    (in-dict (list (cons 1 "one")
                   (cons 2 "two")
                   (cons 3 'three))))
> (for ([(N S) numbers&strings])
    (printf "~s: ~a\n" N S))

1: one

2: two

numbers&strings: broke its own contract

  promised: string?

  produced: 'three

  in: an element of

      (sequence/c number? string?)

  contract from: (definition numbers&strings)

  blaming: (definition numbers&strings)

   (assuming the contract is correct)

  at: eval:57:0

> (define/contract a-sequence
    (sequence/c #:min-count 2 char?)
    "x")
> (for ([x a-sequence]
        [i (in-naturals)])
    (printf "~a is ~a\n" i x))

0 is x

a-sequence: broke its own contract

  promised: a sequence that contains at least 2 values

  produced: "x"

  in: (sequence/c #:min-count 2 char?)

  contract from: (definition a-sequence)

  blaming: (definition a-sequence)

   (assuming the contract is correct)

  at: eval:59:0

4.16.1.3.1 Additional Sequence Constructors

procedure

(in-syntax stx)  sequence?

  stx : syntax?
Produces a sequence whose elements are the successive subparts of + stx. + Equivalent to (stx->list lst). +
An in-syntax application can provide better performance for syntax iteration when it appears directly in a for clause.

Example:
> (for/list ([x (in-syntax #'(1 2 3))])
    x)

'(#<syntax:eval:61:0 1> #<syntax:eval:61:0 2> #<syntax:eval:61:0 3>)

Added in version 6.3 of package base.

procedure

(in-slice length seq)  sequence?

  length : exact-positive-integer?
  seq : sequence?
Returns a sequence whose elements are lists with the first length +elements of seq, then the next length and so on.

Example:
> (for/list ([e (in-slice 3 (in-range 8))]) e)

'((0 1 2) (3 4 5) (6 7))

Added in version 6.3 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/sequences_streams.html b/clones/docs.racket-lang.org/reference/sequences_streams.html new file mode 100644 index 00000000..6600a0ff --- /dev/null +++ b/clones/docs.racket-lang.org/reference/sequences_streams.html @@ -0,0 +1,7 @@ + +4.16 Sequences and Streams

4.16 Sequences and Streams

Sequences and streams abstract over iteration of elements in a +collection. Sequences allow iteration with for macros or with sequence +operations such as sequence-map. Streams are functional sequences that +can be used either in a generic way or a stream-specific way. Generators +are closely related stateful objects that can be converted to a sequence and +vice-versa.

    4.16.1 Sequences

      4.16.1.1 Sequence Predicate and Constructors

      4.16.1.2 Sequence Conversion

      4.16.1.3 Additional Sequence Operations

        4.16.1.3.1 Additional Sequence Constructors

    4.16.2 Streams

    4.16.3 Generators

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/serialization.html b/clones/docs.racket-lang.org/reference/serialization.html new file mode 100644 index 00000000..acdc0ce3 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/serialization.html @@ -0,0 +1,283 @@ + +13.9 Serialization

13.9 Serialization

The bindings documented in this section are provided by the racket/serialize library, not racket/base or racket.

procedure

(serializable? v)  boolean?

  v : any/c
Returns #t if v appears to be serializable, without +checking the content of compound values, and #f otherwise. +See serialize for an enumeration of serializable values.

procedure

(serialize 
  v 
  [#:relative-directory relative-to 
  #:deserialize-relative-directory deserialize-relative-to]) 
  any
  v : serializable?
  relative-to : 
(or/c (and/c path? complete-path?)
      (cons/c (and/c path? complete-path?)
              (and/c path? complete-path?))
      #f)
 = #f
  deserialize-relative-to : 
(or/c (and/c path? complete-path?)
      (cons/c (and/c path? complete-path?)
              (and/c path? complete-path?))
      #f)
   = relative-to
Returns a value that encapsulates the value v. This value +includes only readable values, so it can be written to a stream with +write or s-exp->fasl, later read from a stream using +read or fasl->s-exp, and then converted to a value +like the original using deserialize. Serialization followed +by deserialization produces a value with the same graph structure and +mutability as the original value, but the serialized value is a plain +tree (i.e., no sharing).

The following kinds of values are serializable:

Serialization succeeds for a compound value, such as a pair, only if +all content of the value is serializable. If a value given to +serialize is not completely serializable, the +exn:fail:contract exception is raised.

If v contains a cycle (i.e., a collection of objects that +are all reachable from each other), then v can be serialized +only if the cycle includes a mutable value, where a prefab +structure counts as mutable only if all of its fields are mutable.

If relative-to is not #f, then paths to serialize +that extend the path in relative-to are recorded in relative +and platform-independent form. The possible values and treatment of +relative-to are the same as for current-write-relative-directory.

If deserialize-relative-to is not #f, then any paths +to deserializers as extracted via prop:serializable are +recorded in relative form. Note that relative-to and +deserialize-relative-to are independent, but +deserialize-relative-to defaults to relative-to.

The serialize and deserialize functions +currently do not handle certain cyclic values that read and +write can handle, such as '#0=(#0#).

See deserialize for information on the format of serialized +data.

Changed in version 6.5.0.4 of package base: Added keywords and regexp values as serializable.
Changed in version 7.0.0.6: Added the #:relative-directory and +#:deserialize-relative-directory arguments.

procedure

(deserialize v)  any

  v : any/c
Given a value v that was produced by serialize, +produces a value like the one given to serialize, including +the same graph structure and mutability.

A serialized representation v is a list of six or seven +elements:

  • An optional list '(1), '(2), '(3), +or '(4) that represents +the version of the serialization format. If the first element +of a representation is not a list, then the version is +0. Version 1 adds support for mutable pairs, +version 2 adds support for unreadable symbols, +version 3 adds support for date* structures, +and version 4 adds support for paths that are meant to +be relative to the deserialization directory.

  • A non-negative exact integer s-count that represents the +number of distinct structure types represented in the +serialized data.

  • A list s-types of length s-count, +where each element represents a structure type. Each +structure type is encoded as a pair. The car of the +pair is #f for a structure whose deserialization +information is defined at the top level, otherwise it is a +quoted module path, a byte string (to be converted +into a platform-specific path using bytes->path) +for a module that exports the structure’s deserialization +information, or a relative path element list for a module to +be resolved with respect to +current-load-relative-directory or (as a fallback) +current-directory; the list-of-relative-elements +form is produced by serialize when +the #:deserialize-relative-directory argument is +not #f. The cdr of the pair is the +name of a binding (at the top level or exported from a +module) for deserialization information, either a symbol or +a string representing an unreadable symbol. These two +are used with either namespace-variable-binding or +dynamic-require to obtain deserialization +information. See make-deserialize-info for more +information on the binding’s value. See also +deserialize-module-guard.

  • A non-negative exact integer, g-count that represents the +number of graph points contained in the following list.

  • A list graph of length g-count, where each element + represents a serialized value to be referenced during the + construction of other serialized values. Each list element is + either a box or not:

    • A box represents a value that is part of a cycle, and for +deserialization, it must be allocated with #f for +each of its fields. The content of the box indicates the +shape of the value:

      • a non-negative exact integer i for an instance +of a structure type that is represented by the +ith element of the s-types list;

      • 'c for a pair, which fails on +deserialization (since pairs are immutable; this +case does not appear in output generated by +serialize);

      • 'm for a mutable pair;

      • 'b for a box;

      • a pair whose car is 'v and whose +cdr is a non-negative exact integer s +for a vector of length s;

      • a list whose first element is 'h and whose +remaining elements are symbols that determine the +hash-table type:

      • 'date* for a date* structure, which +fails on deserialization (since dates are immutable; +this case does not appear in output generated by +serialize);

      • 'date for a date structure, which +fails on deserialization (since dates are immutable; +this case does not appear in output generated by +serialize);

      • 'arity-at-least for an +arity-at-least structure, which fails on +deserialization (since arity-at-least are immutable; this +case does not appear in output generated by +serialize); or

      • 'mpi for a module path index, which +fails on deserialization (since a module path index is immutable; +this case does not appear in output generated by +serialize).

      • 'srcloc for a srcloc structure, which +fails on deserialization (since srclocs are immutable; +this case does not appear in output generated by +serialize).

      The #f-filled value will be updated with content specified +by the fifth element of the serialization list v.

    • A non-box represents a serial value to be + constructed immediately, and it is one of the following:

      • a boolean, number, character, interned symbol, or empty list, +representing itself.

      • a string, representing an immutable string.

      • a byte string, representing an immutable byte +string.

      • a pair whose car is '? and whose +cdr is a non-negative exact integer +i; it represents the value constructed for the +ith element of graph, where i is +less than the position of this element within +graph.

      • a pair whose car is a number i; it +represents an instance of a structure type that is +described by the ith element of the +s-types list. The cdr of the pair is +a list of serials representing arguments to be +provided to the structure type’s deserializer.

      • a pair whose car is 'q and whose +cdr is an immutable value; it represents +the quoted value.

      • a pair whose car is 'f; it +represents an instance of a prefab structure +type. The cadr of the pair is a prefab +structure type key, and the cddr is a list of +serials representing the field values.

      • a pair whose car is 'void, +representing #<void>.

      • a pair whose car is 'su and whose +cdr is a character string; it represents an +unreadable symbol.

      • a pair whose car is 'u and whose +cdr is either a byte string or character +string; it represents a mutable byte or character +string.

      • a pair whose car is 'p and whose +cdr is a byte string; it represents a +path using the serializer’s path convention +(deprecated in favor of 'p+).

      • a pair whose car is 'p+, whose +cadr is a byte string, and whose cddr +is one of the possible symbol results of +system-path-convention-type; it represents a +path using the specified convention.

      • a pair whose car is 'p* and whose +cdr is a list of byte strings represents a +relative path; it will be converted by deserialization +based on current-load-relative-directory, +falling back to current-directory.

      • a pair whose car is 'c and whose +cdr is a pair of serials; it represents an +immutable pair.

      • a pair whose car is 'c! and whose +cdr is a pair of serials; it represents a +pair (but formerly represented a mutable pair), and +does not appear in output generated by +serialize.

      • a pair whose car is 'm and whose +cdr is a pair of serials; it represents a +mutable pair.

      • a pair whose car is 'v and whose +cdr is a list of serials; it represents an +immutable vector.

      • a pair whose car is 'v! and whose +cdr is a list of serials; it represents a +mutable vector.

      • a pair whose car is 'vl and whose +cdr is a list of serials; it represents a +flvector.

      • a pair whose car is 'vx and whose +cdr is a list of serials; it represents a +fxvector.

      • a pair whose car is 'b and whose +cdr is a serial; it represents an immutable +box.

      • a pair whose car is 'b! and whose +cdr is a serial; it represents a mutable +box.

      • a pair whose car is 'h, whose +cadr is either '! or '- +(mutable or immutable, respectively), whose +caddr is a list of symbols (containing +'equal, 'weak, both, or neither) +that determines the hash table type, and whose +cdddr is a list of pairs, where the +car of each pair is a serial for a +hash-table key and the cdr is a serial for +the corresponding value.

      • a pair whose car is 'date* and whose +cdr is a list of serials; it represents a +date* structure.

      • a pair whose car is 'date and whose +cdr is a list of serials; it represents a +date structure.

      • a pair whose car is 'arity-at-least +and whose cdr is a serial; it represents an +arity-at-least structure.

      • a pair whose car is 'mpi and whose +cdr is a pair; it represents a +module path index that joins the paired +values.

      • a pair whose car is 'srcloc and whose +cdr is a list of serials; it represents a +srcloc structure.

  • A list of pairs, where the car of each pair is a +non-negative exact integer i and the cdr is a +serial (as defined in the previous bullet). Each element +represents an update to an ith element of graph +that was specified as a box, and the serial describes how to +construct a new value with the same shape as specified by the +box. The content of this new value must be transferred into the +value created for the box in graph.

  • A final serial (as defined in the two bullets back) +representing the result of deserialize.

The result of deserialize shares no mutable values with the +argument to deserialize.

If a value provided to serialize is a simple tree (i.e., no +sharing), then the fourth and fifth elements in the serialized +representation will be empty.

procedure

(serialized=? v1 v2)  boolean?

  v1 : any/c
  v2 : any/c
Returns #t if v1 and v2 represent the same +serialization information.

More precisely, it returns the same value that (equal? (deserialize v1) (deserialize v2)) would return if

  • all structure types whose deserializers are accessed with +distinct module paths are actually distinct types;

  • all structure types are transparent; and

  • all structure instances contain only the constituent values +recorded in each of v1 and v2.

A parameter whose value is called by deserialize before +dynamically loading a module via dynamic-require. The two +arguments provided to the procedure are the same as the arguments to +be passed to dynamic-require. The procedure can raise an +exception to disallow the dynamic-require.

The procedure can optionally return a pair containing a +module-path and symbol. If returned, +deserialize will use them as arguments to +dynamic-require instead.

Changed in version 6.90.0.30 of package base: Adds optional return values for bindings.

syntax

(serializable-struct id maybe-super (field ...)
                     struct-option ...)
Like struct, but instances of the structure type are +serializable with serialize. This form is allowed only at +the top level or in a module’s top level (so that deserialization +information can be found later).

Serialization supports cycles involving the created structure +type only when all fields are mutable (or when the cycle can be broken +through some other mutable value).

In addition to the bindings generated by struct, +serializable-struct binds +deserialize-info:id-v0 to +deserialization information. Furthermore, in a module context, it +automatically provides this binding in a deserialize-info +submodule using module+.

The serializable-struct form enables the construction of +structure instances from places where id is not accessible, +since deserialization must construct instances. Furthermore, +serializable-struct provides limited access to field +mutation, but only for instances generated through the deserialization +information bound to +deserialize-info:id-v0. See +make-deserialize-info for more information.

Beware that the previous paragraph means that if a serializable struct +is exported via contract-out, for example, the contracts are not +checked during deserialization. Consider using struct-guard/c +instead.

The -v0 suffix on the deserialization enables future +versioning on the structure type through +serializable-struct/versions.

When a supertype is supplied as maybe-super, +compile-time information bound to the supertype identifier must +include all of the supertype’s field accessors. If any field mutator +is missing, the structure type will be treated as immutable for the +purposes of marshaling (so cycles involving only instances of the +structure type cannot be handled by the deserializer).

Examples:
> (serializable-struct point (x y))
> (point-x (deserialize (serialize (point 1 2))))

1

syntax

(define-serializable-struct id-maybe-super (field ...)
                             struct-option ...)
Like serializable-struct, but with the supertype syntax and +default constructor name of define-struct.

syntax

(serializable-struct/versions id maybe-super vers (field ...)
                              (other-version-clause ...)
                              struct-option ...)
 
other-version-clause = 
(other-vers make-proc-expr
            cycle-make-proc-expr)
Like serializable-struct, but the generated deserializer +binding is +deserialize-info:id-vvers. In +addition, +deserialize-info:id-vother-vers +is bound for each other-vers. The vers and each +other-vers must be a literal, exact, nonnegative integer.

Each make-proc-expr should produce a procedure, and the +procedure should accept as many argument as fields in the +corresponding version of the structure type, and it produces an +instance of id. Each cycle-make-proc-expr should +produce a procedure of no arguments; this procedure should return two +values: an instance x of id (typically with +#f for all fields) and a procedure that accepts another +instance of id and copies its field values into x.

Examples:
> (serializable-struct point (x y) #:mutable #:transparent)
> (define ps (serialize (point 1 2)))
> (deserialize ps)

(point 1 2)

> (define x (point 1 10))
> (set-point-x! x x)
> (define xs (serialize x))
> (deserialize xs)

#0=(point #0# 10)

> (serializable-struct/versions point 1 (x y z)
     ([0
       ; Constructor for simple v0 instances:
       (lambda (x y) (point x y 0))
       ; Constructor for v0 instance in a cycle:
       (lambda ()
         (let ([p0 (point #f #f 0)])
           (values
             p0
             (lambda (p)
               (set-point-x! p0 (point-x p))
               (set-point-y! p0 (point-y p))))))])
     #:mutable #:transparent)
> (deserialize (serialize (point 4 5 6)))

(point 4 5 6)

> (deserialize ps)

(point 1 2 0)

> (deserialize xs)

#0=(point #0# 10 0)

syntax

(define-serializable-struct/versions id-maybe-super vers (field ...)
                                     (other-version-clause ...)
                                     struct-option ...)
Like serializable-struct/versions, but with the supertype syntax and +default constructor name of define-struct.

procedure

(make-deserialize-info make cycle-make)  any

  make : procedure?
  cycle-make : (-> (values any/c procedure?))
Produces a deserialization information record to be used by +deserialize. This information is normally tied to a +particular structure because the structure has a +prop:serializable property value that points to a top-level +variable or module-exported variable that is bound to deserialization +information.

The make procedure should accept as many arguments as the +structure’s serializer put into a vector; normally, this is the number +of fields in the structure. It should return an instance of the +structure.

The cycle-make procedure should accept no arguments, and it +should return two values: a structure instance x (with dummy +field values) and an update procedure. The update procedure takes +another structure instance generated by the make, and it +transfers the field values of this instance into x.

value

prop:serializable : property?

This property identifies structures and structure types that are +serializable. The property value should be constructed with +make-serialize-info.

procedure

(make-serialize-info to-vector    
  deserialize-id    
  can-cycle?    
  dir)  any
  to-vector : (any/c . -> . vector?)
  deserialize-id : 
(or identifier?
    symbol?
    (cons/c symbol?
            module-path-index?)
    (-> any/c))
  can-cycle? : any/c
  dir : path-string?
Produces a value to be associated with a structure type through the +prop:serializable property. This value is used by +serialize.

The to-vector procedure should accept a structure instance +and produce a vector for the instance’s content.

The deserialize-id value indicates a binding for deserialize +information, to either a module export or a top-level definition. It +must be one of the following:

  • If deserialize-id is an identifier, and if +(identifier-binding deserialize-id) produces a list, then +the third element is used for the exporting module, otherwise the +top-level is assumed. Before trying an exporting module directly, +its deserialize-info submodule is tried; the module +itself is tried if no deserialize-info +submodule is available or if the export is not found. In either case, syntax-e is used to +obtain the name of an exported identifier or top-level definition.

  • If deserialize-id is a symbol, it indicates a +top-level variable that is named by the symbol.

  • If deserialize-id is a pair, the car must be +a symbol to name an exported identifier, and the cdr must be +a module path index to specify the exporting module.

  • If deserialize-id is a procedure, then it is +applied during serialization and its result is used for +deserialize-id.

See make-deserialize-info and deserialize for more +information.

The can-cycle? argument should be false if instances should +not be serialized in such a way that deserialization requires creating +a structure instance with dummy field values and then updating the +instance later.

The dir argument should be a directory path that is used to +resolve a module reference for the binding of deserialize-id. +This directory path is used as a last resort when +deserialize-id indicates a module that was loaded through a +relative path with respect to the top level. Usually, it should be +(or (current-load-relative-directory) (current-directory)).

Changed in version 7.0.0.6 of package base: Allow deserialize-id to be a procedure.

Examples:
> (struct pie (type)
    #:mutable
    #:property prop:serializable
    (make-serialize-info
     (λ (this)
       (vector (pie-type this)))
     'pie-beam
     #t
     (or (current-load-relative-directory) (current-directory))))
> (define pie-beam
    (make-deserialize-info
     (λ (type)
       (pie type))
     (λ ()
       (define pie-pattern (pie 'transporter-error))
       (values pie-pattern
               (λ (type)
                 (set-pie-type! pie-pattern type))))))
> (define original-pie
    (pie 'apple))
> original-pie

#<pie>

> (define pie-in-transit
    (serialize original-pie))
> pie-in-transit

'((3) 1 ((#f . pie-beam)) 0 () () (0 apple))

> (define beamed-up-pie
    (deserialize pie-in-transit))
> beamed-up-pie

#<pie>

> (pie-type beamed-up-pie)

'apple

> (equal? beamed-up-pie original-pie)

#f

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/set_.html b/clones/docs.racket-lang.org/reference/set_.html new file mode 100644 index 00000000..05bc4521 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/set_.html @@ -0,0 +1,24 @@ + +3.17 Assignment: set! and set!-values
On this page:
set!
set!-values

3.17 Assignment: set! and set!-values

+Assignment: set! in The Racket Guide introduces set!.

syntax

(set! id expr)

If id has a transformer binding to an assignment +transformer, as produced by make-set!-transformer or as an +instance of a structure type with the prop:set!-transformer +property, then this form is expanded by calling the assignment +transformer with the full expressions. If id has a +transformer binding to a rename transformer as produced +by make-rename-transformer or as an instance of a structure +type with the prop:rename-transformer property, then this +form is expanded by replacing id with the target identifier +(e.g., the one provided to make-rename-transformer). If a +transformer binding has both prop:set!-transformer and +prop:rename-transformer properties, the latter takes +precedence.

Otherwise, evaluates expr and installs the result into the +location for id, which must be bound as a local variable or +defined as a top-level variable or module-level +variable. If id refers to an imported binding, a syntax +error is reported. If id refers to a top-level +variable that has not been defined, the exn:fail:contract exception is raised.

See also compile-allow-set!-undefined.

Examples:
> (define x 12)
> (set! x (add1 x))
> x

13

> (let ([x 5])
    (set! x (add1 x))
    x)

6

> (set! i-am-not-defined 10)

set!: assignment disallowed;

 cannot set variable before its definition

  variable: i-am-not-defined

  in module: top-level

syntax

(set!-values (id ...) expr)

Assuming that all ids refer to variables, this form evaluates +expr, which must produce as many values as supplied +ids. The location of each id is filled with the +corresponding value from expr in the same way as for +set!.

Example:
> (let ([a 1]
        [b 2])
    (set!-values (a b) (values b a))
    (list a b))

'(2 1)

More generally, the set!-values form is expanded to

(let-values ([(tmp-id ...) expr])
  (set! id tmp-id) ...)

which triggers further expansion if any id has a transformer +binding to an assignment transformer.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/sets.html b/clones/docs.racket-lang.org/reference/sets.html new file mode 100644 index 00000000..8a6c2def --- /dev/null +++ b/clones/docs.racket-lang.org/reference/sets.html @@ -0,0 +1,276 @@ + +4.18 Sets

4.18 Sets

A set represents a collection of distinct elements. The following +datatypes are all sets:

 (require racket/set) package: base
The bindings documented in this section are provided by the racket/set and racket libraries, but not racket/base.

4.18.1 Hash Sets

A hash set is a set whose elements are compared via equal?, +equal-always?, eqv?, or eq? and partitioned +via equal-hash-code, equal-always-hash-code, +eqv-hash-code, or eq-hash-code. A hash set is either +immutable or mutable; mutable hash sets retain their elements either strongly +or weakly.

Like operations on immutable hash tables, “constant time” hash +set operations actually require O(log N) time for a set of size +N.

A hash set can be used as a stream (see Streams) and thus as +a single-valued sequence (see Sequences). The elements of the +set serve as elements of the stream or sequence. If an element is added to or +removed from the hash set during iteration, then an iteration step may fail +with exn:fail:contract, or the iteration may skip or duplicate +elements. See also in-set.

Two hash sets are equal? when they use the same element-comparison +procedure (equal?, equal-always?, eqv?, or +eq?), both hold elements strongly or weakly, have the same +mutability, and have equivalent elements. +Immutable hash sets support effectively constant-time access and +update, just like mutable hash sets; the constant on immutable operations is +usually larger, but the functional nature of immutable hash sets can pay off in +certain algorithms.

All hash sets implement set->stream, +set-empty?, set-member?, set-count, +subset?, proper-subset?, set-map, +set-for-each, set-copy, set-copy-clear, +set->list, and set-first. Immutable hash sets in +addition implement set-add, set-remove, +set-clear, set-union, set-intersect, +set-subtract, and set-symmetric-difference. Mutable +hash sets in addition implement set-add!, +set-remove!, set-clear!, set-union!, +set-intersect!, set-subtract!, and +set-symmetric-difference!.

Operations on sets that contain elements that are mutated are +unpredictable in much the same way that hash table operations are +unpredictable when keys are mutated.

procedure

(set-equal? x)  boolean?

  x : any/c

procedure

(set-equal-always? x)  boolean?

  x : any/c

procedure

(set-eqv? x)  boolean?

  x : any/c

procedure

(set-eq? x)  boolean?

  x : any/c
Returns #t if x is a hash set that compares +elements with equal?, equal-always?, eqv?, +or eq?, respectively; returns #f otherwise.

Changed in version 8.5.0.3 of package base: Added set-equal-always?.

procedure

(set? x)  boolean?

  x : any/c

procedure

(set-mutable? x)  boolean?

  x : any/c

procedure

(set-weak? x)  boolean?

  x : any/c
Returns #t if x is a hash set that is respectively +immutable, mutable with strongly-held keys, or mutable with weakly-held keys; +returns #f otherwise.

procedure

(set v ...)  (and/c generic-set? set-equal? set?)

  v : any/c

procedure

(setalw v ...)  (and/c generic-set? set-equal-always? set?)

  v : any/c

procedure

(seteqv v ...)  (and/c generic-set? set-eqv? set?)

  v : any/c

procedure

(seteq v ...)  (and/c generic-set? set-eq? set?)

  v : any/c

procedure

(mutable-set v ...)

  (and/c generic-set? set-equal? set-mutable?)
  v : any/c

procedure

(mutable-setalw v ...)

  (and/c generic-set? set-equal-always? set-mutable?)
  v : any/c

procedure

(mutable-seteqv v ...)

  (and/c generic-set? set-eqv? set-mutable?)
  v : any/c

procedure

(mutable-seteq v ...)

  (and/c generic-set? set-eq? set-mutable?)
  v : any/c

procedure

(weak-set v ...)  (and/c generic-set? set-equal? set-weak?)

  v : any/c

procedure

(weak-setalw v ...)

  (and/c generic-set? set-equal-always? set-weak?)
  v : any/c

procedure

(weak-seteqv v ...)  (and/c generic-set? set-eqv? set-weak?)

  v : any/c

procedure

(weak-seteq v ...)  (and/c generic-set? set-eq? set-weak?)

  v : any/c
Creates a hash set with the given vs as elements. The +elements are added in the order that they appear as arguments, so in the case +of sets that use equal?, equal-always?, or eqv?, +an earlier element may be replaced by a later element that is +equal?, equal-always?, or eqv?, but not +eq?.

Changed in version 8.5.0.3 of package base: Added setalw, +mutable-setalw, and weak-setalw.

procedure

(list->set lst)  (and/c generic-set? set-equal? set?)

  lst : list?

procedure

(list->setalw lst)

  (and/c generic-set? set-equal-always? set?)
  lst : list?

procedure

(list->seteqv lst)  (and/c generic-set? set-eqv? set?)

  lst : list?

procedure

(list->seteq lst)  (and/c generic-set? set-eq? set?)

  lst : list?

procedure

(list->mutable-set lst)

  (and/c generic-set? set-equal? set-mutable?)
  lst : list?

procedure

(list->mutable-setalw lst)

  (and/c generic-set? set-equal-always? set-mutable?)
  lst : list?

procedure

(list->mutable-seteqv lst)

  (and/c generic-set? set-eqv? set-mutable?)
  lst : list?

procedure

(list->mutable-seteq lst)

  (and/c generic-set? set-eq? set-mutable?)
  lst : list?

procedure

(list->weak-set lst)

  (and/c generic-set? set-equal? set-weak?)
  lst : list?

procedure

(list->weak-setalw lst)

  (and/c generic-set? set-equal-always? set-weak?)
  lst : list?

procedure

(list->weak-seteqv lst)

  (and/c generic-set? set-eqv? set-weak?)
  lst : list?

procedure

(list->weak-seteq lst)  (and/c generic-set? set-eq? set-weak?)

  lst : list?
Creates a hash set with the elements of the given lst as +the elements of the set. Equivalent to (apply set lst), +(apply setalw lst), (apply seteqv lst), +(apply seteq lst), and so on, respectively.

Changed in version 8.5.0.3 of package base: Added list->setalw, +list->mutable-setalw, and list->weak-setalw.

syntax

(for/set (for-clause ...) body ...+)

syntax

(for/seteq (for-clause ...) body ...+)

syntax

(for/seteqv (for-clause ...) body ...+)

syntax

(for/setalw (for-clause ...) body ...+)

syntax

(for*/set (for-clause ...) body ...+)

syntax

(for*/seteq (for-clause ...) body ...+)

syntax

(for*/seteqv (for-clause ...) body ...+)

syntax

(for*/setalw (for-clause ...) body ...+)

syntax

(for/mutable-set (for-clause ...) body ...+)

syntax

(for/mutable-seteq (for-clause ...) body ...+)

syntax

(for/mutable-seteqv (for-clause ...) body ...+)

syntax

(for/mutable-setalw (for-clause ...) body ...+)

syntax

(for*/mutable-set (for-clause ...) body ...+)

syntax

(for*/mutable-seteq (for-clause ...) body ...+)

syntax

(for*/mutable-seteqv (for-clause ...) body ...+)

syntax

(for*/mutable-setalw (for-clause ...) body ...+)

syntax

(for/weak-set (for-clause ...) body ...+)

syntax

(for/weak-seteq (for-clause ...) body ...+)

syntax

(for/weak-seteqv (for-clause ...) body ...+)

syntax

(for/weak-setalw (for-clause ...) body ...+)

syntax

(for*/weak-set (for-clause ...) body ...+)

syntax

(for*/weak-seteq (for-clause ...) body ...+)

syntax

(for*/weak-seteqv (for-clause ...) body ...+)

syntax

(for*/weak-setalw (for-clause ...) body ...+)

Analogous to for/list and for*/list, but to +construct a hash set instead of a list.

Changed in version 8.5.0.3 of package base: Added for/setalw, +for/mutable-setalw, and for/weak-setalw.

procedure

(in-immutable-set st)  sequence?

  st : set?

procedure

(in-mutable-set st)  sequence?

  st : set-mutable?

procedure

(in-weak-set st)  sequence?

  st : set-weak?
Explicitly converts a specific kind of hash set to a sequence for +use with for forms.

As with in-list and some other sequence constructors, +in-immutable-set performs better when it appears directly in a +for clause.

These sequence constructors are compatible with +Custom Hash Sets.

Added in version 6.4.0.7 of package base.

4.18.2 Set Predicates and Contracts

procedure

(generic-set? v)  boolean?

  v : any/c
Returns #t if v is a set; returns #f +otherwise.

Examples:
> (generic-set? (list 1 2 3))

#t

> (generic-set? (set 1 2 3))

#t

> (generic-set? (mutable-seteq 1 2 3))

#t

> (generic-set? (vector 1 2 3))

#f

procedure

(set-implements? st sym ...)  boolean?

  st : generic-set?
  sym : symbol?
Returns #t if st implements all of the methods from +gen:set named by the syms; returns #f otherwise. +Fallback implementations do not affect the result; st may support the +given methods via fallback implementations yet produce #f.

Examples:
> (set-implements? (list 1 2 3) 'set-add)

#t

> (set-implements? (list 1 2 3) 'set-add!)

#f

> (set-implements? (set 1 2 3) 'set-add)

#t

> (set-implements? (set 1 2 3) 'set-add!)

#t

> (set-implements? (mutable-seteq 1 2 3) 'set-add)

#t

> (set-implements? (mutable-seteq 1 2 3) 'set-add!)

#t

> (set-implements? (weak-seteqv 1 2 3) 'set-remove 'set-remove!)

#t

procedure

(set-implements/c sym ...)  flat-contract?

  sym : symbol?
Recognizes sets that support all of the methods from gen:set +named by the syms.

procedure

(set/c elem/c    
  [#:cmp cmp    
  #:kind kind    
  #:lazy? lazy?    
  #:equal-key/c equal-key/c])  contract?
  elem/c : chaperone-contract?
  cmp : (or/c 'dont-care 'equal 'equal-always 'eqv 'eq)
   = 'dont-care
  kind : (or/c 'dont-care 'immutable 'mutable 'weak 'mutable-or-weak)
   = 'immutable
  lazy? : any/c = 
(not (and (equal? kind 'immutable)
          (flat-contract? elem/c)))
  equal-key/c : contract? = any/c
Constructs a contract that recognizes sets whose elements match + elem/c.

If kind is 'immutable, 'mutable, or + 'weak, the resulting contract accepts only hash sets that + are respectively immutable, mutable with strongly-held keys, or mutable with + weakly-held keys. If kind is 'mutable-or-weak, the + resulting contract accepts any mutable hash sets, regardless of + key-holding strength.

If cmp is 'equal, 'equal-always, 'eqv, + or 'eq, the resulting contract accepts only hash sets that + compare elements using equal?, equal-always?, + eqv?, or eq?, respectively.

If cmp is 'eqv or 'eq, then elem/c must + be a flat contract.

If cmp and kind are both 'dont-care, then the + resulting contract will accept any kind of set, not just hash +sets.

If lazy? is not #f, then the elements of the set are not checked +immediately by the contract and only the set itself is checked (according to the +cmp and kind arguments). If lazy? is +#f, then the elements are checked immediately by the contract. +The lazy? argument is ignored when the set contract accepts generic sets +(i.e., when cmp and kind are both 'dont-care); in that +case, the value being checked in that case is a list?, then the contract +is not lazy otherwise the contract is lazy.

If kind allows mutable sets (i.e., is 'dont-care, +'mutable, 'weak, or +'mutable-or-weak) and lazy? is #f, then the elements +are checked both immediately and when they are accessed from the set.

The equal-key/c contract is used when values are passed to the comparison +and hashing functions used internally.

The result contract will be a flat contract when elem/c +and equal-key/c are both flat contracts, +lazy? is #f, and kind is 'immutable. +The result will be a chaperone contract when elem/c is a +chaperone contract.

Changed in version 8.3.0.9 of package base: Added support for random generation.
Changed in version 8.5.0.3: Added 'equal-always support for cmp.

4.18.3 Generic Set Interface

syntax

gen:set

A generic interface (see Generic Interfaces) that +supplies set method implementations for a structure type via the +#:methods option of struct definitions. This interface can +be used to implement any of the methods documented as +Set Methods.

Examples:
> (struct binary-set [integer]
    #:transparent
    #:methods gen:set
    [(define (set-member? st i)
       (bitwise-bit-set? (binary-set-integer st) i))
     (define (set-add st i)
       (binary-set (bitwise-ior (binary-set-integer st)
                                (arithmetic-shift 1 i))))
     (define (set-remove st i)
       (binary-set (bitwise-and (binary-set-integer st)
                                (bitwise-not (arithmetic-shift 1 i)))))])
> (define bset (binary-set 5))
> bset

(binary-set 5)

> (generic-set? bset)

#t

> (set-member? bset 0)

#t

> (set-member? bset 1)

#f

> (set-member? bset 2)

#t

> (set-add bset 4)

(binary-set 21)

> (set-remove bset 2)

(binary-set 1)

4.18.3.1 Set Methods

The methods of gen:set can be classified into three categories, as determined by their fallback implementations:

  1. methods with no fallbacks,

  2. methods whose fallbacks depend on other, non-fallback methods,

  3. and methods whose fallbacks can depend on either fallback or non-fallback methods.

As an example, implementing the following methods would guarantee that all the methods in gen:set would at least have a fallback method:

There may be other such subsets of methods that would guarantee at least a fallback for every method.

procedure

(set-member? st v)  boolean?

  st : generic-set?
  v : any/c
Returns #t if v is in st, #f +otherwise. Has no fallback.

procedure

(set-add st v)  generic-set?

  st : generic-set?
  v : any/c
Produces a set that includes v plus all elements of +st. This operation runs in constant time for hash sets. Has no fallback.

procedure

(set-add! st v)  void?

  st : generic-set?
  v : any/c
Adds the element v to st. This operation runs in constant +time for hash sets. Has no fallback.

For hash sets, see also the caveats concerning concurrent modification +for hash tables, which applies to +hash sets.

procedure

(set-remove st v)  generic-set?

  st : generic-set?
  v : any/c
Produces a set that includes all elements of st except +v. This operation runs in constant time for hash sets. Has no fallback.

procedure

(set-remove! st v)  void?

  st : generic-set?
  v : any/c
Removes the element v from st. This operation runs in constant +time for hash sets. Has no fallback.

For hash sets, see also the caveats concerning concurrent modification +for hash tables, which applies to +hash sets.

procedure

(set-empty? st)  boolean?

  st : generic-set?
Returns #t if st has no members; returns #f +otherwise.

Supported for any st that implements set->stream or +set-count.

procedure

(set-count st)  exact-nonnegative-integer?

  st : generic-set?
Returns the number of elements in st.

Supported for any st that supports set->stream.

procedure

(set-first st)  any/c

  st : (and/c generic-set? (not/c set-empty?))
Produces an unspecified element of st. Multiple uses of +set-first on st produce the same result.

Supported for any st that implements set->stream.

procedure

(set-rest st)  generic-set?

  st : (and/c generic-set? (not/c set-empty?))
Produces a set that includes all elements of st except +(set-first st).

Supported for any st that implements set-remove and either +set-first or set->stream.

procedure

(set->stream st)  stream?

  st : generic-set?
Produces a stream containing the elements of st.

Supported for any st that implements: +

procedure

(set-copy st)  generic-set?

  st : generic-set?
Produces a new, mutable set of the same type and with the same elements as +st.

Supported for any st that supports set->stream and +implements set-copy-clear and set-add!.

procedure

(set-copy-clear st)  (and/c generic-set? set-empty?)

  st : generic-set?
Produces a new, empty set of the same type, mutability, and key strength as +st.

A difference between set-copy-clear and set-clear is +that the latter conceptually iterates set-remove on the given +set, and so it preserves any contract on the given set. The +set-copy-clear function produces a new set without any +contracts.

The set-copy-clear function must call concrete set constructors +and thus has no generic fallback.

procedure

(set-clear st)  (and/c generic-set? set-empty?)

  st : generic-set?
Produces a set like st but with all elements removed.

Supported for any st that implements set-remove and supports +set->stream.

procedure

(set-clear! st)  void?

  st : generic-set?
Removes all elements from st.

Supported for any st that implements set-remove! and either +supports set->stream or implements set-first and either set-count or set-empty?.

For hash sets, see also the caveats concerning concurrent modification +for hash tables, which applies to +hash sets.

procedure

(set-union st0 st ...)  generic-set?

  st0 : generic-set?
  st : generic-set?
Produces a set of the same type as st0 that includes the elements from +st0 and all of the sts.

If st0 is a list, each st must also be a list. This +operation runs on lists in time proportional to the total size of the +sts times the size of the result.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +total size of all of the sets except the largest immutable set.

At least one set must be provided to set-union to determine the type +of the resulting set (list, hash set, etc.). If there is a case where +set-union may be applied to zero arguments, instead pass an empty set +of the intended type as the first argument.

Supported for any st that implements set-add and supports set->stream.

Examples:
> (set-union (set))

(set)

> (set-union (seteq))

(seteq)

> (set-union (set 1 2) (set 2 3))

(set 1 2 3)

> (set-union (list 1 2) (list 2 3))

'(3 1 2)

> (set-union (set 1 2) (seteq 2 3))

set-union: set arguments have incompatible equivalence

predicates

  first set: (set 1 2)

  incompatible set: (seteq 2 3)

; Sets of different types cannot be unioned

procedure

(set-union! st0 st ...)  void?

  st0 : generic-set?
  st : generic-set?
Adds the elements from all of the sts to st0.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +total size of the sts.

Supported for any st that implements set-add! and supports set->stream.

For hash sets, see also the caveats concerning concurrent modification +for hash tables, which applies to +hash sets.

procedure

(set-intersect st0 st ...)  generic-set?

  st0 : generic-set?
  st : generic-set?
Produces a set of the same type as st0 that includes the elements from +st0 that are also contained by all of the sts.

If st0 is a list, each st must also be a list. This +operation runs on lists in time proportional to the total size of the +sts times the size of st0.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +size of the smallest immutable set.

Supported for any st that implements either set-remove or +both set-clear and set-add, and supports set->stream.

procedure

(set-intersect! st0 st ...)  void?

  st0 : generic-set?
  st : generic-set?
Removes every element from st0 that is not contained by all of the +sts.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +size of st0.

Supported for any st that implements set-remove! and supports set->stream.

For hash sets, see also the caveats concerning concurrent modification +for hash tables, which applies to +hash sets.

procedure

(set-subtract st0 st ...)  generic-set?

  st0 : generic-set?
  st : generic-set?
Produces a set of the same type as st0 that includes the elements from +st0 that are not contained by any of the sts.

If st0 is a list, each st must also be a list. This +operation runs on lists in time proportional to the total size of the +sts times the size of st0.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +size of st0.

Supported for any st that implements either set-remove or +both set-clear and set-add, and supports set->stream.

procedure

(set-subtract! st0 st ...)  void?

  st0 : generic-set?
  st : generic-set?
Removes every element from st0 that is contained by any of the +sts.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +size of st0.

Supported for any st that implements set-remove! and supports set->stream.

For hash sets, see also the caveats concerning concurrent modification +for hash tables, which applies to +hash sets.

procedure

(set-symmetric-difference st0 st ...)  generic-set?

  st0 : generic-set?
  st : generic-set?
Produces a set of the same type as st0 that includes all of the +elements contained an odd number of times in st0 and the +sts.

If st0 is a list, each st must also be a list. This +operation runs on lists in time proportional to the total size of the +sts times the size of st0.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +total size of all of the sets except the largest immutable set.

Supported for any st that implements set-remove or both set-clear and set-add, and supports set->stream.

Example:
> (set-symmetric-difference (set 1) (set 1 2) (set 1 2 3))

(set 1 3)

procedure

(set-symmetric-difference! st0 st ...)  void?

  st0 : generic-set?
  st : generic-set?
Adds and removes elements of st0 so that it includes all of the +elements contained an odd number of times in the sts and the +original contents of st0.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +total size of the sts.

Supported for any st that implements set-remove! and supports set->stream.

For hash sets, see also the caveats concerning concurrent modification +for hash tables, which applies to +hash sets.

procedure

(set=? st st2)  boolean?

  st : generic-set?
  st2 : generic-set?
Returns #t if st and st2 contain the same +members; returns #f otherwise.

If st0 is a list, each st must also be a list. This +operation runs on lists in time proportional to the size of st times +the size of st2.

If st0 is a hash set, each st must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +size of st plus the size of st2.

Supported for any st and st2 that both support +subset?; also supported for any if st2 that implements +set=? regardless of st.

Examples:
> (set=? (list 1 2) (list 2 1))

#t

> (set=? (set 1) (set 1 2 3))

#f

> (set=? (set 1 2 3) (set 1))

#f

> (set=? (set 1 2 3) (set 1 2 3))

#t

> (set=? (seteq 1 2) (mutable-seteq 2 1))

#t

> (set=? (seteq 1 2) (seteqv 1 2))

set=?: set arguments have incompatible equivalence

predicates

  first set: (seteq 1 2)

  incompatible set: (seteqv 1 2)

; Sets of different types cannot be compared

procedure

(subset? st st2)  boolean?

  st : generic-set?
  st2 : generic-set?
Returns #t if st2 contains every member of st; +returns #f otherwise.

If st is a list, then st2 must also be a list. This +operation runs on lists in time proportional to the size of st times +the size of st2.

If st is a hash set, then st2 must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +size of st.

Supported for any st that supports set->stream.

Examples:
> (subset? (set 1) (set 1 2 3))

#t

> (subset? (set 1 2 3) (set 1))

#f

> (subset? (set 1 2 3) (set 1 2 3))

#t

procedure

(proper-subset? st st2)  boolean?

  st : generic-set?
  st2 : generic-set?
Returns #t if st2 contains every member of st and at +least one additional element; returns #f otherwise.

If st is a list, then st2 must also be a list. This +operation runs on lists in time proportional to the size of st times +the size of st2.

If st is a hash set, then st2 must also be a +hash set that uses the same comparison function (equal?, +equal-always?, eqv?, or eq?). +The mutability and key strength of the hash +sets may differ. This operation runs on hash sets in time proportional to the +size of st plus the size of st2.

Supported for any st and st2 that both support +subset?.

Examples:
> (proper-subset? (set 1) (set 1 2 3))

#t

> (proper-subset? (set 1 2 3) (set 1))

#f

> (proper-subset? (set 1 2 3) (set 1 2 3))

#f

procedure

(set->list st)  list?

  st : generic-set?
Produces a list containing the elements of st.

Supported for any st that supports set->stream.

procedure

(set-map st proc)  (listof any/c)

  st : generic-set?
  proc : (any/c . -> . any/c)
Applies the procedure proc to each element in +st in an unspecified order, accumulating the results +into a list.

Supported for any st that supports set->stream.

procedure

(set-for-each st proc)  void?

  st : generic-set?
  proc : (any/c . -> . any)
Applies proc to each element in st (for the +side-effects of proc) in an unspecified order.

Supported for any st that supports set->stream.

procedure

(in-set st)  sequence?

  st : generic-set?
Explicitly converts a set to a sequence for use with for and +other forms.

Supported for any st that supports set->stream.

procedure

(impersonate-hash-set st 
  inject-proc 
  add-proc 
  shrink-proc 
  extract-proc 
  [clear-proc 
  equal-key-proc] 
  prop 
  prop-val ... 
  ...) 
  (and/c (or/c set-mutable? set-weak?) impersonator?)
  st : (or/c set-mutable? set-weak?)
  inject-proc : (or/c #f (-> set? any/c any/c))
  add-proc : (or/c #f (-> set? any/c any/c))
  shrink-proc : (or/c #f (-> set? any/c any/c))
  extract-proc : (or/c #f (-> set? any/c any/c))
  clear-proc : (or/c #f (-> set? any)) = #f
  equal-key-proc : (or/c #f (-> set? any/c any/c)) = #f
  prop : impersonator-property?
  prop-val : any/c
Impersonates st, redirecting various set operations via the given procedures.

The inject-proc procedure +is called whenever an element is temporarily put into the set for the purposes +of comparing it with other elements that may already be in the set. For example, +when evaluating (set-member? s e), e will be passed to the +inject-proc before comparing it with other elements of s.

The add-proc procedure is called when adding an element to a set, e.g., +via set-add or set-add!. The result of the add-proc is +stored in the set.

The shrink-proc procedure is called when building a new set with +one fewer element. For example, when evaluating (set-remove s e) +or (set-remove! s e), +an element is removed from a set, e.g., +via set-remove or set-remove!. The result of the shrink-proc +is the element actually removed from the set.

The extract-proc procedure is called when an element is pulled out of +a set, e.g., by set-first. The result of the extract-proc is +the element actually produced by from the set.

The clear-proc is called by set-clear and set-clear! +and if it returns (as opposed to escaping, perhaps via raising an exception), +the clearing operation is permitted. Its result is ignored. If clear-proc +is #f, then clearing is done element by element (via calls into the other +supplied procedures).

The equal-key-proc is called when an element’s hash code is needed of when an +element is supplied to the underlying equality in the set. The result of +equal-key-proc is used when computing the hash or comparing for equality.

If any of the inject-proc, add-proc, shrink-proc, or +extract-proc arguments are #f, then they all must be #f, +the clear-proc and equal-key-proc must also be #f, +and there must be at least one property supplied.

Pairs of prop and prop-val (the number of arguments to +impersonate-hash-set must be odd) add impersonator properties or +override impersonator property values of st.

procedure

(chaperone-hash-set st 
  inject-proc 
  add-proc 
  shrink-proc 
  extract-proc 
  [clear-proc 
  equal-key-proc] 
  prop 
  prop-val ... 
  ...) 
  (and/c (or/c set? set-mutable? set-weak?) chaperone?)
  st : (or/c set? set-mutable? set-weak?)
  inject-proc : (or/c #f (-> set? any/c any/c))
  add-proc : (or/c #f (-> set? any/c any/c))
  shrink-proc : (or/c #f (-> set? any/c any/c))
  extract-proc : (or/c #f (-> set? any/c any/c))
  clear-proc : (or/c #f (-> set? any)) = #f
  equal-key-proc : (or/c #f (-> set? any/c any/c)) = #f
  prop : impersonator-property?
  prop-val : any/c
Chaperones st. Like impersonate-hash-set but with +the constraints that the results of the inject-proc, +add-proc, shrink-proc, extract-proc, and +equal-key-proc must be +chaperone-of? their second arguments. Also, the input +may be an immutable? set.

4.18.4 Custom Hash Sets

syntax

(define-custom-set-types name
                         optional-predicate
                         comparison-expr
                         optional-hash-functions)
 
optional-predicate = 
  | #:elem? predicate-expr
     
optional-hash-functions = 
  | hash1-expr
  | hash1-expr hash2-expr
Creates a new hash set type based on the given comparison comparison-expr, +hash functions hash1-expr and hash2-expr, and element +predicate predicate-expr; the interfaces for these functions are the +same as in make-custom-set-types. The new set type has three +variants: immutable, mutable with strongly-held elements, and mutable with +weakly-held elements.

Defines seven names:

  • name? recognizes instances of the new type,

  • immutable-name? recognizes +immutable instances of the new type,

  • mutable-name? recognizes +mutable instances of the new type with strongly-held elements,

  • weak-name? recognizes +mutable instances of the new type with weakly-held elements,

  • make-immutable-name constructs +immutable instances of the new type,

  • make-mutable-name constructs +mutable instances of the new type with strongly-held elements, and

  • make-weak-name constructs +mutable instances of the new type with weakly-held elements.

The constructors all accept a stream as an optional argument, providing +initial elements.

Examples:
> (define-custom-set-types string-set
                           #:elem? string?
                           string=?
                           string-length)
> (define imm
    (make-immutable-string-set '("apple" "banana")))
> (define mut
    (make-mutable-string-set '("apple" "banana")))
> (generic-set? imm)

#t

> (generic-set? mut)

#t

> (set? imm)

#t

> (generic-set? imm)

#t

> (string-set? imm)

#t

> (string-set? mut)

#t

> (immutable-string-set? imm)

#t

> (immutable-string-set? mut)

#f

> (set-member? imm "apple")

#t

> (set-member? mut "banana")

#t

> (equal? imm mut)

#f

> (set=? imm mut)

#t

> (set-remove! mut "banana")
> (set-member? mut "banana")

#f

> (equal? (set-remove (set-remove imm "apple") "banana")
          (make-immutable-string-set))

#t

procedure

(make-custom-set-types eql? 
  [hash1 
  hash2 
  #:elem? elem? 
  #:name name 
  #:for who]) 
  
(any/c . -> . boolean?)
(any/c . -> . boolean?)
(any/c . -> . boolean?)
(any/c . -> . boolean?)
(->* [] [stream?] generic-set?)
(->* [] [stream?] generic-set?)
(->* [] [stream?] generic-set?)
  eql? : 
(or/c (any/c any/c . -> . any/c)
      (any/c any/c (any/c any/c . -> . any/c) . -> . any/c))
  hash1 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  hash2 : 
(or/c (any/c . -> . exact-integer?)
      (any/c (any/c . -> . exact-integer?) . -> . exact-integer?))
   = (const 1)
  elem? : (any/c . -> . boolean?) = (const #true)
  name : symbol? = 'custom-set
  who : symbol? = 'make-custom-set-types
Creates a new set type based on the given comparison function eql?, +hash functions hash1 and hash2, and predicate elem?. +The new set type has variants that are immutable, mutable with strongly-held +elements, and mutable with weakly-held elements. The given name is +used when printing instances of the new set type, and the symbol who +is used for reporting errors.

The comparison function eql? may accept 2 or 3 arguments. If it +accepts 2 arguments, it given two elements to compare them. If it accepts 3 +arguments and does not accept 2 arguments, it is also given a recursive +comparison function that handles data cycles when comparing sub-parts of the +elements.

The hash functions hash1 and hash2 may accept 1 or 2 +arguments. If either hash function accepts 1 argument, it is applied to a +element to compute the corresponding hash value. If either hash function +accepts 2 arguments and does not accept 1 argument, it is also given a +recursive hash function that handles data cycles when computing hash values of +sub-parts of the elements.

The predicate elem? must accept 1 argument and is used to recognize +valid elements for the new set type.

Produces seven values:

  • a predicate recognizing all instances of the new set type,

  • a predicate recognizing weak instances,

  • a predicate recognizing mutable instances,

  • a predicate recognizing immutable instances,

  • a constructor for weak instances,

  • a constructor for mutable instances, and

  • a constructor for immutable instances.

See define-custom-set-types for an example.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/sha.html b/clones/docs.racket-lang.org/reference/sha.html new file mode 100644 index 00000000..a337e288 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/sha.html @@ -0,0 +1,20 @@ + +13.11 Cryptographic Hashing

13.11 Cryptographic Hashing

procedure

(sha1-bytes in [start end])  bytes?

  in : (or/c bytes? input-port?)
  start : exact-nonnegative-integer? = 0
  end : (or/c #f exact-nonnegative-integer?) = #f

procedure

(sha224-bytes in [start end])  bytes?

  in : (or/c bytes? input-port?)
  start : exact-nonnegative-integer? = 0
  end : (or/c #f exact-nonnegative-integer?) = #f

procedure

(sha256-bytes in [start end])  bytes?

  in : (or/c bytes? input-port?)
  start : exact-nonnegative-integer? = 0
  end : (or/c #f exact-nonnegative-integer?) = #f
Computes the SHA-1, SHA-224, or SHA-256 hash of a byte sequence and +returns the hash as a byte string with 20 bytes, 28 bytes, or 32 +bytes, respectively.

The start and end arguments determine the range of +bytes of the input that are used to compute the hash. An end +value of #f corresponds to the end of the byte string or an +end-of-file position for an input port. When in is a byte +string, the start and end values (when non +#f) must be no greater than the length of the byte string, +and start must be no greater than end. When +in is an input port, start must be no greater than +end; if in supplies less than start or +end bytes before an end-of-file, then start and/or +end is effectively changed to the number of supplied bytes +(so that an empty or truncated byte sequence is hashed). When +in is an input port and end is a number, then at +most end bytes are read from the input port.

For security purposes, favor sha224-bytes and +sha256-bytes (which are part of the SHA-2 family) over +sha1-bytes.

Use bytes->hex-string from file/sha1 to +convert a byte string hash to a human-readable string.

Examples:
> (sha1-bytes #"abc")

#"\251\231>6G\6\201j\272>%qxP\302l\234\320\330\235"

> (require file/sha1)
> (bytes->hex-string (sha1-bytes #"abc"))

"a9993e364706816aba3e25717850c26c9cd0d89d"

> (bytes->hex-string (sha224-bytes #"abc"))

"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"

> (bytes->hex-string (sha224-bytes (open-input-string "xabcy") 1 4))

"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"

Added in version 7.0.0.5 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/shared.html b/clones/docs.racket-lang.org/reference/shared.html new file mode 100644 index 00000000..1997f500 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/shared.html @@ -0,0 +1,46 @@ + +3.11 Constructing Graphs: shared
On this page:
shared

3.11 Constructing Graphs: shared

 (require racket/shared) package: base
The bindings documented in this section are provided by the racket/shared and racket libraries, but not racket/base.

syntax

(shared ([id expr] ...) body ...+)

Binds ids with shared structure according to exprs +and then evaluates the bodys, returning the result of +the last expression.

The shared form is similar to letrec, except that +special forms of expr are recognized (after partial macro +expansion) to construct graph-structured data, where the corresponding +letrec would instead produce a use-before-initialization error.

Each expr (after partial expansion) is matched against the +following shared-expr grammar, where earlier variants in a +production take precedence over later variants:

  shared-expr = shell-expr
  | plain-expr
     
  shell-expr = (cons in-immutable-expr in-immutable-expr)
  | (list in-immutable-expr ...)
  | (list* in-immutable-expr ...)
  | (append early-expr ... in-immutable-expr)
  | (vector-immutable in-immutable-expr ...)
  | (box-immutable in-immutable-expr)
  | (mcons patchable-expr patchable-expr)
  | (vector patchable-expr ...)
  | (box patchable-expr)
  | (prefix:make-id patchable-expr ...)
     
  in-immutable-expr = shell-id
  | shell-expr
  | early-expr
     
  shell-id = id
     
  patchable-expr = expr
     
  early-expr = expr
     
  plain-expr = expr

The prefix:make-id identifier above matches three kinds of references. The +first kind is any binding whose name has make- in the +middle, and where prefix:id has a transformer binding to +structure information with a full set of mutator bindings; see +Structure Type Transformer Binding. The second kind is an identifier that itself has a +transformer binding to structure information. The third kind is an +identifier that has a 'constructor-for syntax property +whose value is an identifier with a transformer binding to structure +information. A shell-id, meanwhile, must be one of the +ids bound by the shared form to a +shell-expr.

When the exprs of the shared form are parsed as +shared-expr (taking into account the order of the variants +for parsing precedence), the sub-expressions that were parsed via +early-expr will be evaluated first when the shared +form is evaluated. Among such expressions, they are evaluated in the +order as they appear within the shared form. However, any +reference to an id bound by shared produces +a use-before-initialization errror, even if the binding for the id appears +before the corresponding early-expr within the +shared form.

The shell-ids and shell-exprs (not counting +patchable-expr and early-expr sub-expressions) are +effectively evaluated next:

  • A shell-id reference produces the same value as the +corresponding id will produce within the +bodys, assuming that id is never mutated +with set!. This special handling of a +shell-id reference is one way in which +shared supports the creation of cyclic data, including +immutable cyclic data.

  • A shell-expr of the form (mcons patchable-expr patchable-expr), (vector patchable-expr ...), (box patchable-expr), or (prefix:make-id patchable-expr ...) produces a mutable value whose content +positions are initialized to undefined. Each content +position is patched (i.e., updated) after the +corresponding patchable-expr expression is later +evaluated.

Next, the plain-exprs are evaluated as for letrec, +where a reference to an id raises exn:fail:contract:variable if it +is evaluated before the right-hand side of the id binding.

Finally, the patchable-exprs are evaluated and their values +replace undefineds in the results of +shell-exprs. At this point, all ids are bound, so +patchable-exprs can create data cycles (but only with cycles +that can be created via mutation).

Examples:
> (shared ([a (cons 1 a)])
    a)

#0='(1 . #0#)

> (shared ([a (cons 1 b)]
           [b (cons 2 a)])
    a)

#0='(1 2 . #0#)

> (shared ([a (cons 1 b)]
           [b 7])
    a)

'(1 . 7)

> (shared ([a a]) ; no indirection...
    a)

a: undefined;

 cannot use before initialization

> (shared ([a (cons 1 b)] ; b is early...
           [b a])
    a)

a: undefined;

 cannot use before initialization

> (shared ([a (mcons 1 b)] ; b is patchable...
           [b a])
    a)

#0=(mcons 1 #0#)

> (shared ([a (vector b b b)]
           [b (box 1)])
    (set-box! b 5)
    a)

'#(#&5 #&5 #&5)

> (shared ([a (box b)]
           [b (vector (unbox a)   ; unbox after a is patched
                      (unbox c))] ; unbox before c is patched
           [c (box b)])
    b)

#0='#(#0# #<undefined>)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/single-unit.html b/clones/docs.racket-lang.org/reference/single-unit.html new file mode 100644 index 00000000..aaefc29b --- /dev/null +++ b/clones/docs.racket-lang.org/reference/single-unit.html @@ -0,0 +1,11 @@ + +7.10 Single-Unit Modules

7.10 Single-Unit Modules

When racket/unit is used as a language name with +#lang, the module body is treated as a unit body. The +body must match the following module-body grammar:

  module-body = 
require-decl ...
(import tagged-sig-expr ...)
(export tagged-sig-expr ...)
init-depends-decl
unit-body-expr-or-defn
...
     
  require-decl = (require require-spec ...)
  | (begin require-decl ...)
  | derived-require-form

After any number of require-decls, the content of the module +is the same as a unit body.

The resulting unit is exported as base@, +where base is derived from the enclosing module’s name +(i.e., its symbolic name, or its path without the directory and file +suffix). If the module name ends in -unit, then +base corresponds to the module name before +-unit. Otherwise, the module name serves as +base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/special-comments.html b/clones/docs.racket-lang.org/reference/special-comments.html new file mode 100644 index 00000000..2f536b1f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/special-comments.html @@ -0,0 +1,10 @@ + +13.7.3 Special Comments
13.7.3 Special Comments

procedure

(make-special-comment v)  special-comment?

  v : any/c
Creates a special-comment value that encapsulates v. The +read, read-syntax, etc., procedures treat values +constructed with make-special-comment as delimiting +whitespace when returned by a reader-extension procedure (see +Reader-Extension Procedures).

procedure

(special-comment? v)  boolean?

  v : any/c
Returns #t if v is the result of +make-special-comment, #f otherwise.

procedure

(special-comment-value sc)  any

  sc : special-comment?
Returns the value encapsulated by the special-comment value +sc. This value is never used directly by a reader, but it +might be used by the context of a read-char-or-special, etc., +call that detects a special comment.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/splicing.html b/clones/docs.racket-lang.org/reference/splicing.html new file mode 100644 index 00000000..7c923b4a --- /dev/null +++ b/clones/docs.racket-lang.org/reference/splicing.html @@ -0,0 +1,29 @@ + +12.6 Local Binding with Splicing Body

12.6 Local Binding with Splicing Body

The bindings documented in this section are provided by the racket/splicing library, not racket/base or racket.

Like let (not named let), letrec, let-values, +letrec-values, let-syntax, letrec-syntax, +let-syntaxes, letrec-syntaxes, +letrec-syntaxes+values, local, and +parameterize, except that in a definition context, the body +forms are spliced into the enclosing definition context (in the same +way as for begin).

Examples:
> (splicing-let-syntax ([one (lambda (stx) #'1)])
    (define o one))
> o

1

> one

one: undefined;

 cannot reference an identifier before its definition

  in module: top-level

When a splicing binding form occurs in a top-level context or +module context, its local bindings are treated similarly to +definitions. In particular, syntax bindings are +evaluated every time the module is visited, instead of only +once during compilation as in let-syntax, etc.

Example:
> (splicing-letrec ([x bad]
                    [bad 1])
    x)

bad.1: undefined;

 cannot reference an identifier before its definition

  in module: top-level

If a definition within a splicing form is intended to be local to the +splicing body, then the identifier should have a true value for the +'definition-intended-as-local syntax property. For +example, splicing-let itself adds the property to +locally-bound identifiers as it expands to a sequence of definitions, +so that nesting splicing-let within a splicing form works as +expected (without any ambiguous bindings).

Changed in version 6.12.0.2 of package base: Added splicing-parameterize.

Like syntax-parameterize, except that in a definition context, the body +forms are spliced into the enclosing definition context (in the same way as for +begin). In a definition context, the body of +splicing-syntax-parameterize can be empty.

Note that require transformers and provide transformers are not +affected by syntax parameterization. While all uses of require and +provide will be spliced into the enclosing context, derived import or +export specifications will expand as if they had not been inside of the +splicing-syntax-parameterize.

Additionally, submodules defined with module* that specify +#f in place of a module path are affected by syntax +parameterization, but other submodules (those defined with module or +module* with a module path) are not.

Examples:
> (define-syntax-parameter place (lambda (stx) #'"Kansas"))
> (define-syntax-rule (where) `(at ,(place)))
> (where)

'(at "Kansas")

> (splicing-syntax-parameterize ([place (lambda (stx) #'"Oz")])
    (define here (where)))
> here

'(at "Oz")

Changed in version 6.11.0.1 of package base: Modified to syntax parameterize module* submodules that +specify #f in place of a module path.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stencil_vectors.html b/clones/docs.racket-lang.org/reference/stencil_vectors.html new file mode 100644 index 00000000..5c221f34 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stencil_vectors.html @@ -0,0 +1,50 @@ + +4.13 Stencil Vectors

4.13 Stencil Vectors

A stencil vector is like a vector, but it has an +associated mask fixnum where the number of bits set in the mask +determines the length of the vector. A stencil vector is useful for +implementing some data structures [Torosyan21], such as a hash +array mapped trie (HAMT).

Conceptually, a stencil vector’s mask indicates which virtual elements +of a full-sized stencil vector are present, but mask bits have no +effect on access or mutation via stencil-vector-ref and +stencil-vector-set!. For example, such a stencil vector has a +mask 25, which could also be written #b11001; +reading from low bit to high, that mask represents values present at +the first, fourth, and fifth virtual slots. If that stencil vector’s +elements are 'a, 'b, and 'c, then +'a is at virtual slot 0 and accessed with index 0, +'b is at virtual slot 3 and accessed with index 1, +and 'c is at virtual slot 4 and accessed with index +2.

The relative order of bits in a mask is relevant for a +functional-update operation with stencil-vector-update. +Elements to remove are specified with a removal mask, and elements to +add are ordered relative to remaining elements through an addition +mask. For example, starting with the stencil vector whose mask is +#b11001 with elements 'a, 'b, and +'c, adding new elements 'd and 'e using the +addition mask #b100100 produces a stencil vector whose +mask is #b111101 and whose elements in order are +'a, 'b, 'd, 'c, and 'e.

The maximum size of a stencil vector is 58 elements on a 64-bit +platform and 26 elements on a 32-bit platform. This limited size +enables a compact internal representation and ensures that update +operations are relatively simple. Stencil vectors are mutable, +although they are intended primarily for use without mutation to +implement a persistent data structure.

Two stencil vectors are equal? if they have the same mask, +and if the values in corresponding slots of the stencil vectors are +equal?.

A printed vector starts with #<stencil ...>, and this +printed form cannot be parsed by read. The +s-exp->fasl and serialize functions do not support +stencil vectors, in part because a stencil vector on a 64-bit platform +might not be representable on a 32-bit platform. The intent is that +stencil vectors are used as an in-memory representation for a datatype +implementation.

Added in version 8.5.0.7 of package base.

procedure

(stencil-vector? v)  boolean?

  v : any/c
Returns #t if v is a stencil vector, #f otherwise.

Examples:
> (stencil-vector #b10010 'a 'b)

#<stencil 18: a b>

> (stencil-vector #b111 'a 'b 'c)

#<stencil 7: a b c>

Added in version 8.5.0.7 of package base.

Returns the maximum number of elements allowed in a stencil vector on +the current platform. The result is 58 on a 64-bit platform +or 26 on a 32-bit platform.

procedure

(stencil-vector mask v ...)  stencil-vector?

  mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  v : any/c
Returns a stencil vector combining mask with elements +v. The number of supplied vs must match the number +of bits set in mask’s two’s complement representation.

Added in version 8.5.0.7 of package base.

procedure

(stencil-vector-mask vec)

  (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  vec : stencil-vector?
Returns the mask of vec. Note that the mask of a stencil +vector is determined at creation time and cannot be changed later.

Example:
> (stencil-vector-mask (stencil-vector #b10010 'a 'b))

18

Added in version 8.5.0.7 of package base.

Returns the length of vec (i.e., the number of slots in the +vector). The result is the same as (fxpopcount (stencil-vector-mask vec)).

Example:
> (stencil-vector-length (stencil-vector #b10010 'a 'b))

2

Added in version 8.5.0.7 of package base.

procedure

(stencil-vector-ref vec pos)  any/c

  vec : stencil-vector?
  pos : exact-nonnegative-integer?
Returns the element in slot pos of vec. The first +slot is position 0, and the last slot is one less than +(stencil-vector-length vec).

Examples:
> (stencil-vector-ref (stencil-vector #b10010 'a 'b) 1)

'b

> (stencil-vector-ref (stencil-vector #b111 'a 'b 'c) 1)

'b

Added in version 8.5.0.7 of package base.

procedure

(stencil-vector-set! vec pos v)  avoid?

  vec : stencil-vector?
  pos : exact-nonnegative-integer?
  v : any/c
Updates the slot pos of vec to contain v.

Examples:
> (define st-vec (stencil-vector #b101 'a 'b))
> st-vec

#<stencil 5: a b>

> (stencil-vector-set! st-vec 1 'c)
> st-vec

#<stencil 5: a c>

Added in version 8.5.0.7 of package base.

procedure

(stencil-vector-update vec    
  remove-mask    
  add-mask    
  v ...)  stencil-vector?
  vec : stencil-vector?
  remove-mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  add-mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  v : any/c
Returns a stencil vector that is like vec, but with elements +corresponding to remove-mask removed, and with the given +vs added at positions relative to existing (unremoved) +elements determined by add-mask.

Examples:
> (define st-vec (stencil-vector #b101 'a 'b))
> (stencil-vector-update st-vec #b0 #b10 'c)

#<stencil 7: a c b>

> (stencil-vector-update st-vec #b0 #b1000 'c)

#<stencil 13: a b c>

> st-vec ; unchanged by updates

#<stencil 5: a b>

> (stencil-vector-update st-vec #b1 #b1 'c)

#<stencil 5: c b>

> (stencil-vector-update st-vec #b100 #b100 'c)

#<stencil 5: a c>

> (stencil-vector-update st-vec #b100 #b0)

#<stencil 1: a>

Added in version 8.5.0.7 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stratified-body.html b/clones/docs.racket-lang.org/reference/stratified-body.html new file mode 100644 index 00000000..1e7a34ee --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stratified-body.html @@ -0,0 +1,9 @@ + +3.24 Internal-Definition Limiting: #%stratified-body
On this page:
#%stratified-body

3.24 Internal-Definition Limiting: #%stratified-body

syntax

(#%stratified-body defn-or-expr ...)

Like (let () defn-or-expr ...) for an +internal-definition context sequence, except that an expression +is not allowed to precede a definition, and all definitions are +treated as referring to all other definitions (i.e., locations +for variables are all allocated first, like letrec and +unlike letrec-syntaxes+values).

The #%stratified-body form is useful for implementing +syntactic forms or languages that supply a more limited kind of +internal-definition context.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/streams.html b/clones/docs.racket-lang.org/reference/streams.html new file mode 100644 index 00000000..e450899c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/streams.html @@ -0,0 +1,104 @@ + +4.16.2 Streams
4.16.2 Streams

A stream is a kind of sequence that supports +functional iteration via stream-first and +stream-rest. The stream-cons form constructs a lazy +stream, but plain lists can be used as streams, and functions such as +in-range and in-naturals also create streams.

 (require racket/stream) package: base
The bindings documented in this section are provided by the racket/stream and racket libraries, but not racket/base.

procedure

(stream? v)  boolean?

  v : any/c
Returns #t if v can be used as a stream, +#f otherwise.

procedure

(stream-empty? s)  boolean?

  s : stream?
Returns #t if s has no elements, #f +otherwise.

procedure

(stream-first s)  any

  s : (and/c stream? (not/c stream-empty?))
Returns the value(s) of the first element in s.

procedure

(stream-rest s)  stream?

  s : (and/c stream? (not/c stream-empty?))
Returns a stream that is equivalent to s without its first +element.

syntax

(stream-cons first-expr rest-expr)

(stream-cons #:eager first-expr rest-expr)
(stream-cons first-expr #:eager rest-expr)
(stream-cons #:eager first-expr #:eager rest-expr)
Produces a stream whose first element is determined by +first-expr and whose rest is determined by +rest-expr.

If first-expr is not preceded by #:eager, then +first-expr is not evaluated immediately. Instead, +stream-first on the result stream forces the evaluation of +first-expr (once) to produce the first element of the +stream. If evaluating first-expr raises an exception or +tries to force itself, then an exn:fail:contract exception is raised, and +future attempts to force evaluation will trigger another exception.

If rest-expr is not preceded by #:eager, then +rest-expr is not evaluated immediately. Instead, +stream-rest on the result stream produces another stream +that is like the one produced by (stream-lazy rest-expr).

The first element of the stream as produced by first-expr +must be a single value. The rest-expr must produce a stream +when it is evaluated, otherwise the exn:fail:contract? exception is raised.

Changed in version 8.0.0.12 of package base: Added #:eager options.

syntax

(stream-lazy stream-expr)

(stream-lazy #:who who-expr stream-expr)
Similar to (delay stream-expr), but the result is a stream +instead of a promise, and stream-expr must produce a +stream when it is eventually forced. The stream produced by +stream-lazy has the same content as the stream produced by +stream-expr; that is, operations like stream-first +on the result stream will force stream-expr and retry on its +result.

If evaluating stream-expr raises an exception or tries to +force itself, then an exn:fail:contract exception is raised, and future +attempts to force evaluation will trigger another exception.

If who-expr is provided, it is evaluated when constructing +the delayed stream. If stream-expr later produces a value +that is not a stream, and if who-expr produced a symbol +value, then the symbol is used for the error message.

Added in version 8.0.0.12 of package base.

procedure

(stream-force s)  stream?

  s : stream?
Forces the evaluation of a delayed stream from stream-lazy, +from the stream-rest of a stream-cons, etc., +returning the forced stream. If s is not a delayed stream, +then s is returned.

Normally, stream-force is not needed, because operations +like stream-first, stream-rest, and +stream-empty? force a delayed stream as needed. In rare +cases, stream-force can be useful to reveal the underlying +implementation of a stream (e.g., a stream that is an instance of a +structure type that has the prop:stream property).

Added in version 8.0.0.12 of package base.

syntax

(stream e ...)

A shorthand for nested stream-conses ending with +empty-stream. As a match pattern, stream +matches a stream with as many elements as es, +and each element must match the corresponding e pattern.

syntax

(stream* e ... tail)

A shorthand for nested stream-conses, but the tail + must produce a stream when it is forced, and that stream is used as the rest of the stream instead of + empty-stream. Similar to list* but for streams. + As a match pattern, stream* is similar to a stream pattern, + but the tail pattern matches the “rest” of the stream after the last e.

Added in version 6.3 of package base.
Changed in version 8.0.0.12: Changed to delay rest-expr even +if zero exprs are provided.

procedure

(in-stream s)  sequence?

  s : stream?
Returns a sequence that is equivalent to s. +
An in-stream application can provide better performance for streams iteration when it appears directly in a for clause.
See for for information on the reachability of stream elements +during an iteration.

Changed in version 6.7.0.4 of package base: Improved element-reachability guarantee for streams in for.

A stream with no elements.

procedure

(stream->list s)  list?

  s : stream?
Returns a list whose elements are the elements of s, each +of which must be a single value. If s is infinite, this +function does not terminate.

procedure

(stream-length s)  exact-nonnegative-integer?

  s : stream?
Returns the number of elements of s. If s is +infinite, this function does not terminate.

In the case of lazy streams, this function forces evaluation only of +the sub-streams, and not the stream’s elements.

procedure

(stream-ref s i)  any

  s : stream?
  i : exact-nonnegative-integer?
Returns the ith element of s (which may be +multiple values).

procedure

(stream-tail s i)  stream?

  s : stream?
  i : exact-nonnegative-integer?
Returns a stream equivalent to s, except that the first +i elements are omitted.

In case extracting elements from s involves a side effect, +they will not be extracted until the first element is extracted from +the resulting stream.

procedure

(stream-take s i)  stream?

  s : stream?
  i : exact-nonnegative-integer?
Returns a stream of the first i elements of s.

procedure

(stream-append s ...)  stream?

  s : stream?
Returns a stream that contains all elements of each stream in the +order they appear in the original streams. The new stream is +constructed lazily, while the last given stream is used in the tail +of the result.

procedure

(stream-map f s)  stream?

  f : procedure?
  s : stream?
Returns a stream that contains f applied to each element of +s. The new stream is constructed lazily.

procedure

(stream-andmap f s)  boolean?

  f : (-> any/c ... boolean?)
  s : stream?
Returns #t if f returns a true result on every +element of s. If s is infinite and f +never returns a false result, this function does not terminate.

procedure

(stream-ormap f s)  boolean?

  f : (-> any/c ... boolean?)
  s : stream?
Returns #t if f returns a true result on some +element of s. If s is infinite and f +never returns a true result, this function does not terminate.

procedure

(stream-for-each f s)  void?

  f : (-> any/c ... any)
  s : stream?
Applies f to each element of s. If s is +infinite, this function does not terminate.

procedure

(stream-fold f i s)  any/c

  f : (-> any/c any/c ... any/c)
  i : any/c
  s : stream?
Folds f over each element of s with i as +the initial accumulator. If s is infinite, this function +does not terminate. The f function takes the accumulator as +its first argument and the next stream element as its second.

procedure

(stream-count f s)  exact-nonnegative-integer?

  f : procedure?
  s : stream?
Returns the number of elements in s for which f +returns a true result. If s is infinite, this function +does not terminate.

procedure

(stream-filter f s)  stream?

  f : (-> any/c ... boolean?)
  s : stream?
Returns a stream whose elements are the elements of s for +which f returns a true result. Although the new stream is +constructed lazily, if s has an infinite number of elements +where f returns a false result in between two elements +where f returns a true result, then operations on this +stream will not terminate during the infinite sub-stream.

procedure

(stream-add-between s e)  stream?

  s : stream?
  e : any/c
Returns a stream whose elements are the elements of s, but +with e between each pair of elements in s. The +new stream is constructed lazily.

syntax

(for/stream (for-clause ...) body-or-break ... body)

syntax

(for*/stream (for-clause ...) body-or-break ... body)

Iterates like for/list and for*/list, respectively, but the +results are lazily collected into a stream instead of a list.

Unlike most for forms, these forms are evaluated lazily, so each +body will not be evaluated until the resulting stream is forced. This +allows for/stream and for*/stream to iterate over infinite +sequences, unlike their finite counterparts.

Please note that these forms do not support returning multiple values.

Examples:
> (for/stream ([i '(1 2 3)]) (* i i))

#<stream>

> (stream->list (for/stream ([i '(1 2 3)]) (* i i)))

'(1 4 9)

> (stream-ref (for/stream ([i '(1 2 3)]) (displayln i) (* i i)) 1)

2

4

> (stream-ref (for/stream ([i (in-naturals)]) (* i i)) 25)

625

Added in version 6.3.0.9 of package base.

value

gen:stream : any/c

Associates three methods to a structure type to implement the +generic interface (see Generic Interfaces) for +streams.

To supply method implementations, the #:methods keyword +should be used in a structure type definition. The following three +methods should be implemented:

Examples:
> (struct list-stream (v)
    #:methods gen:stream
    [(define (stream-empty? stream)
       (empty? (list-stream-v stream)))
     (define (stream-first stream)
       (first (list-stream-v stream)))
     (define (stream-rest stream)
       (list-stream (rest (list-stream-v stream))))])
> (define l1 (list-stream '(1 2)))
> (stream? l1)

#t

> (stream-first l1)

1

A structure type property used to define custom +extensions to the stream API. Using the prop:stream property +is discouraged; use the gen:stream generic interface +instead. Accepts a vector of three procedures taking the same arguments +as the methods in gen:stream.

procedure

(stream/c c)  contract?

  c : contract?
Returns a contract that recognizes streams. All elements of the stream must match +c.

If the c argument is a flat contract or a chaperone contract, then the +result will be a chaperone contract. Otherwise, the result will be an +impersonator contract.

When an stream/c contract is applied to a stream, the result is not +eq? to the input. The result will be either a chaperone or +impersonator of the input depending on the type of contract.

Contracts on streams are evaluated lazily by necessity (since streams may be +infinite). Contract violations will not be raised until the value in violation +is retrieved from the stream. As an exception to this rule, streams that are +lists are checked immediately, as if c had been used with +listof.

If a contract is applied to a stream, and that stream is subsequently used as +the tail of another stream (as the second parameter to stream-cons), +the new elements will not be checked with the contract, but the tail’s elements +will still be enforced.

Added in version 6.1.1.8 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stringport.html b/clones/docs.racket-lang.org/reference/stringport.html new file mode 100644 index 00000000..91945ec9 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stringport.html @@ -0,0 +1,36 @@ + +13.1.6 String Ports
13.1.6 String Ports

A string port reads or writes from a byte string. An +input string port can be created from either a byte string +or a string; in the latter case, the string is effectively +converted to a byte string using string->bytes/utf-8. An +output string port collects output into a byte string, but +get-output-string conveniently converts the accumulated bytes +to a string.

Input and output string ports do not need to be explicitly +closed. The file-position procedure works for string +ports in position-setting mode.

+Byte Strings also provides information on bytestrings.

procedure

(string-port? p)  boolean?

  p : port?
Returns #t if p is a string port, #f +otherwise.

Added in version 6.0.1.6 of package base.

procedure

(open-input-bytes bstr [name])  (and/c input-port? string-port?)

  bstr : bytes?
  name : any/c = 'string
Creates an input string port that reads characters from +bstr (see Byte Strings). Modifying bstr +afterward does not affect the byte stream produced by the port. The +optional name argument is used as the name for the returned +port.

Examples:
> (define sp (open-input-bytes #"(apples 42 day)"))
> (define sexp1 (read sp))
> (first sexp1)

'apples

> (rest sexp1)

'(42 day)

> (read-line (open-input-bytes
              #"the cow jumped over the moon\nthe little dog\n"))

"the cow jumped over the moon"

+Strings also provides information on strings.

procedure

(open-input-string str [name])  (and/c input-port? string-port?)

  str : string?
  name : any/c = 'string
Creates an input string port that reads bytes from the UTF-8 +encoding (see Encodings and Locales) of str. The optional +name argument is used as the name for the returned port.

Examples:
> (define sp (open-input-string "(λ (x) x)"))
> (read sp)

'(λ (x) x)

> (define names (open-input-string "Günter Harder\nFrédéric Paulin\n"))
> (read-line names)

"Günter Harder"

> (read-line names)

"Frédéric Paulin"

procedure

(open-output-bytes [name])  (and/c output-port? string-port?)

  name : any/c = 'string
Creates an output string port that accumulates the output into a +byte string. The optional name argument is used as the name for +the returned port.

Examples:
> (define op1 (open-output-bytes))
> (write '((1 2 3) ("Tom" "Dick") ('a 'b 'c)) op1)
> (get-output-bytes op1)

#"((1 2 3) (\"Tom\" \"Dick\") ((quote a) (quote b) (quote c)))"

> (define op2 (open-output-bytes))
> (write "Hi " op2)
> (write "there" op2)
> (get-output-bytes op2)

#"\"Hi \"\"there\""

> (define op3 (open-output-bytes))
> (write-bytes #"Hi " op3)

3

> (write-bytes #"there" op3)

5

> (get-output-bytes op3)

#"Hi there"

procedure

(open-output-string [name])  (and/c output-port? string-port?)

  name : any/c = 'string
The same as open-output-bytes.

Examples:
> (define op1 (open-output-string))
> (write '((1 2 3) ("Tom" "Dick") ('a 'b 'c)) op1)
> (get-output-string op1)

"((1 2 3) (\"Tom\" \"Dick\") ((quote a) (quote b) (quote c)))"

> (define op2 (open-output-string))
> (write "Hi " op2)
> (write "there" op2)
> (get-output-string op2)

"\"Hi \"\"there\""

> (define op3 (open-output-string))
> (write-string "Hi " op3)

3

> (write-string "there" op3)

5

> (get-output-string op3)

"Hi there"

procedure

(get-output-bytes out    
  [reset?    
  start-pos    
  end-pos])  bytes?
  out : (and/c output-port? string-port?)
  reset? : any/c = #f
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = #f
Returns the bytes accumulated in the string port out so +far in a freshly allocated byte string (including any bytes +written after the port’s current position, if any). The out +port must be an output string port produced by +open-output-bytes (or open-output-string) or a +structure whose prop:output-port property refers to such an +output port (transitively).

If reset? is true, then all bytes are removed from the port, +and the port’s position is reset to 0; if reset? is +#f, then all bytes remain in the port for further +accumulation (so they are returned for later calls to +get-output-bytes or get-output-string), and the +port’s position is unchanged.

The start-pos and end-pos arguments specify the +range of bytes in the port to return; supplying start-pos and +end-pos is the same as using subbytes on the result +of get-output-bytes, but supplying them to +get-output-bytes can avoid an allocation. The +end-pos argument can be #f, which corresponds to not +passing a second argument to subbytes.

Examples:
> (define op (open-output-bytes))
> (write '((1 2 3) ("Tom" "Dick") ('a 'b 'c)) op)
> (get-output-bytes op)

#"((1 2 3) (\"Tom\" \"Dick\") ((quote a) (quote b) (quote c)))"

> (get-output-bytes op #f 3 16)

#" 2 3) (\"Tom\" "

> (get-output-bytes op #t)

#"((1 2 3) (\"Tom\" \"Dick\") ((quote a) (quote b) (quote c)))"

> (get-output-bytes op)

#""

procedure

(get-output-string out)  string?

  out : (and/c output-port? string-port?)
Returns (bytes->string/utf-8 (get-output-bytes out) #\uFFFD).

Examples:
> (define i (open-input-string "hello world"))
> (define o (open-output-string))
> (write (read i) o)
> (get-output-string o)

"hello"

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/strings.html b/clones/docs.racket-lang.org/reference/strings.html new file mode 100644 index 00000000..82dd41c0 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/strings.html @@ -0,0 +1,223 @@ + +4.4 Strings

4.4 Strings

+Strings (Unicode) in The Racket Guide introduces strings.

A string is a fixed-length array of +characters.

A string can be mutable or +immutable. When an immutable string is provided to a +procedure like string-set!, the +exn:fail:contract exception is raised. String constants generated by the +default reader (see Reading Strings) are +immutable, and they are interned in read-syntax mode. +Use immutable? to check whether a string is immutable.

Two strings are equal? when they have the same length and +contain the same sequence of characters.

A string can be used as a single-valued sequence (see +Sequences). The characters of the string serve as elements +of the sequence. See also in-string.

See Reading Strings + for information on reading + strings and Printing Strings + for information on printing strings.

See also: immutable?, symbol->string, +bytes->string/utf-8.

4.4.1 String Constructors, Selectors, and Mutators

procedure

(string? v)  boolean?

  v : any/c
Returns #t if v + is a string, #f otherwise.

Examples:
> (string? "Apple")

#t

> (string? 'apple)

#f

procedure

(make-string k [char])  string?

  k : exact-nonnegative-integer?
  char : char? = #\nul
Returns a new mutable string of length k where +each position in the string is initialized with the character +char.

Example:
> (make-string 5 #\z)

"zzzzz"

procedure

(string char ...)  string?

  char : char?
Returns a new +mutable string whose length is the number of provided chars, and +whose positions are initialized with the given chars.

Example:
> (string #\A #\p #\p #\l #\e)

"Apple"

procedure

(string->immutable-string str)  (and/c string? immutable?)

  str : string?
Returns an immutable string with the same content as + str, returning str itself if str is + immutable.

procedure

(string-length str)  exact-nonnegative-integer?

  str : string?
Returns the length of str.

Example:
> (string-length "Apple")

5

procedure

(string-ref str k)  char?

  str : string?
  k : exact-nonnegative-integer?
Returns the character at position k in str. + The first position in the string corresponds to 0, so the + position k must be less than the length of the string, + otherwise the exn:fail:contract exception is raised.

Example:
> (string-ref "Apple" 0)

#\A

procedure

(string-set! str k char)  void?

  str : (and/c string? (not/c immutable?))
  k : exact-nonnegative-integer?
  char : char?
Changes the + character position k in str to char. The first + position in the string corresponds to 0, so the position + k must be less than the length of the string, otherwise the + exn:fail:contract exception is raised.

Examples:
> (define s (string #\A #\p #\p #\l #\e))
> (string-set! s 4 #\y)
> s

"Apply"

procedure

(substring str start [end])  string?

  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (string-length str)
Returns a new mutable string that is (- end start) + characters long, and that contains the same characters as + str from start inclusive to end exclusive. + The first position in a string corresponds to 0, so + the start and end arguments must be less than or + equal to the length of str, and end must be greater + than or equal to start, otherwise the + exn:fail:contract exception is raised.

Examples:
> (substring "Apple" 1 3)

"pp"

> (substring "Apple" 1)

"pple"

procedure

(string-copy str)  string?

  str : string?
Returns + (substring str 0). +

Examples:
> (define s1 "Yui")
> (define pilot (string-copy s1))
> (list s1 pilot)

'("Yui" "Yui")

> (for ([i (in-naturals)] [ch '(#\R #\e #\i)])
    (string-set! pilot i ch))
> (list s1 pilot)

'("Yui" "Rei")

procedure

(string-copy! dest    
  dest-start    
  src    
  [src-start    
  src-end])  void?
  dest : (and/c string? (not/c immutable?))
  dest-start : exact-nonnegative-integer?
  src : string?
  src-start : exact-nonnegative-integer? = 0
  src-end : exact-nonnegative-integer? = (string-length src)
Changes the characters of dest starting at position + dest-start to match the characters in src from + src-start (inclusive) to src-end (exclusive), + where the first position in a string corresponds to 0. The + strings dest and src can be the same string, and in + that case the destination region can overlap with the source region; + the destination characters after the copy match the source characters + from before the copy. If any of dest-start, + src-start, or src-end are out of range (taking into + account the sizes of the strings and the source and destination + regions), the exn:fail:contract exception is raised.

Examples:
> (define s (string #\A #\p #\p #\l #\e))
> (string-copy! s 4 "y")
> (string-copy! s 0 s 3 4)
> s

"lpply"

procedure

(string-fill! dest char)  void?

  dest : (and/c string? (not/c immutable?))
  char : char?
Changes dest so that every position in the + string is filled with char.

Examples:
> (define s (string #\A #\p #\p #\l #\e))
> (string-fill! s #\q)
> s

"qqqqq"

procedure

(string-append str ...)  string?

  str : string?
Returns a new mutable string that is +as long as the sum of the given strs’ lengths, and that +contains the concatenated characters of the given strs. If no +strs are provided, the result is a zero-length string.

Example:
> (string-append "Apple" "Banana")

"AppleBanana"

procedure

(string-append-immutable str ...)  (and/c string? immutable?)

  str : string?
The same as string-append, but the result is an immutable +string.

Examples:
> (string-append-immutable "Apple" "Banana")

"AppleBanana"

> (immutable? (string-append-immutable "A" "B"))

#t

Added in version 7.5.0.14 of package base.

procedure

(string->list str)  (listof char?)

  str : string?
Returns a new + list of characters corresponding to the content of str. That is, + the length of the list is (string-length str), and the + sequence of characters in str is the same sequence in the + result list.

Example:
> (string->list "Apple")

'(#\A #\p #\p #\l #\e)

procedure

(list->string lst)  string?

  lst : (listof char?)
Returns a new + mutable string whose content is the list of characters in lst. + That is, the length of the string is (length lst), and + the sequence of characters in lst is the same sequence in + the result string.

Example:
> (list->string (list #\A #\p #\p #\l #\e))

"Apple"

procedure

(build-string n proc)  string?

  n : exact-nonnegative-integer?
  proc : (exact-nonnegative-integer? . -> . char?)
Creates a string of n characters by applying proc to +the integers from 0 to (sub1 n) in order. If +str is the resulting string, then (string-ref str i) is the character produced by (proc i).

Example:
> (build-string 5 (lambda (i) (integer->char (+ i 97))))

"abcde"

4.4.2 String Comparisons

procedure

(string=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Returns + #t if all of the arguments are equal?.

Examples:
> (string=? "Apple" "apple")

#f

> (string=? "a" "as" "a")

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string<? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Returns #t if the arguments are lexicographically sorted + increasing, where individual characters are ordered by + char<?, #f otherwise.

Examples:
> (string<? "Apple" "apple")

#t

> (string<? "apple" "Apple")

#f

> (string<? "a" "b" "c")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string<=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments are nondecreasing.

Examples:
> (string<=? "Apple" "apple")

#t

> (string<=? "apple" "Apple")

#f

> (string<=? "a" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments are decreasing.

Examples:
> (string>? "Apple" "apple")

#f

> (string>? "apple" "Apple")

#t

> (string>? "c" "b" "a")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string>=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments are nonincreasing.

Examples:
> (string>=? "Apple" "apple")

#f

> (string>=? "apple" "Apple")

#t

> (string>=? "c" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Returns #t if all of the arguments are equal? after + locale-insensitive case-folding via string-foldcase.

Examples:
> (string-ci=? "Apple" "apple")

#t

> (string-ci=? "a" "a" "a")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci<? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments would be in + increasing order if each was first case-folded using + string-foldcase (which is locale-insensitive).

Examples:
> (string-ci<? "Apple" "apple")

#f

> (string-ci<? "apple" "banana")

#t

> (string-ci<? "a" "b" "c")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci<=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-ci<?, but checks whether the arguments would be nondecreasing after case-folding.

Examples:
> (string-ci<=? "Apple" "apple")

#t

> (string-ci<=? "apple" "Apple")

#t

> (string-ci<=? "a" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-ci<?, but checks whether the arguments would be decreasing after case-folding.

Examples:
> (string-ci>? "Apple" "apple")

#f

> (string-ci>? "banana" "Apple")

#t

> (string-ci>? "c" "b" "a")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci>=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-ci<?, but checks whether the arguments would be nonincreasing after case-folding.

Examples:
> (string-ci>=? "Apple" "apple")

#t

> (string-ci>=? "apple" "Apple")

#t

> (string-ci>=? "c" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.4.3 String Conversions

procedure

(string-upcase str)  string?

  str : string?
Returns a string + whose characters are the upcase conversion of the characters in + str. The conversion uses Unicode’s locale-independent + conversion rules that map code-point sequences to code-point + sequences (instead of simply mapping a 1-to-1 function on code points + over the string), so the string produced by the conversion can be + longer than the input string.

Examples:
> (string-upcase "abc!")

"ABC!"

> (string-upcase "Straße")

"STRASSE"

procedure

(string-downcase string)  string?

  string : string?
Like + string-upcase, but the downcase conversion.

Examples:
> (string-downcase "aBC!")

"abc!"

> (string-downcase "Straße")

"straße"

> (string-downcase "ΚΑΟΣ")

"καος"

> (string-downcase "Σ")

"σ"

procedure

(string-titlecase string)  string?

  string : string?
Like + string-upcase, but the titlecase conversion only for the + first character in each sequence of cased characters in str + (ignoring case-ignorable characters).

Examples:
> (string-titlecase "aBC  twO")

"Abc  Two"

> (string-titlecase "y2k")

"Y2k"

> (string-titlecase "main straße")

"Main Straße"

> (string-titlecase "stra ße")

"Stra Sse"

procedure

(string-foldcase string)  string?

  string : string?
Like + string-upcase, but the case-folding conversion.

Examples:
> (string-foldcase "aBC!")

"abc!"

> (string-foldcase "Straße")

"strasse"

> (string-foldcase "ΚΑΟΣ")

"καοσ"

procedure

(string-normalize-nfd string)  string?

  string : string?
Returns a +string that is the Unicode normalized form D of string. If +the given string is already in the corresponding Unicode normal form, +the string may be returned directly as the result (instead of a newly +allocated string).

procedure

(string-normalize-nfkd string)  string?

  string : string?
Like +string-normalize-nfd, but for normalized form KD.

procedure

(string-normalize-nfc string)  string?

  string : string?
Like +string-normalize-nfd, but for normalized form C.

procedure

(string-normalize-nfkc string)  string?

  string : string?
Like +string-normalize-nfd, but for normalized form KC.

4.4.4 Locale-Specific String Operations

procedure

(string-locale=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string=?, but the strings are compared in a + locale-specific way, based on the value of current-locale. See + Encodings and Locales for more information on locales.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale<? str1 str2 ...+)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but the sort order compares strings in a + locale-specific way, based on the value of current-locale. In + particular, the sort order may not be simply a lexicographic + extension of character ordering.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string>?, but locale-specific like + string-locale<?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-ci=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-locale=?, but strings are compared + using rules that are both locale-specific and case-insensitive + (depending on what “case-insensitive” means for the current + locale).

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-ci<? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but both locale-sensitive and + case-insensitive like string-locale-ci=?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-ci>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string>?, but both locale-sensitive and + case-insensitive like string-locale-ci=?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-upcase string)  string?

  string : string?
Like +string-upcase, but using locale-specific case-conversion +rules based on the value of current-locale.

procedure

(string-locale-downcase string)  string?

  string : string?
Like +string-downcase, but using locale-specific case-conversion +rules based on the value of current-locale.

4.4.5 Additional String Functions

 (require racket/string) package: base
The bindings documented in this section are provided by the racket/string and racket libraries, but not racket/base.

procedure

(string-append* str ... strs)  string?

  str : string?
  strs : (listof string?)
Like string-append, but the last argument is used as a list +of arguments for string-append, so (string-append* str ... strs) is the same as (apply string-append str ... strs). In other words, the relationship between +string-append and string-append* is similar to the +one between list and list*.

Examples:
> (string-append* "a" "b" '("c" "d"))

"abcd"

> (string-append* (cdr (append* (map (lambda (x) (list ", " x))
                                     '("Alpha" "Beta" "Gamma")))))

"Alpha, Beta, Gamma"

procedure

(string-join strs    
  [sep    
  #:before-first before-first    
  #:before-last before-last    
  #:after-last after-last])  string?
  strs : (listof string?)
  sep : string? = " "
  before-first : string? = ""
  before-last : string? = sep
  after-last : string? = ""
Appends the strings in strs, inserting sep between +each pair of strings in strs. before-last, +before-first, and after-last are analogous to the +inputs of add-between: they specify an alternate separator +between the last two strings, a prefix string, and a suffix string +respectively.

Examples:
> (string-join '("one" "two" "three" "four"))

"one two three four"

> (string-join '("one" "two" "three" "four") ", ")

"one, two, three, four"

> (string-join '("one" "two" "three" "four") " potato ")

"one potato two potato three potato four"

> (string-join '("x" "y" "z") ", "
               #:before-first "Todo: "
               #:before-last " and "
               #:after-last ".")

"Todo: x, y and z."

procedure

(string-normalize-spaces str    
  [sep    
  space    
  #:trim? trim?    
  #:repeat? repeat?])  string?
  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  space : string? = " "
  trim? : any/c = #t
  repeat? : any/c = #f
Normalizes spaces in the input str by trimming it (using +string-trim and sep) and replacing all whitespace +sequences in the result with space, which defaults to a +single space.

Example:
> (string-normalize-spaces "  foo bar  baz \r\n\t")

"foo bar baz"

The result of (string-normalize-spaces str sep space) is the same +as (string-join (string-split str sep ....) space).

procedure

(string-replace str from to [#:all? all?])  string?

  str : string?
  from : (or/c string? regexp?)
  to : string?
  all? : any/c = #t
Returns str with all occurrences of from replaced +with by to. If from is a string, it is matched +literally (as opposed to being used as a regular expression).

By default, all occurrences are replaced, but only the first match is +replaced if all? is #f.

Example:
> (string-replace "foo bar baz" "bar" "blah")

"foo blah baz"

procedure

(string-split str    
  [sep    
  #:trim? trim?    
  #:repeat? repeat?])  (listof string?)
  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  trim? : any/c = #t
  repeat? : any/c = #f
Splits the input str on sep, returning a list of +substrings of str that are separated by sep, defaulting +to splitting the input on whitespaces. The +input is first trimmed using sep (see string-trim), +unless trim? is #f. Empty matches are handled in the +same way as for regexp-split. As a special case, if +str is the empty string after trimming, the result is +'() instead of '("").

Like string-trim, provide sep to use a different separator, +and repeat? controls matching repeated sequences.

Examples:
> (string-split "  foo bar  baz \r\n\t")

'("foo" "bar" "baz")

> (string-split "  ")

'()

> (string-split "  " #:trim? #f)

'("" "")

procedure

(string-trim str    
  [sep    
  #:left? left?    
  #:right? right?    
  #:repeat? repeat?])  string?
  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  left? : any/c = #t
  right? : any/c = #t
  repeat? : any/c = #f
Trims the input str by removing prefix and suffix sep, +which defaults to whitespace. A string sep is matched literally +(as opposed to being used as a regular expression).

Use #:left? #f or #:right? #f to suppress trimming +the corresponding side. When repeat? is #f (the +default), only one match is removed from each side; when +repeat? is true, all initial or trailing matches are +trimmed (which is an alternative to using a regular expression +sep that contains +).

Examples:
> (string-trim "  foo bar  baz \r\n\t")

"foo bar  baz"

> (string-trim "  foo bar  baz \r\n\t" " " #:repeat? #t)

"foo bar  baz \r\n\t"

> (string-trim "aaaxaayaa" "aa")

"axaay"

procedure

(non-empty-string? x)  boolean?

  x : any/c
Returns #t if x is a string and is not empty; +returns #f otherwise. +

Added in version 6.3 of package base.

procedure

(string-contains? s contained)  boolean?

  s : string?
  contained : string?

procedure

(string-prefix? s prefix)  boolean?

  s : string?
  prefix : string?

procedure

(string-suffix? s suffix)  boolean?

  s : string?
  suffix : string?
Checks whether s includes at any location, start with, or ends with +the second argument, respectively.

Examples:
> (string-prefix? "Racket" "R")

#t

> (string-prefix? "Jacket" "R")

#f

> (string-suffix? "Racket" "et")

#t

> (string-contains? "Racket" "ack")

#t

Added in version 6.3 of package base.

4.4.6 Converting Values to Strings

 (require racket/format) package: base
The bindings documented in this section are provided by the racket/format and racket libraries, but not racket/base.

The racket/format library provides functions for +converting Racket values to strings. In addition to features like +padding and numeric formatting, the functions have the virtue of being +shorter than format (with format string), +number->string, or string-append.

procedure

(~a v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = ""
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = ""
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Converts each v to a string in display mode—that +is, like (format "~a" v)then concatentates the results +with separator between consecutive items, and then pads or +truncates the string to be at least min-width characters and +at most max-width characters.

Examples:
> (~a "north")

"north"

> (~a 'south)

"south"

> (~a #"east")

"east"

> (~a #\w "e" 'st)

"west"

> (~a (list "red" 'green #"blue"))

"(red green blue)"

> (~a 17)

"17"

> (~a #e1e20)

"100000000000000000000"

> (~a pi)

"3.141592653589793"

> (~a (expt 6.1 87))

"2.1071509386211452e+68"

The ~a function is primarily useful for strings, numbers, and other +atomic data. The ~v and ~s functions are better suited to +compound data.

Let s be the concatenated string forms of the vs +plus separators. If s is longer than max-width +characters, it is truncated to exactly max-width +characters. If s is shorter than min-width +characters, it is padded to exactly min-width +characters. Otherwise s is returned unchanged. If +min-width is greater than max-width, an exception is +raised.

If s is longer than max-width characters, it is +truncated and the end of the string is replaced with +limit-marker. If limit-marker is longer than +max-width, an exception is raised. +If limit-prefix? is #t, the beginning of the string +is truncated instead of the end.

Examples:
> (~a "abcde" #:max-width 5)

"abcde"

> (~a "abcde" #:max-width 4)

"abcd"

> (~a "abcde" #:max-width 4 #:limit-marker "*")

"abc*"

> (~a "abcde" #:max-width 4 #:limit-marker "...")

"a..."

> (~a "The quick brown fox" #:max-width 15 #:limit-marker "")

"The quick brown"

> (~a "The quick brown fox" #:max-width 15 #:limit-marker "...")

"The quick br..."

> (~a "The quick brown fox" #:max-width 15 #:limit-marker "..." #:limit-prefix? #f)

"The quick br..."

If s is shorter than min-width, it is padded to at +least min-width characters. If align is +'left, then only right padding is added; if align +is 'right, then only left padding is added; and if +align is 'center, then roughly equal amounts of +left padding and right padding are added.

Padding is specified as a non-empty string. Left padding consists of +left-pad-string repeated in its entirety as many times as +possible followed by a prefix of left-pad-string to fill +the remaining space. In contrast, right padding consists of a +suffix of right-pad-string followed by a number of copies +of right-pad-string in its entirety. Thus left padding starts +with the start of left-pad-string and right padding ends with +the end of right-pad-string.

Examples:
> (~a "apple" #:min-width 20 #:align 'left)

"apple               "

> (~a "pear" #:min-width 20 #:align 'left #:right-pad-string " .")

"pear . . . . . . . ."

> (~a "plum" #:min-width 20 #:align 'right #:left-pad-string ". ")

". . . . . . . . plum"

> (~a "orange" #:min-width 20 #:align 'center
                #:left-pad-string "- " #:right-pad-string " -")

"- - - -orange- - - -"

Use width to set both max-width and min-width +simultaneously, ensuring that the resulting string is exactly +width characters long:

> (~a "terse" #:width 6)

"terse "

> (~a "loquacious" #:width 6)

"loquac"

procedure

(~v v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, but each value is converted like (format "~v" v), the default separator is " ", and the default limit +marker is "...".

Examples:
> (~v "north")

"\"north\""

> (~v 'south)

"'south"

> (~v #"east")

"#\"east\""

> (~v #\w)

"#\\w"

> (~v (list "red" 'green #"blue"))

"'(\"red\" green #\"blue\")"

Use ~v to produce text that talks about Racket values.

Example:
> (let ([nums (for/list ([i 10]) i)])
    (~a "The even numbers in " (~v nums)
        " are " (~v (filter even? nums)) "."))

"The even numbers in '(0 1 2 3 4 5 6 7 8 9) are '(0 2 4 6 8)."

procedure

(~s v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, but each value is converted like (format "~s" v), the default separator is " ", and the default limit +marker is "...".

Examples:
> (~s "north")

"\"north\""

> (~s 'south)

"south"

> (~s #"east")

"#\"east\""

> (~s #\w)

"#\\w"

> (~s (list "red" 'green #"blue"))

"(\"red\" green #\"blue\")"

procedure

(~e v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, but each value is converted like (format "~e" v), the default separator is " ", and the default limit +marker is "...".

Examples:
> (~e "north")

"\"north\""

> (~e 'south)

"'south"

> (~e #"east")

"#\"east\""

> (~e #\w)

"#\\w"

> (~e (list "red" 'green #"blue"))

"'(\"red\" green #\"blue\")"

procedure

(~r x    
  [#:sign sign    
  #:base base    
  #:precision precision    
  #:notation notation    
  #:format-exponent format-exponent    
  #:min-width min-width    
  #:pad-string pad-string    
  #:groups groups    
  #:group-sep group-sep    
  #:decimal-sep decimal-sep])  string?
  x : rational?
  sign : 
(or/c #f '+ '++ 'parens
      (let ([ind (or/c string? (list/c string? string?))])
        (list/c ind ind ind)))
   = #f
  base : (or/c (integer-in 2 36) (list/c 'up (integer-in 2 36)))
   = 10
  precision : 
(or/c exact-nonnegative-integer?
      (list/c '= exact-nonnegative-integer?))
 = 6
  notation : 
(or/c 'positional 'exponential
      (-> rational? (or/c 'positional 'exponential)))
   = 'positional
  format-exponent : (or/c #f string? (-> exact-integer? string?))
   = #f
  min-width : exact-positive-integer? = 1
  pad-string : non-empty-string? = " "
  groups : (non-empty-listof exact-positive-integer?) = '(3)
  group-sep : string? = ""
  decimal-sep : string? = "."
Converts the rational number x to a string in either +positional or exponential notation, depending on +notation. The exactness or inexactness of x does not +affect its formatting.

The optional arguments control number formatting:

  • notation determines whether the number is printed +in positional or exponential notation. If notation is a +function, it is applied to x to get the notation to be used.

    Examples:
    > (~r 12345)

    "12345"

    > (~r 12345 #:notation 'exponential)

    "1.2345e+04"

    > (let ([pick-notation
             (lambda (x)
               (if (or (< (abs x) 0.001) (> (abs x) 1000))
                   'exponential
                   'positional))])
        (for/list ([i (in-range 1 5)])
          (~r (expt 17 i) #:notation pick-notation)))

    '("17" "289" "4.913e+03" "8.3521e+04")

  • precision controls the number of digits after the +decimal point (or more accurately, the +radix point). +When x is formatted in exponential form, precision +applies to the significand.

    If precision is a natural number, then up to precision digits are +displayed, but trailing zeroes are dropped, and if all digits after the decimal +point are dropped the decimal point is also dropped. If precision is +(list '= digits), then exactly digits digits after the +decimal point are used, and the decimal point is never dropped.

    Examples:
    > (~r pi)

    "3.141593"

    > (~r pi #:precision 4)

    "3.1416"

    > (~r pi #:precision 0)

    "3"

    > (~r 1.5 #:precision 4)

    "1.5"

    > (~r 1.5 #:precision '(= 4))

    "1.5000"

    > (~r 50 #:precision 2)

    "50"

    > (~r 50 #:precision '(= 2))

    "50.00"

    > (~r 50 #:precision '(= 0))

    "50."

  • decimal-sep specifies what decimal separator is printed.

    Examples:
    > (~r 123.456)

    "123.456"

    > (~r 123.456 #:decimal-sep ",")

    "123,456"

  • groups controls how digits of the integral part of the number +are separated into groups. +Rightmost numbers of groups are used to group rightmost digits of the integral part. +The leftmost number of groups is used repeatedly to group leftmost digits. +The group-sep argument specifies which separator to use between digit groups.

    Examples:
    > (~r 1234567890 #:groups '(3) #:group-sep ",")

    "1,234,567,890"

    > (~r 1234567890 #:groups '(3 2) #:group-sep ",")

    "12,345,678,90"

    > (~r 1234567890 #:groups '(1 3 2) #:group-sep "_")

    "1_2_3_4_5_678_90"

  • min-width if x would normally be printed +with fewer than min-width digits (including the decimal +point but not including the sign indicator), the digits are left-padded +using pad-string.

    Examples:
    > (~r 17)

    "17"

    > (~r 17 #:min-width 4)

    "  17"

    > (~r -42 #:min-width 4)

    "-  42"

    > (~r 1.5 #:min-width 4)

    " 1.5"

    > (~r 1.5 #:precision 4 #:min-width 10)

    "       1.5"

    > (~r 1.5 #:precision '(= 4) #:min-width 10)

    "    1.5000"

    > (~r #e1e10 #:min-width 6)

    "10000000000"

  • pad-string specifies the string used to pad the +number to at least min-width characters (not including the +sign indicator). The padding is placed between the sign and the normal +digits of x.

    Examples:
    > (~r 17 #:min-width 4 #:pad-string "0")

    "0017"

    > (~r -42 #:min-width 4 #:pad-string "0")

    "-0042"

  • sign controls how the sign of the number is +indicated: +
    • If sign is #f (the default), no sign output is +generated if x is either positive or zero, and a minus sign is +prefixed if x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x))

      '("17" "0" "-42")

    • If sign is '+, no sign output is generated if +x is zero, a plus sign is prefixed if x is positive, and a +minus sign is prefixed if x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x #:sign '+))

      '("+17" "0" "-42")

    • If sign is '++, a plus sign is prefixed if x +is zero or positive, and a minus sign is prefixed if x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x #:sign '++))

      '("+17" "+0" "-42")

    • If sign is 'parens, no sign output is generated if +x is zero or positive, and the number is enclosed in parentheses if +x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x #:sign 'parens))

      '("17" "0" "(42)")

    • If sign is (list pos-ind zero-ind neg-ind), then +pos-ind, zero-ind, and neg-ind are used to +indicate positive, zero, and negative numbers, respectively. Each indicator is +either a string to be used as a prefix or a list containing two strings: a +prefix and a suffix.

      Example:
      > (let ([sign-table '(("" " up") "an even " ("" " down"))])
          (for/list ([x '(17 0 -42)]) (~r x #:sign sign-table)))

      '("17 up" "an even 0" "42 down")

      The default behavior is equivalent to '("" "" "-"); the +'parens mode is equivalent to '("" "" ("(" ")")).

  • base controls the base that x is formatted in. If +base is a number greater than 10, then lower-case letters are +used. If base is (list 'up base*) and base* is +greater than 10, then upper-case letters are used.

    Examples:
    > (~r 100 #:base 7)

    "202"

    > (~r 4.5 #:base 2)

    "100.1"

    > (~r 3735928559 #:base 16)

    "deadbeef"

    > (~r 3735928559 #:base '(up 16))

    "DEADBEEF"

    > (~r 3735928559 #:base '(up 16) #:notation 'exponential)

    "D.EADBEF*16^+07"

  • format-exponent determines how the exponent is displayed.

    If format-exponent is a string, the exponent is displayed with an +explicit sign (as with a sign of '++) and at least two +digits, separated from the significand by the “exponent marker” +format-exponent:

    > (~r 1234 #:notation 'exponential #:format-exponent "E")

    "1.234E+03"

    If format-exponent is #f, the “exponent marker” is +"e" if base is 10 and a string involving +base otherwise:

    > (~r 1234 #:notation 'exponential)

    "1.234e+03"

    > (~r 1234 #:notation 'exponential #:base 8)

    "2.322*8^+03"

    If format-exponent is a procedure, it is applied to the exponent and +the resulting string is appended to the significand:

    > (~r 1234 #:notation 'exponential
               #:format-exponent (lambda (e) (format "E~a" e)))

    "1.234E3"

Changed in version 8.5.0.5 of package base: Added #:groups, #:group-sep and #:decimal-sep.

procedure

(~.a v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = ""
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = ""
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

procedure

(~.v v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

procedure

(~.s v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, ~v, and ~s, but each v is +formatted like (format "~.a" v), (format "~.v" v), +and (format "~.s" v), respectively.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/struct-copy.html b/clones/docs.racket-lang.org/reference/struct-copy.html new file mode 100644 index 00000000..2eb21b38 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/struct-copy.html @@ -0,0 +1,24 @@ + +5.5 Copying and Updating Structures

5.5 Copying and Updating Structures

syntax

(struct-copy id struct-expr fld-id ...)

 
fld-id = [field-id expr]
  | [field-id #:parent parent-id expr]
Creates a new instance of the structure type id (which is defined via a +structure type defining form such as struct) +with the same field values as the structure produced by struct-expr, except +that the value of each supplied field-id is instead +determined by the corresponding expr. If #:parent +is specified, the parent-id must be bound to a parent +structure type of id.

The id must have a transformer binding that +encapsulates information about a structure type (i.e., like the +initial identifier bound by struct), and the binding +must supply a constructor, a predicate, and all field accessors.

Each field-id must correspond to a field-id in +the structure type defining forms of id +(or parent-id, if present). The accessor bindings determined by different +field-ids under the same id (or parent-id, if present) +must be distinct. The order of the +field-ids need not match the order of the corresponding +fields in the structure type.

The struct-expr is evaluated first. The result must be an +instance of the id structure type, otherwise the +exn:fail:contract exception is raised. Next, the field exprs are +evaluated in order (even if the fields that correspond to the +field-ids are in a different order). Finally, the new +structure instance is created.

The result of struct-expr can be an instance of a sub-type of +id, but the resulting copy is an immediate instance of +id (not the sub-type).

Examples:
> (struct fish (color weight) #:transparent)
> (define marlin (fish 'orange-and-white 11))
> (define dory (struct-copy fish marlin
                            [color 'blue]))
> dory

(fish 'blue 11)

> (struct shark fish (weeks-since-eating-fish) #:transparent)
> (define bruce (shark 'grey 110 3))
> (define chum (struct-copy shark bruce
                            [weight #:parent fish 90]
                            [weeks-since-eating-fish 0]))
> chum

(shark 'grey 90 0)

; subtypes can be copied as if they were supertypes,
; but the result is an instance of the supertype
> (define not-really-chum
    (struct-copy fish bruce
                 [weight 90]))
> not-really-chum

(fish 'grey 90)

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/struct-generics.html b/clones/docs.racket-lang.org/reference/struct-generics.html new file mode 100644 index 00000000..6eebc868 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/struct-generics.html @@ -0,0 +1,103 @@ + +5.4 Generic Interfaces
8.6

5.4 Generic Interfaces

 (require racket/generic) package: base

A generic interface allows per-type methods to be +associated with generic functions. Generic functions are defined +using a define-generics form. Method implementations for +a structure type are defined using the #:methods keyword +(see Defining Structure Types: struct).

syntax

(define-generics id
  generics-opt ...
  [method-id . kw-formals*] ...
  generics-opt ...)
 
generics-opt = #:defaults ([default-pred? default-impl ...] ...)
  | #:fast-defaults ([fast-pred? fast-impl ...] ...)
  | #:fallbacks [fallback-impl ...]
  | #:defined-predicate defined-pred-id
  | #:defined-table defined-table-id
  | #:derive-property prop-expr prop-value-expr
     
kw-formals* = (arg* ...)
  | (arg* ...+ . rest-id)
  | rest-id
     
arg* = arg-id
  | [arg-id]
  | keyword arg-id
  | keyword [arg-id]
Defines the following names, plus any specified by keyword options.

  • gen:id as a transformer binding for +the static information about a new generic interface;

  • id? as a predicate identifying +instances of structure types that implement this generic group; and

  • each method-id as a generic method that calls the +corresponding method on values where +id? is true. +Each method-id’s kw-formals* must include a required +by-position argument that is free-identifier=? to +id. That argument is used in the generic definition to +locate the specialization.

  • id/c as a contract combinator that +recognizes instances of structure types which implement the +gen:id generic interface. The combinator +takes pairs of method-ids and contracts. The contracts +will be applied to each of the corresponding method implementations. +The id/c combinator is intended to be used to +contract the range of a constructor procedure for a struct type that +implements the generic interface.

The #:defaults option may be provided at most once. +When it is provided, each generic function +uses default-pred?s to dispatch to the given +default method implementations, +default-impls, if dispatching to the generic method table fails. +The syntax of the default-impls is the same as the methods +provided for the #:methods keyword for struct.

The #:fast-defaults option may be provided at most once. +It works the same as #:defaults, except the fast-pred?s are +checked before dispatching to the generic method table. This option is +intended to provide a fast path for dispatching to built-in datatypes, such as +lists and vectors, that do not overlap with structures implementing +gen:id.

The #:fallbacks option may be provided at most once. +When it is provided, the fallback-impls define +fallback method implementations +that are used for any instance of the generic interface that does not supply a +specific implementation. The syntax of the fallback-impls is the same +as the methods provided for the #:methods keyword for struct.

The #:defined-predicate option may be provided at most once. +When it is provided, defined-pred-id is defined as a +procedure that reports whether a specific instance of the generic interface +implements a given set of methods. +Specifically, (defined-pred-id v 'name ...) produces #t if +v has implementations for each method name, not counting +#:fallbacks implementations, and produces #f otherwise. +This procedure is intended for use by +higher-level APIs to adapt their behavior depending on method +availability.

The #:defined-table option may be provided at most once. +When it is provided, defined-table-id is defined as a +procedure that takes an instance of the generic interface and returns an +immutable hash table that maps symbols corresponding to method +names to booleans representing whether or not that method is +implemented by the instance. This option is deprecated; use +#:defined-predicate instead.

The #:derive-property option may be provided any number of times. +Each time it is provided, it specifies a structure type property via +prop-expr and a value for the property via prop-value-expr. +All structures implementing the generic interface via #:methods +automatically implement this structure type property using the provided values. +When prop-value-expr is executed, each method-id is bound to +its specific implementation for the structure type.

If a value v satisfies id?, then v is +a generic instance of gen:id.

If a generic instance v has a corresponding implementation for some +method-id provided via #:methods in struct or via +#:defaults or #:fast-defaults in define-generics, +then method-id is an implemented generic method of +v.

If method-id is not an implemented generic method of a generic +instance v, and method-id has a fallback implementation that +does not raise an exn:fail:support exception when given v, +then method-id is a supported generic method of v.

procedure

(raise-support-error name v)  none/c

  name : symbol?
  v : any/c
Raises an exn:fail:support exception for a generic +method called name that does not support the generic +instance v.

Example:
> (raise-support-error 'some-method-name '("arbitrary" "instance" "value"))

some-method-name: not implemented for '("arbitrary"

"instance" "value")

struct

(struct exn:fail:support exn:fail ()
    #:transparent)
Raised for generic methods that do not support the given +generic instance.

syntax

(define/generic local-id method-id)

When used inside the method definitions associated with the #:methods, +#:fallbacks, #:defaults or #:fast-defaults keywords, +binds local-id to the generic for method-id. This form is +useful for method specializations to use generic methods (as opposed to the +local specialization) on other values.

The define/generic form is only allowed inside: +

Using define/generic elsewhere is a syntax error.

Examples:
> (define-generics printable
    (gen-print printable [port])
    (gen-port-print port printable)
    (gen-print* printable [port] #:width width #:height [height])
    #:defaults ([string?
                 (define/generic super-print gen-print)
                 (define (gen-print s [port (current-output-port)])
                   (fprintf port "String: ~a" s))
                 (define (gen-port-print port s)
                   ; we can call gen-print alternatively
                   (super-print s port))
                 (define (gen-print* s [port (current-output-port)]
                                     #:width w #:height [h 0])
                   (fprintf port "String (~ax~a): ~a" w h s))]))
> (struct num (v)
    #:methods gen:printable
    [(define (gen-print n [port (current-output-port)])
       (fprintf port "Num: ~a" (num-v n)))
     (define (gen-port-print port n)
       (gen-print n port))
     (define (gen-print* n [port (current-output-port)]
                         #:width w #:height [h 0])
       (fprintf port "Num (~ax~a): ~a" w h (num-v n)))])
> (struct string+num (v n)
    #:methods gen:printable
    [(define/generic super-print gen-print)
     (define/generic super-print* gen-print*)
     (define (gen-print b [port (current-output-port)])
       (super-print (string+num-v b) port)
       (fprintf port " ")
       (super-print (string+num-n b) port))
     (define (gen-port-print port b)
       (gen-print b port))
     (define (gen-print* b [port (current-output-port)]
                         #:width w #:height [h 0])
       (super-print* (string+num-v b) #:width w #:height h)
       (fprintf port " ")
       (super-print* (string+num-n b) #:width w #:height h))])
> (define x (num 10))
> (gen-print x)

Num: 10

> (gen-port-print (current-output-port) x)

Num: 10

> (gen-print* x #:width 100 #:height 90)

Num (100x90): 10

> (define str "Strings are printable too!")
> (gen-print str)

String: Strings are printable too!

> (define y (string+num str x))
> (gen-print y)

String: Strings are printable too! Num: 10

> (gen-port-print (current-output-port) y)

String: Strings are printable too! Num: 10

> (gen-print* y #:width 100 #:height 90)

String (100x90): Strings are printable too! Num (100x90): 10

> (define/contract make-num-contracted
    (-> number?
        (printable/c
          [gen-print (->* (printable?) (output-port?) void?)]
          [gen-port-print (-> output-port? printable? void?)]
          [gen-print* (->* (printable? #:width exact-nonnegative-integer?)
                           (output-port? #:height exact-nonnegative-integer?)
                           void?)]))
     num)
> (define z (make-num-contracted 10))
> (gen-print* z #:width "not a number" #:height 5)

make-num-contracted: contract violation

  expected: natural?

  given: "not a number"

  in: the #:width argument of

      method gen-print*

      the range of

      (->

       number?

       (printable/c

        (gen-print

         (->* (printable?) (output-port?) void?))

        (gen-port-print

         (-> output-port? printable? void?))

        (gen-print*

         (->*

          (printable? #:width natural?)

          (output-port? #:height natural?)

          void?))))

  contract from:

      (definition make-num-contracted)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:16:0

syntax

(generic-instance/c gen-id [method-id method-ctc] ...)

 
  method-ctc : contract?
Creates a contract that recognizes structures that implement the generic +interface gen-id, and constrains their implementations of the +specified method-ids with the corresponding method-ctcs.

syntax

(impersonate-generics gen-id val-expr
  [method-id method-proc-expr] ...
  maybe-properties)
 
maybe-properties = 
  | #:properties props-expr
 
  method-proc-expr : (any/c . -> . any/c)
  props-expr : (list/c impersonator-property? any/c ... ...)
Creates an impersonator of val-expr, which must be a structure +that implements the generic interface gen-id. The impersonator +applies the results of the method-proc-exprs to the structure’s implementation +of the corresponding method-ids, and replaces the method +implementation with the result.

A props-expr can provide properties to attach to the +impersonator. The result of props-expr must be a list with +an even number of elements, where the first element of the list is an +impersonator property, the second element is its value, and so on.

Changed in version 6.1.1.8 of package base: Added #:properties.

syntax

(chaperone-generics gen-id val-expr
  [method-id method-proc-expr] ...
  maybe-properties)
Like impersonate-generics, but +creates a chaperone of val-expr, which must be a structure +that implements the generic interface gen-id. The chaperone +applies the specified method-procs to the structure’s implementation +of the corresponding method-ids, and replaces the method +implementation with the result, which must be a chaperone of the original.

syntax

(redirect-generics mode gen-id val-expr
   [method-id method-proc-expr] ...
   maybe-properties)
Like impersonate-generics, but +creates an impersonator of val-expr +if mode evaluates to #f, or creates +a chaperone of val-expr otherwise.

syntax

(make-struct-type-property/generic
  name-expr
  maybe-guard-expr
  maybe-supers-expr
  maybe-can-impersonate?-expr
  property-option
  ...)
 
maybe-guard-expr = 
  | guard-expr
     
maybe-supers-expr = 
  | supers-expr
     
maybe-can-impersonate?-expr = 
  | can-impersonate?-expr
     
property-option = #:property prop-expr val-expr
  | #:methods gen:name-id method-defs
     
method-defs = (definition ...)
 
  name-expr : symbol?
  guard-expr : (or/c procedure? #f 'can-impersonate)
  supers-expr : (listof (cons/c struct-type-property? (-> any/c any/c)))
  can-impersonate?-expr : any/c
  prop-expr : struct-type-property?
  val-expr : any/c
Creates a new structure type property and returns three +values, just like make-struct-type-property would:

Any struct that implements this property will also implement +the properties and generic interfaces given in the +#:property and #:methods declarations. +The property val-exprs and method-defs are +evaluated eagerly when the property is created, not when +it is attached to a structure type.

syntax

(make-generic-struct-type-property
   gen:name-id
   method-def
   ...)
Creates a new structure type property and returns the +structure type property descriptor.

Any struct that implements this property will also implement +the generic interface given by gen:name-id +with the given method-defs. The method-defs +are evaluated eagerly when the property is created, not when +it is attached to a structure type.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/structinfo.html b/clones/docs.racket-lang.org/reference/structinfo.html new file mode 100644 index 00000000..1da836ec --- /dev/null +++ b/clones/docs.racket-lang.org/reference/structinfo.html @@ -0,0 +1,103 @@ + +5.7 Structure Type Transformer Binding

5.7 Structure Type Transformer Binding

The struct form binds the name of a structure type as +a transformer binding that records the other identifiers bound +to the structure type, the constructor procedure, the predicate +procedure, and the field accessor and mutator procedures. This +information can be used during the expansion of other expressions via +syntax-local-value.

For example, the struct variant for subtypes uses the +base type name t to find the variable +struct:t containing the base type’s descriptor; it +also folds the field accessor and mutator information for the base +type into the information for the subtype. As another example, the +match form uses a type name to find the predicates and field +accessors for the structure type. The struct form in an +imported signature for unit causes the unit +transformer to generate information about imported structure types, so +that match and subtyping struct forms work +within the unit.

The expansion-time information for a structure type can be represented +directly as a list of six elements (of the same sort that the +encapsulated procedure must return):

  • an identifier that is bound to the structure type’s descriptor, +or #f if none is known;

  • an identifier that is bound to the structure type’s constructor, +or #f if none is known;

  • an identifier that is bound to the structure type’s predicate, +or #f if none is known;

  • a list of identifiers bound to the field accessors of the +structure type, optionally with #f as the list’s last +element. A #f as the last element indicates that the +structure type may have additional fields, otherwise the list is a +reliable indicator of the number of fields in the structure +type. Furthermore, the accessors are listed in reverse order for the +corresponding constructor arguments. (The reverse order enables +sharing in the lists for a subtype and its base type.)

  • a list of identifiers bound to the field mutators of +the structure type, or #f for each field that has no known +mutator, and optionally with an extra #f as the list’s last +element (if the accessor list has such a #f). The list’s +order and the meaning of a final #f are the same as for the +accessor identifiers, and the length of the mutator list is the same +as the accessor list’s length.

  • an identifier that determines a super-type for the structure +type, #f if the super-type (if any) is unknown, or +#t if there is no super-type. If a super-type is specified, +the identifier is also bound to structure-type expansion-time +information.

Instead of this direct representation, the representation can be a +structure created by make-struct-info (or an instance of a +subtype of struct:struct-info), which encapsulates a +procedure that takes no arguments and returns a list of six +elements. Alternately, the representation can be a structure whose +type has the prop:struct-info structure type property. +Finally, the representation can be an instance of a structure type +derived from struct:struct-info or with the +prop:struct-info property that also implements +prop:procedure, and where the instance is further is wrapped +by make-set!-transformer. In addition, the representation may +implement the prop:struct-auto-info and +prop:struct-field-info properties.

Use struct-info? to recognize all allowed forms of the +information, and use extract-struct-info to obtain a list +from any representation.

The implementor of a syntactic form can expect users of the form to +know what kind of information is available about a structure type. For +example, the match implementation works with structure +information containing an incomplete set of accessor bindings, because +the user is assumed to know what information is available in the +context of the match expression. In particular, the +match expression can appear in a unit form with an +imported structure type, in which case the user is expected to know +the set of fields that are listed in the signature for the structure +type.

The bindings documented in this section are provided by the racket/struct-info library, not racket/base or racket.

procedure

(struct-info? v)  boolean?

  v : any/c
Returns #t if v is either a six-element list with +the correct shape for representing structure-type information, a +procedure encapsulated by make-struct-info, a structure with +the prop:struct-info property, or a structure type derived +from struct:struct-info or with prop:struct-info and +wrapped with make-set!-transformer.

procedure

(checked-struct-info? v)  boolean?

  v : any/c
Returns #t if v is a procedure encapsulated by +make-struct-info and produced by struct, but +only when no parent type is specified or the parent type is also +specified through a transformer binding to such a value.

procedure

(make-struct-info thunk)  struct-info?

  thunk : (-> (and/c struct-info? list?))
Encapsulates a thunk that returns structure-type information in list +form. Note that accessors are listed in reverse order, as mentioned in Structure Type Transformer Binding. +Note that the field names are not well-defined for struct-type informations +that are created with this method, so it is likely not going to work well +with forms like struct-copy and struct*.

Examples:
> (define (new-pair? x) (displayln "new pair?") (pair? x))
> (define (new-car x) (displayln "new car") (car x))
> (define (new-cdr x) (displayln "new cdr") (cdr x))
> (define-syntax new-list
    (make-struct-info
     (λ () (list #f
                 #'cons
                 #'new-pair?
                 (list #'new-cdr #'new-car)
                 (list #f #f)
                 #t))))
> (match (list 1 2 3)
    [(new-list hd tl) (append tl (list hd))])

new pair?

new car

new cdr

'(2 3 1)

Examples:
> (struct A (x y))
> (define (new-A-x a) (displayln "A-x") (A-x a))
> (define (new-A-y a) (displayln "A-y") (A-y a))
> (define (new-A? a) (displayln "A?") (A? a))
> (define-syntax A-info
    (make-struct-info
     (λ () (list #'A
                 #'A
                 #'new-A?
                 (list #'new-A-y #'new-A-x)
                 (list #f #f)
                 #t))))
> (define-match-expander B
    (syntax-rules () [(_ x ...) (A-info x ...)]))
> (match (A 10 20)
    [(B x y) (list y x)])

A?

A-x

A-y

'(20 10)

procedure

(extract-struct-info v)  (and/c struct-info? list?)

  v : struct-info?
Extracts the list form of the structure type information represented +by v.

The structure type descriptor for the structure type returned +by make-struct-info. This structure type descriptor is +mostly useful for creating structure subtypes. The structure type +includes a guard that checks an instance’s first field in the same way +as make-struct-info.

The structure type property for creating new structure types +like struct:struct-info. The property value must be a procedure +of one argument that takes an instance structure and returns +structure-type information in list form.

The prop:struct-auto-info property is implemented to provide +static information about which of the accessor and mutator identifiers +for a structure type correspond to #:auto fields (so that +they have no corresponding argument in the constructor). The property +value must be a procedure that accepts an instance structure to which +the property is given, and the result must be two lists of identifiers +suitable as a result from struct-auto-info-lists.

The struct-auto-info? predicate recognizes values that +implement the prop:struct-auto-info property.

The struct-auto-info-lists function extracts two lists of +identifiers from a value that implements the +prop:struct-auto-info property. The first list should be a +subset of the accessor identifiers for the structure type described by +sai, and the second list should be a subset of the mutator +identifiers. The two subsets correspond to #:auto fields.

The prop:struct-field-info property is implemented to provide +static information about field names in a structure type. The property +value must be a procedure that accepts an instance structure to which +the property is given, and the result must be a list of symbols +suitable as a result from struct-field-info-list.

The struct-field-info? predicate recognizes values that +implement the prop:struct-field-info property.

The struct-field-info-list function extracts a list of +symbols from a value that implements the prop:struct-field-info property. +The list should contain every immediate field name +(that is, not including fields from its super struct type) +in the reverse order.

Examples:
> (struct foo (x))
> (struct bar foo (y z))
> (define-syntax (get-bar-field-names stx)
    #`'#,(struct-field-info-list (syntax-local-value #'bar)))
> (get-bar-field-names)

'(z y)

Added in version 7.7.0.9 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/structprops.html b/clones/docs.racket-lang.org/reference/structprops.html new file mode 100644 index 00000000..87494cc4 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/structprops.html @@ -0,0 +1,74 @@ + +5.3 Structure Type Properties

5.3 Structure Type Properties

Generic Interfaces provide a high-level API on top of +structure type properties.

A structure type property allows per-type information to be + associated with a structure type (as opposed to per-instance + information associated with a structure value). A property value is + associated with a structure type through the + make-struct-type procedure (see + Creating Structure Types) or through the #:property + option of struct. Subtypes inherit the property + values of their parent types, and subtypes can override an inherited + property value with a new value.

procedure

(make-struct-type-property name 
  [guard 
  supers 
  can-impersonate? 
  accessor-name 
  contract-str 
  realm]) 
  
struct-type-property?
procedure?
procedure?
  name : symbol?
  guard : (or/c procedure? #f 'can-impersonate) = #f
  supers : 
(listof (cons/c struct-type-property?
                (any/c . -> . any/c)))
 = null
  can-impersonate? : any/c = #f
  accessor-name : (or/c symbol? #f) = #f
  contract-str : (or/c string? symbol? #f) = #f
  realm : symbol? = 'racket
Creates a new structure type property and returns three values:

  • a structure type property descriptor, for use with +make-struct-type and struct;

  • a property predicate procedure, which takes an +arbitrary value and returns #t if the value is a +descriptor or instance of a structure type that has a value for +the property, #f otherwise;

  • a property accessor procedure, which returns the +value associated with the structure type given its descriptor or +one of its instances; if the structure type does not have a +value for the property, or if any other kind of value is +provided, the exn:fail:contract exception is raised unless a second +argument, failure-result, is supplied to the +procedure. In that case, if failure-result is a +procedure, it is called (through a tail call) with no arguments +to produce the result of the property accessor procedure; +otherwise, failure-result is itself returned as the +result.

If the optional guard is supplied as a procedure, it is +called by make-struct-type before attaching the property to a +new structure type. The guard must accept two arguments: +a value for the property supplied to make-struct-type, and a +list containing information about the new structure type. The list +contains the values that struct-type-info would return for +the new structure type if it skipped the current-inspector +control checks.

The result of calling guard is associated with the property +in the target structure type, instead of the value supplied to +make-struct-type. To reject a property association (e.g., +because the value supplied to make-struct-type is +inappropriate for the property), the guard can raise an +exception. Such an exception prevents make-struct-type from +returning a structure type descriptor.

If guard is 'can-impersonate, then the property’s +accessor can be redirected through +impersonate-struct. This option is identical to supplying +#t as the can-impersonate? argument and is provided +for backwards compatibility.

The optional supers argument is a list of properties that are +automatically associated with some structure type when the newly +created property is associated to the structure type. Each property in +supers is paired with a procedure that receives the value +supplied for the new property (after it is processed by +guard) and returns a value for the associated property (which +is then sent to that property’s guard, of any).

The optional can-impersonate? argument determines if the +structure type property can be redirected through impersonate-struct. +If the argument is #f, then redirection is not allowed. +Otherwise, the property accessor may be redirected by a struct +impersonator.

The optional accessor-name argument supplies a name (in the +sense of object-name) to use for the returned accessor +function. If accessor-name is #f, a name is created +by adding -accessor to the end of name.

The optional contract-str argument supplies a contract that +is included in an error message with the returned accessor is applied +to a value that is not an instance of the property (and where a +failure-result argument is not supplied to the accessor). If +contract-str is #f, a contract is created by adding +? to the end of name.

The optional realm argument supplies a realm (in the +sense of procedure-realm) to associate with the returned +accessor.

Examples:
> (define-values (prop:p p? p-ref) (make-struct-type-property 'p))
> (define-values (struct:a make-a a? a-ref a-set!)
    (make-struct-type 'a #f 2 1 'uninitialized
                      (list (cons prop:p 8))))
> (p? struct:a)

#t

> (p? 13)

#f

> (define an-a (make-a 'x 'y))
> (p? an-a)

#t

> (p-ref an-a)

8

> (define-values (struct:b make-b b? b-ref b-set!)
    (make-struct-type 'b #f 0 0 #f))
> (p? struct:b)

#f

> (define-values (prop:q q? q-ref) (make-struct-type-property
                                    'q (lambda (v si) (add1 v))
                                    (list (cons prop:p sqrt))))
> (define-values (struct:c make-c c? c-ref c-set!)
    (make-struct-type 'c #f 0 0 'uninit
                      (list (cons prop:q 8))))
> (q-ref struct:c)

9

> (p-ref struct:c)

3

Changed in version 7.0 of package base: The CS implementation of Racket +skips the inspector check +for exposing an ancestor structure +type, if any, in information provided to a guard procedure.
Changed in version 8.4.0.2: Added the accessor-name, + contract-str, and + realm arguments.
Changed in version 8.5.0.2: Changed the BC implementation of Racket +to skip the inspector check, the same as the CS implementation, +for ancestor information provided to a guard procedure.

procedure

(struct-type-property? v)  boolean?

  v : any/c
Returns #t if v is a structure type property +descriptor value, #f otherwise.

Returns #t if v is an accessor procedure produced +by make-struct-type-property, #f otherwise.

procedure

(struct-type-property-predicate-procedure? v    
  [prop])  boolean?
  v : any/c
  prop : (or/c struct-type-property? #f) = #f
Returns #t if v is a predicate procedure produced by +make-struct-type-property and either prop is +#f or it was produced by the same call to +make-struct-type-property, #f otherwise.

Added in version 7.5.0.11 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/structures.html b/clones/docs.racket-lang.org/reference/structures.html new file mode 100644 index 00000000..943200d3 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/structures.html @@ -0,0 +1,53 @@ + +5 Structures

5 Structures

+Programmer-Defined Datatypes in The Racket Guide introduces structure types via struct.

A structure type is a record datatype composing a number of +fields. A structure, an instance of a structure +type, is a first-class value that contains a value for each field of +the structure type. A structure instance is created with a +type-specific constructor procedure, and its field values are +accessed and changed with type-specific accessor and +mutator procedures. In addition, each structure type has a +predicate procedure that answers #t for instances of +the structure type and #f for any other value.

A structure type’s fields are essentially unnamed, though names are +supported for error-reporting purposes. The constructor procedure +takes one value for each field of the structure type, except that some +of the fields of a structure type can be automatic fields; +the automatic fields are initialized to a constant that is +associated with the structure type, and the corresponding arguments +are omitted from the constructor procedure. All automatic fields in a +structure type follow the non-automatic fields.

A structure type can be created as a structure subtype of +an existing base structure type. An instance of a structure subtype +can always be used as an instance of the base structure type, but the +subtype gets its own predicate procedure, and it may have its own +fields in addition to the fields of the base type.

A structure subtype “inherits” the fields of its base type. If the +base type has m fields, and if n fields are specified +for the new structure subtype, then the resulting structure type has +m+n fields. The value for automatic fields can be different in +a subtype than in its base type.

If m of the original m fields are non-automatic (where +m<m), and n of the new fields are non-automatic (where +n<n), then m+n field values must be provided to the +subtype’s constructor procedure. Values for the first m fields +of a subtype instance are accessed with selector procedures for the +original base type (or its supertypes), and the last n are +accessed with subtype-specific selectors. Subtype-specific +accessors and mutators for the first m fields do +not exist.

The struct form and make-struct-type +procedure typically create a new structure type, but they can also +access prefab (i.e., previously fabricated) structure types +that are globally shared, and whose instances can be parsed and +written by the default reader (see The Reader) and printer (see +The Printer). Prefab structure types can inherit only from +other prefab structure types, and they cannot have guards (see +Creating Structure Types) or properties (see +Structure Type Properties). Exactly one prefab structure type exists for +each combination of name, supertype, field count, automatic field +count, automatic field value (when there is at least one automatic +field), and field mutability.

+Serialization also provides information on reading and writing structures.

Two structure values are +eqv? if and only if they are eq?. Two structure +values are equal? if they are eq?. By default, two +structure values are also equal? if they are instances of the +same structure type, no fields are opaque, and the results of applying +struct->vector to the structs are +equal?. (Consequently, equal? testing for +structures may depend on the current inspector.) A structure type can +override the default equal? definition through the +gen:equal+hash or gen:equal-mode+hash generic interface.

    5.1 Defining Structure Types: struct

    5.2 Creating Structure Types

    5.3 Structure Type Properties

    5.4 Generic Interfaces

    5.5 Copying and Updating Structures

    5.6 Structure Utilities

      5.6.1 Additional Structure Utilities

    5.7 Structure Type Transformer Binding

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/structutils.html b/clones/docs.racket-lang.org/reference/structutils.html new file mode 100644 index 00000000..74a143d2 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/structutils.html @@ -0,0 +1,82 @@ + +5.6 Structure Utilities

5.6 Structure Utilities

procedure

(struct->vector v [opaque-v])  vector?

  v : any/c
  opaque-v : any/c = '...
Creates a vector representing v. The first slot of the +result vector contains a symbol whose printed name has the form +struct:id. Each remaining slot contains +either the value of a field in v, if it is accessible via the +current inspector, or opaque-v for a field that is not +accessible. A single opaque-v value is used in the vector for +contiguous inaccessible fields. (Consequently, the size of the vector +does not match the size of the struct if more than one field +is inaccessible.)

procedure

(struct? v)  any

  v : any/c
Returns #t if +struct-info exposes any structure types of v with +the current inspector, #f otherwise.

Typically, when (struct? v) is true, then +(struct->vector v) exposes at least one field value. It is +possible, however, for the only visible types of v to +contribute zero fields.

procedure

(struct-type? v)  boolean?

  v : any/c
Returns #t if +v is a structure type descriptor value, #f +otherwise.

procedure

(struct-constructor-procedure? v)  boolean?

  v : any/c
Returns +#t if v is a constructor procedure generated by +struct or make-struct-type, #f +otherwise.

procedure

(struct-predicate-procedure? v)  boolean?

  v : any/c
Returns +#t if v is a predicate procedure generated by +struct or make-struct-type, #f +otherwise.

procedure

(struct-accessor-procedure? v)  boolean?

  v : any/c
Returns +#t if v is an accessor procedure generated by +struct, make-struct-type, or +make-struct-field-accessor, #f otherwise.

procedure

(struct-mutator-procedure? v)  boolean?

  v : any/c
Returns +#t if v is a mutator procedure generated by +struct, make-struct-type, or +make-struct-field-mutator, #f otherwise.

procedure

(prefab-struct-key v)  (or/c #f symbol? list?)

  v : any/c
Returns #f if v is not an instance of a +prefab structure type. Otherwise, the result is the shorted key +that could be used with make-prefab-struct to create an instance +of the structure type.

Examples:
> (prefab-struct-key #s(cat "Garfield"))

'cat

> (struct cat (name) #:prefab)
> (struct cute-cat cat (shipping-dest) #:prefab)
> (cute-cat "Nermel" "Abu Dhabi")

'#s((cute-cat cat 1) "Nermel" "Abu Dhabi")

> (prefab-struct-key (cute-cat "Nermel" "Abu Dhabi"))

'(cute-cat cat 1)

procedure

(make-prefab-struct key v ...)  struct?

  key : prefab-key?
  v : any/c
Creates an instance of a prefab structure type, using the +vs as field values. The key and the number of +vs determine the prefab structure type.

A key identifies a structure type based on a list with the +following items:

  • A symbol for the structure type’s name.

  • An exact, nonnegative integer representing the number of +non-automatic fields in the structure type, not counting fields +from the supertype (if any).

  • A list of two items, where the first is an exact, nonnegative +integer for the number of automatic fields in the structure +type that are not from the supertype (if any), and the second +element is an arbitrary value that is the value for the +automatic fields.

  • A vector of exact, nonnegative integers that indicate mutable +non-automatic fields in the structure type, counting from +0 and not including fields from the supertype (if +any).

  • Nothing else, if the structure type has no +supertype. Otherwise, the rest of the list is the key +for the supertype.

An empty vector and an auto-field list that starts with 0 can +be omitted. Furthermore, the first integer (which indicates the number +of non-automatic fields) can be omitted, since it can be inferred from +the number of supplied vs. Finally, a single symbol can be +used instead of a list that contains only a symbol (in the case that +the structure type has no supertype, no automatic fields, and no +mutable fields).

The total field count must be no more than 32768. If the number of +fields indicated by key is inconsistent with the number of +supplied vs, the exn:fail:contract exception is raised.

Examples:
> (make-prefab-struct 'clown "Binky" "pie")

'#s(clown "Binky" "pie")

> (make-prefab-struct '(clown 2) "Binky" "pie")

'#s(clown "Binky" "pie")

> (make-prefab-struct '(clown 2 (0 #f) #()) "Binky" "pie")

'#s(clown "Binky" "pie")

> (make-prefab-struct '(clown 1 (1 #f) #()) "Binky" "pie")

'#s((clown (1 #f)) "Binky" "pie")

> (make-prefab-struct '(clown 1 (1 #f) #(0)) "Binky" "pie")

'#s((clown (1 #f) #(0)) "Binky" "pie")

procedure

(prefab-struct-type-key+field-count type)

  (or/c #f (cons/c prefab-key? (integer-in 0 32768)))
  type : struct-type?
Returns a pair containing the prefab key and field count for +the structure type descriptor type if it represents a +prefab structure type, #f otherwise.

Added in version 8.5.0.8 of package base.

procedure

(prefab-key->struct-type key field-count)  struct-type?

  key : prefab-key?
  field-count : (integer-in 0 32768)
Returns a structure type descriptor for the prefab +structure type specified by the combination of key and +field-count.

If the number of fields indicated by key is inconsistent with +field-count, the exn:fail:contract exception is raised.

procedure

(prefab-key? v)  boolean?

  v : any/c
Return #t if v can be a prefab structure type +key, #f otherwise.

See make-prefab-struct for a description of valid key shapes.

5.6.1 Additional Structure Utilities

 (require racket/struct) package: base
The bindings documented in this section are provided by the racket/struct library, not racket/base or racket.

procedure

(make-constructor-style-printer get-constructor 
  get-contents) 
  (-> any/c output-port? (or/c #t #f 0 1) void?)
  get-constructor : (-> any/c (or/c symbol? string?))
  get-contents : (-> any/c sequence?)
Produces a function suitable as a value for + gen:custom-write or prop:custom-write. + The function prints values in “constructor style.” When + the value is printed as an expression, it is shown + as an application of the constructor (as returned by + get-constructor) to the contents (as returned by + get-contents). When given to write, it is + shown as an unreadable value with the constructor separated + from the contents by a colon.

Examples:
> (struct point (x y)
    #:methods gen:custom-write
    [(define write-proc
       (make-constructor-style-printer
        (lambda (obj) 'point)
        (lambda (obj) (list (point-x obj) (point-y obj)))))])
> (print (point 1 2))

(point 1 2)

> (write (point 1 2))

#<point: 1 2>

The function also cooperates with pretty-print:

> (parameterize ((pretty-print-columns 10))
    (pretty-print (point 3000000 4000000)))

(point

 3000000

 4000000)

> (parameterize ((pretty-print-columns 10))
    (pretty-write (point 3000000 4000000)))

#<point:

 3000000

 4000000>

Note that the printer uses a separate property, +prop:custom-print-quotable, to determine whether a struct +instance is quotable. If so, the printer may print it in +write mode it in certain contexts, such as within a list. For +example: +
> (print (list (point 1 2) (point 3 4)))

'(#<point: 1 2> #<point: 3 4>)

Use #:property prop:custom-print-quotable 'never to prevent a +struct instance from being considered quotable. For example: +
> (struct point2 (x y)
    #:property prop:custom-print-quotable 'never
    #:methods gen:custom-write
    [(define write-proc
       (make-constructor-style-printer
        (lambda (obj) 'point)
        (lambda (obj) (list (point2-x obj) (point2-y obj)))))])
> (print (list (point2 1 2) (point2 3 4)))

(list (point 1 2) (point 3 4))

Keyword arguments can be simulated with unquoted-printing-string:

; Private implementation
> (struct kwpoint-impl (x y)
    #:methods gen:custom-write
    [(define write-proc
       (make-constructor-style-printer
        (lambda (obj) 'kwpoint)
        (lambda (obj)
          (list (unquoted-printing-string "#:x")
                (kwpoint-impl-x obj)
                (unquoted-printing-string "#:y")
                (kwpoint-impl-y obj)))))])
; Public ``constructor''
> (define (kwpoint #:x x #:y y)
    (kwpoint-impl x y))
; Example use
> (print (kwpoint #:x 1 #:y 2))

(kwpoint #:x 1 #:y 2)

> (write (kwpoint #:x 3 #:y 4))

#<kwpoint: #:x 3 #:y 4>

Added in version 6.3 of package base.

procedure

(struct->list v [#:on-opaque on-opaque])  (or/c list? #f)

  v : any/c
  on-opaque : (or/c 'error 'return-false 'skip) = 'error
Returns a list containing the struct instance v’s +fields. Unlike struct->vector, the struct name itself is not +included.

If any fields of v are inaccessible via the current inspector +the behavior of struct->list is determined by +on-opaque. If on-opaque is 'error (the +default), an error is raised. If it is 'return-false, +struct->list returns #f. If it is 'skip, +the inaccessible fields are omitted from the list.

Examples:
> (struct open (u v) #:transparent)
> (struct->list (open 'a 'b))

'(a b)

> (struct->list #s(pre 1 2 3))

'(1 2 3)

> (struct secret open (x y))
> (struct->list (secret 0 1 17 22))

struct->list: expected argument of type <non-opaque struct>;

given: (secret 0 1 ...)

> (struct->list (secret 0 1 17 22) #:on-opaque 'return-false)

#f

> (struct->list (secret 0 1 17 22) #:on-opaque 'skip)

'(0 1)

> (struct->list 'not-a-struct #:on-opaque 'return-false)

#f

> (struct->list 'not-a-struct #:on-opaque 'skip)

'()

Added in version 6.3 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stx-patterns.html b/clones/docs.racket-lang.org/reference/stx-patterns.html new file mode 100644 index 00000000..aedf1fa3 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stx-patterns.html @@ -0,0 +1,197 @@ + +12.1 Pattern-Based Syntax Matching

12.1 Pattern-Based Syntax Matching

syntax

(syntax-case stx-expr (literal-id ...)
  clause ...)
 
clause = [pattern result-expr]
  | [pattern fender-expr result-expr]
     
pattern = np-pattern
  | (pattern ...)
  | (pattern ...+ . np-pattern)
  | (pattern ... pattern ellipsis pattern ... . np-pattern)
     
np-pattern = _
  | id
  | #(pattern ...)
  | #(pattern ... pattern ellipsis pattern ...)
  | #&pattern
  | #s(key-datum pattern ...)
  | #s(key-datum pattern ... pattern ellipsis pattern ...)
  | (ellipsis stat-pattern)
  | const
     
stat-pattern = id
  | (stat-pattern ...)
  | (stat-pattern ...+ . stat-pattern)
  | #(stat-pattern ...)
  | #&stat-pattern
  | #s(key-datum stat-pattern ...)
  | const
     
ellipsis = ...
Finds the first pattern that matches the syntax object +produced by stx-expr, and for which the corresponding +fender-expr (if any) produces a true value; the result is +from the corresponding result-expr, which is in tail position +for the syntax-case form. If no clause matches, then +the exn:fail:syntax exception is raised; the exception is generated by calling +raise-syntax-error with #f as the “name” argument, +a string with a generic error message, and the result of stx-expr.

A syntax object matches a pattern as follows:

_

A _ pattern (i.e., an identifier with the same binding as +_ and not among the literal-ids) matches any syntax object.

id

An id matches any syntax object when it is not bound to +... or _ and does not have the same binding as +any literal-id. The id is further bound as +pattern variable for the corresponding fender-expr +(if any) and result-expr. A pattern-variable binding is a +transformer binding; the pattern variable can be referenced only +through forms like syntax. The binding’s value is the syntax +object that matched the pattern with a depth marker of +0.

With a stat-pattern, ... is not treated specially. +It either matches a literal-id or is bound as a +pattern variable.

An id that has the same binding as a literal-id +matches a syntax object that is an identifier with the same binding +in the sense of free-identifier=?. The match does not +introduce any pattern variables.

(pattern ...)

A (pattern ...) pattern matches a syntax object whose datum +form (i.e., without lexical information) is a list with as many +elements as sub-patterns in the pattern, and where each +syntax object that corresponds to an element of the list matches +the corresponding sub-pattern.

Any pattern variables bound by the sub-patterns are +bound by the complete pattern; the bindings must all be distinct.

(pattern ...+ . np-pattern)

Like the previous kind of pattern, but matches syntax objects that +are not necessarily lists; for n sub-patterns before +the final np-pattern, the syntax object’s datum must be a +pair such that n-1 cdrs produce pairs. The final +np-pattern is matched against the syntax object +corresponding to the nth cdr (or the +datum->syntax coercion of the datum using the nearest +enclosing syntax object’s lexical context and source location).

(pattern ... pattern ellipsis pattern ...)

Like the (pattern ...) kind of pattern, but matching a +syntax object with any number (zero or more) elements that match the +sub-pattern followed by ellipsis in the +corresponding position relative to other sub-patterns.

For each pattern variable bound by the sub-pattern followed +by ellipsis, the larger pattern binds the same pattern +variable to a list of values, one for each element of the syntax +object matched to the sub-pattern, with an incremented +depth marker. (The sub-pattern itself may contain +ellipsis, leading to a pattern variables bound to lists of +lists of syntax objects with a depth marker of 2, and +so on.)

All patterns forms with ellipsis apply only when +ellipsis is not among the literal-ids.

(pattern ... pattern ellipsis pattern ... . np-pattern)

Like the previous kind of pattern, but with a final +np-pattern as for (pattern ...+ . np-pattern). The +final np-pattern never matches a syntax object whose datum is a +pair.

#(pattern ...)

Like a (pattern ...) pattern, but matching a vector syntax object +whose elements match the corresponding sub-patterns.

#(pattern ... pattern ellipsis pattern ...)

Like a (pattern ... pattern ellipsis pattern ...) pattern, +but matching a vector syntax object whose elements match the +corresponding sub-patterns.

#&pattern

Matches a box syntax object whose content matches the +pattern.

#s(key-datum pattern ...)

Like a (pattern ...) pattern, but matching a prefab +structure syntax object whose fields match the corresponding +sub-patterns. The key-datum must correspond to a +valid first argument to make-prefab-struct.

#s(key-datum pattern ... pattern ellipsis pattern ...)

Like a (pattern ... pattern ellipsis pattern ...) pattern, +but matching a prefab structure syntax object whose elements +match the corresponding sub-patterns.

(ellipsis stat-pattern)

Matches the same as stat-pattern, which is like a pattern, +but identifiers with the binding ... are treated the same as +other ids.

const

A const is any datum that does not match one of the +preceding forms; a syntax object matches a const pattern +when its datum is equal? to the quoted +const.

If stx-expr produces a non-syntax object, then its +result is converted to a syntax object using datum->syntax +and the lexical context and source location of the stx-expr.

If stx-expr produces a syntax object that is tainted, +then any syntax object bound by a pattern +are tainted.

Examples:
> (require (for-syntax racket/base))
> (define-syntax (swap stx)
    (syntax-case stx ()
      [(_ a b) #'(let ([t a])
                   (set! a b)
                   (set! b t))]))
> (let ([x 5] [y 10])
    (swap x y)
    (list x y))

'(10 5)

> (syntax-case #'(ops 1 2 3 => +) (=>)
    [(_ x ... => op) #'(op x ...)])

#<syntax:eval:657:0 (+ 1 2 3)>

> (syntax-case #'(let ([x 5] [y 9] [z 12])
                   (+ x y z))
               (let)
    [(let ([var expr] ...) body ...)
     (list #'(var ...)
           #'(expr ...))])

'(#<syntax:eval:658:0 (x y z)> #<syntax:eval:658:0 (5 9 12)>)

syntax

(syntax-case* stx-expr (literal-id ...) id-compare-expr
  clause ...)
Like syntax-case, but id-compare-expr must produce a +procedure that accepts two arguments. A literal-id in a +pattern matches an identifier for which the procedure +returns true when given the identifier to match (as the first argument) +and the identifier in the pattern (as the second argument).

In other words, syntax-case is like syntax-case* with +an id-compare-expr that produces free-identifier=?.

syntax

(with-syntax ([pattern stx-expr] ...)
  body ...+)
Similar to syntax-case, in that it matches a pattern +to a syntax object. Unlike syntax-case, all patterns +are matched, each to the result of a corresponding stx-expr, +and the pattern variables from all matches (which must be distinct) +are bound with a single body sequence. The result of the +with-syntax form is the result of the last body, +which is in tail position with respect to the with-syntax +form.

If any pattern fails to match the corresponding +stx-expr, the exn:fail:syntax exception is raised.

A with-syntax form is roughly equivalent to the following +syntax-case form:

(syntax-case (list stx-expr ...) ()
  [(pattern ...) (let () body ...+)])

However, if any individual stx-expr produces a +non-syntax object, then it is converted to one using +datum->syntax and the lexical context and source location of +the individual stx-expr.

Examples:
> (define-syntax (hello stx)
    (syntax-case stx ()
      [(_ name place)
       (with-syntax ([print-name #'(printf "~a\n" 'name)]
                     [print-place #'(printf "~a\n" 'place)])
         #'(begin
             (define (name times)
               (printf "Hello\n")
               (for ([i (in-range 0 times)])
                    print-name))
             (define (place times)
               (printf "From\n")
               (for ([i (in-range 0 times)])
                    print-place))))]))
> (hello jon utah)
> (jon 2)

Hello

jon

jon

> (utah 2)

From

utah

utah

> (define-syntax (math stx)
    (define (make+1 expression)
      (with-syntax ([e expression])
        #'(+ e 1)))
    (syntax-case stx ()
      [(_ numbers ...)
       (with-syntax ([(added ...)
                      (map make+1
                           (syntax->list #'(numbers ...)))])
         #'(begin
             (printf "got ~a\n" added)
             ...))]))
> (math 3 1 4 1 5 9)

got 4

got 2

got 5

got 2

got 6

got 10

syntax

(syntax template)

 
template = id
  | (head-template ...)
  | (head-template ...+ . template)
  | #(head-template ...)
  | #&template
  | #s(key-datum head-template ...)
  | (~? template template)
  | (ellipsis stat-template)
  | const
     
head-template = template
  | head-template ellipsis ...+
  | (~@ . template)
  | (~? head-template head-template)
  | (~? head-template)
     
stat-template = like template, but without ..., +~?, and ~@
     
ellipsis = ...
Constructs a syntax object based on a template, which can +include pattern variables bound by syntax-case or +with-syntax.

A template produces a single syntax object. A +head-template produces a sequence of zero or more syntax +objects. A stat-template is like a template, except that +..., ~?, and ~@ are interpreted as +constants instead of template forms.

A template produces a syntax object as follows:

id

If id is bound as a pattern variable, then +id as a template produces the pattern variable’s +match result. Unless the id is a sub-template that is +replicated by ellipsis in a larger template, the +pattern variable’s value must be a syntax object with a +depth marker of 0 (as opposed to a list of +matches).

More generally, if the pattern variable’s value has a depth +marker n, then it can only appear within a template where it +is replicated by at least n ellipsises. In that case, +the template will be replicated enough times to use each match result +at least once.

If id is not bound as a pattern variable, then id +as a template produces (quote-syntax id).

(head-template ...)

Produces a syntax object whose datum is a list, and where the +elements of the list correspond to syntax objects produced by the +head-templates.

(head-template ... . template)

Like the previous form, but the result is not necessarily a list; +instead, the place of the empty list in the resulting syntax object’s +datum is taken by the syntax object produced by template.

#(head-template ...)

Like the (head-template ...) form, but producing a syntax +object whose datum is a vector instead of a list.

#&template

Produces a syntax object whose datum is a box holding the +syntax object produced by template.

#s(key-datum head-template ...)

Like the (head-template ...) form, but producing a syntax +object whose datum is a prefab structure instead of a list. +The key-datum must correspond to a valid first argument of +make-prefab-struct.

(~? template1 template2)

Produces the result of template1 if template1 has no +pattern variables with “missing values”; otherwise, produces the result of +template2.

A pattern variable bound by syntax-case never has a missing value, but +pattern variables bound by syntax-parse (for example, ~or or +~optional patterns) can.

Examples:
> (syntax-parse #'(m 1 2 3)
    [(_ (~optional (~seq #:op op:expr)) arg:expr ...)
     #'((~? op +) arg ...)])

#<syntax:eval:3:0 (+ 1 2 3)>

> (syntax-parse #'(m #:op max 1 2 3)
    [(_ (~optional (~seq #:op op:expr)) arg:expr ...)
     #'((~? op +) arg ...)])

#<syntax:eval:4:0 (max 1 2 3)>

(ellipsis stat-template)

Produces the same result as stat-template, which is like a +template, but ..., ~?, and ~@ +are treated like an id (with no pattern binding).

const

A const template is any form that does not match the +preceding cases, and it produces the result (quote-syntax const).

A head-template produces a sequence of syntax objects; that sequence is +“inlined” into the result of the enclosing template. The result of a +head-template is defined as follows:

template

Produces one syntax object, according to the rules for template +above.

head-template ellipsis ...+

Generates a sequence of syntax objects by “mapping” the +head-template over the values of its pattern variables. The number of +iterations depends on the values of the pattern variables referenced +within the sub-template.

To be more precise: Let outer be inner followed by one +ellipsis. A pattern variable is an iteration pattern variable +for outer if occurs at a depth equal to its depth +marker. There must be at least one; otherwise, an error is raised. If there +are multiple iteration variables, then all of their values must be lists of +the same length. The result for outer is produced by +mapping the inner template over the iteration pattern +variable values and decreasing their effective depth markers by 1 +within inner. The outer result is formed by appending the +inner results.

Consequently, if a pattern variable occurs at a depth greater than its +depth marker, it is used as an iteration pattern variable for +the innermost ellipses but not the outermost. A pattern variable must +not occur at a depth less than its depth marker; otherwise, an error is +raised.

(~@ . template)

Produces the sequence of elements in the syntax list produced by +template. If template does not produce a proper syntax list, +an exception is raised.

Examples:
> (with-syntax ([(key ...) #'('a 'b 'c)]
                [(val ...) #'(1 2 3)])
    #'(hash (~@ key val) ...))

#<syntax:eval:2:0 (hash (quote a) 1 (quote b) 2 (quote c) 3)>

> (with-syntax ([xs #'(2 3 4)])
    #'(list 1 (~@ . xs) 5))

#<syntax:eval:3:0 (list 1 2 3 4 5)>

(~? head-template1 head-template2)

Produces the result of head-template1 if none of its pattern +variables have “missing values”; otherwise produces the result of +head-template2.

(~? head-template)

Produces the result of head-template if none of its pattern +variables have “missing values”; otherwise produces nothing.

Equivalent to (~? head-template (~@)).

A (syntax template) form is normally +abbreviated as #'template; see also +Reading Quotes. If template contains no pattern +variables, then #'template is equivalent to +(quote-syntax template).

Changed in version 6.90.0.25 of package base: Added ~@ and ~?.

syntax

(quasisyntax template)

Like syntax, but (unsyntax expr) and (unsyntax-splicing expr) +escape to an expression within the template.

The expr must produce a syntax object (or syntax list) to be +substituted in place of the unsyntax or +unsyntax-splicing form within the quasiquoting template, just +like unquote and unquote-splicing within +quasiquote, except that a hash table value position is not +an escape position for quasisyntax. (If the escaped expression does not generate a +syntax object, it is converted to one in the same way as for the +right-hand side of with-syntax.) Nested +quasisyntaxes introduce quasiquoting layers in the same way +as nested quasiquotes.

Also analogous to quasiquote, the reader converts #` +to quasisyntax, #, to unsyntax, and +#,@ to unsyntax-splicing. See also +Reading Quotes.

syntax

(unsyntax expr)

Illegal as an expression form. The unsyntax form is for use +only with a quasisyntax template.

syntax

(unsyntax-splicing expr)

Illegal as an expression form. The unsyntax-splicing form is +for use only with a quasisyntax template.

syntax

(syntax/loc loc-expr template)

 
  loc-expr : 
(or/c #f srcloc? syntax?
      (list/c any/c
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f)
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f))
      (vector/c any/c
                (or/c exact-positive-integer? #f)
                (or/c exact-nonnegative-integer? #f)
                (or/c exact-positive-integer? #f)
                (or/c exact-nonnegative-integer? #f)))
Like syntax, except that the immediate resulting syntax +object takes its source-location information from the result of +loc-expr.

Only the source location of the immediate result—the “outermost” +syntax object—is adjusted. The source location is not +adjusted if both the source and position of loc-expr are +#f. The source location is adjusted only if the resulting +syntax object comes from the template itself rather than the value of +a syntax pattern variable. For example, if x is a syntax +pattern variable, then (syntax/loc loc-expr x) does not use +the location of loc-expr.

Changed in version 6.90.0.25 of package base: Previously, syntax/loc +did not enforce the contract on loc-expr if template +was just a pattern variable.
Changed in version 8.2.0.6: Allows loc-expr to be any +source location value that datum->syntax accepts.

syntax

(quasisyntax/loc loc-expr template)

 
  loc-expr : 
(or/c #f srcloc? syntax?
      (list/c any/c
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f)
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f))
      (vector/c any/c
                (or/c exact-positive-integer? #f)
                (or/c exact-nonnegative-integer? #f)
                (or/c exact-positive-integer? #f)
                (or/c exact-nonnegative-integer? #f)))
Like quasisyntax, but with source-location assignment like +syntax/loc.

Changed in version 8.2.0.6 of package base: Allows loc-expr to be any +source location value that datum->syntax accepts.

syntax

(quote-syntax/prune id)

Like quote-syntax, but the lexical context of id is +pruned via identifier-prune-lexical-context to including +binding only for the symbolic name of id and for +'#%top. Use this form to quote an identifier when its lexical +information will not be transferred to other syntax objects (except +maybe to '#%top for a top-level binding).

syntax

(syntax-rules (literal-id ...)
  [(id . pattern) template] ...)
Equivalent to

(lambda (stx)
  (syntax-case stx (literal-id ...)
    [(generated-id . pattern) (syntax-protect #'template)]  ...))

where each generated-id binds no identifier in the +corresponding template.

syntax

(syntax-id-rules (literal-id ...)
  [pattern template] ...)
Equivalent to

(make-set!-transformer
 (lambda (stx)
   (syntax-case stx (literal-id ...)
     [pattern (syntax-protect #'template)]  ...)))

syntax

(define-syntax-rule (id . pattern) template)

Equivalent to

(define-syntax id
  (syntax-rules ()
   [(id . pattern) template]))

but with syntax errors potentially phrased in terms of +pattern.

syntax

...

The ... transformer binding prohibits ... from +being used as an expression. This binding is useful only in syntax +patterns and templates (or other unrelated expression forms +that treat it specially like ->), where it indicates repetitions +of a pattern or template. See syntax-case and syntax.

syntax

_

The _ transformer binding prohibits _ from being +used as an expression. This binding is useful only in syntax patterns, +where it indicates a pattern that matches any syntax object. See +syntax-case.

syntax

~?

syntax

~@

The ~? and ~@ transformer bindings prohibit these forms from +being used as an expression. The bindings are useful only in syntax templates. +See syntax.

Added in version 6.90.0.25 of package base.

procedure

(syntax-pattern-variable? v)  boolean?

  v : any/c
Returns #t if v is a value that, as a +transformer-binding value, makes the bound variable as pattern +variable in syntax and other forms. To check whether an +identifier is a pattern variable, use syntax-local-value to +get the identifier’s transformer value, and then test the value with +syntax-pattern-variable?.

The syntax-pattern-variable? procedure is provided +for-syntax by racket/base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stxcerts.html b/clones/docs.racket-lang.org/reference/stxcerts.html new file mode 100644 index 00000000..ce8c823d --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stxcerts.html @@ -0,0 +1,27 @@ + +12.8 Syntax Taints

12.8 Syntax Taints

+Tainted Syntax in The Racket Guide introduces syntax taints.

A tainted identifier is rejected by the macro expander for +use as either a binding or expression. If a syntax object stx is +tainted, then any syntax object in the result of +(syntax-e stx) is tainted, and datum->syntax +with stx as its first argument produces a tainted +syntax object. Any syntax object in the result of (syntax-property stx key) +is also tainted if it is in a position within the value that would be +reached by datum->syntax’s conversion. Taints cannot be removed.

A syntax object is tainted when it is included in an exception by the +macro expander or when it is produced by a function like +expand using a code inspector that is not the original +code inspector. The function syntax-taint also returns a +tainted syntax object.

Previous versions of Racket included a notion of arming and +disarming syntax to trigger taints or avoid taints. That +indirection is no longer supported, and the operations +syntax-arm, syntax-disarm, syntax-rearm, and +syntax-protect now have no effect on their arguments. Along +similar lines, the syntax properties (see Syntax Object Properties) +'taint-mode and 'certify-mode were +formerly used to control syntax arming and are no longer specifically +recognized by the macro expander.

procedure

(syntax-tainted? stx)  boolean?

  stx : syntax?
Returns #t if stx is tainted, #f +otherwise.

procedure

(syntax-arm stx [inspector use-mode?])  syntax?

  stx : syntax?
  inspector : (or/c inspector? #f) = #f
  use-mode? : any/c = #f
Returns stx.

Changed in version 8.2.0.4 of package base: Changed to just return stx instead +of returning “armed” syntax.

procedure

(syntax-protect stx)  syntax?

  stx : syntax?
Returns stx.

Changed in version 8.2.0.4 of package base: Changed to just return stx instead +of returning “armed” syntax.

procedure

(syntax-disarm stx inspector)  syntax?

  stx : syntax?
  inspector : (or/c inspector? #f)
Returns stx.

Changed in version 8.2.0.4 of package base: Changed to just return stx instead +of potentially “disarming” syntax.

procedure

(syntax-rearm stx from-stx [use-mode?])  syntax?

  stx : syntax?
  from-stx : syntax?
  use-mode? : any/c = #f
Returns stx.

Changed in version 8.2.0.4 of package base: Changed to just return stx instead +of potentially “arming” syntax.

procedure

(syntax-taint stx)  syntax?

  stx : syntax?
Returns tainted version of stx, which is stx +if it is already tainted.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stxcmp.html b/clones/docs.racket-lang.org/reference/stxcmp.html new file mode 100644 index 00000000..b5961708 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stxcmp.html @@ -0,0 +1,97 @@ + +12.3 Syntax Object Bindings

12.3 Syntax Object Bindings

procedure

(bound-identifier=? a-id b-id [phase-level])  boolean?

  a-id : syntax?
  b-id : syntax?
  phase-level : (or/c exact-integer? #f)
   = (syntax-local-phase-level)
Returns #t if the identifier a-id would bind +b-id (or vice versa) if the identifiers were substituted in a +suitable expression context at the phase level indicated by +phase-level, #f otherwise. A #f value for +phase-level corresponds to the label phase level.

Examples:
> (define-syntax (check stx)
    (syntax-case stx ()
      [(_ x y)
       (if (bound-identifier=? #'x #'y)
           #'(let ([y 'wrong]) (let ([x 'binds]) y))
           #'(let ([y 'no-binds]) (let ([x 'wrong]) y)))]))
> (check a a)

'binds

> (check a b)

'no-binds

> (define-syntax-rule (check-a x) (check a x))
> (check-a a)

'no-binds

procedure

(free-identifier=? a-id    
  b-id    
  [a-phase-level    
  b-phase-level])  boolean?
  a-id : identifier?
  b-id : identifier?
  a-phase-level : (or/c exact-integer? #f)
   = (syntax-local-phase-level)
  b-phase-level : (or/c exact-integer? #f) = a-phase-level
Returns #t if a-id and b-id access the same +local binding, module binding, or top-level +bindingperhaps via rename transformersat the phase +levels indicated by a-phase-level and +b-phase-level, respectively. A #f value for +a-phase-level or b-phase-level corresponds to the +label phase level.

“Same module binding” means that the identifiers refer to the same +original definition site, and not necessarily to the same +require or provide site. Due to renaming in +require and provide, or due to a transformer binding +to a rename transformer, the identifiers may return distinct +results with syntax-e.

Examples:
> (define-syntax (check stx)
    (syntax-case stx ()
      [(_ x)
       (if (free-identifier=? #'car #'x)
           #'(list 'same: x)
           #'(list 'different: x))]))
> (check car)

'(same: #<procedure:car>)

> (check mcar)

'(different: #<procedure:mcar>)

> (let ([car list])
    (check car))

'(different: #<procedure:list>)

> (require (rename-in racket/base [car kar]))
> (check kar)

'(same: #<procedure:car>)

procedure

(free-transformer-identifier=? a-id b-id)  boolean?

  a-id : identifier?
  b-id : identifier?

procedure

(free-template-identifier=? a-id b-id)  boolean?

  a-id : identifier?
  b-id : identifier?

procedure

(free-label-identifier=? a-id b-id)  boolean?

  a-id : identifier?
  b-id : identifier?
Same as (free-identifier=? a-id b-id #f).

procedure

(check-duplicate-identifier ids)  (or/c identifier? #f)

  ids : (listof identifier?)
Compares each identifier in ids with every other identifier +in the list with bound-identifier=?. If any comparison +returns #t, one of the duplicate identifiers is returned (the +first one in ids that is a duplicate), otherwise the result +is #f.

procedure

(identifier-binding id-stx 
  [phase-level 
  top-level-symbol?]) 
  
(or/c 'lexical
      #f
      (list/c module-path-index?
              symbol?
              module-path-index?
              symbol?
              exact-nonnegative-integer?
              phase+space-shift?
              phase+space?)
      (list/c symbol?))
  id-stx : identifier?
  phase-level : (or/c exact-integer? #f)
   = (syntax-local-phase-level)
  top-level-symbol? : any/c = #f
Returns one of three (if top-level-symbol? is #f) +or four (if top-level-symbol? is true) kinds of values, depending on the binding of +id-stx at the phase level indicated by +phase-level (where a #f value for +phase-level corresponds to the label phase level):

  • The result is 'lexical if id-stx +has a local binding.

  • The result is a list of seven items when id-stx +has a module binding: (list from-mod from-sym nominal-from-mod nominal-from-sym from-phase import-phase+space-shift nominal-export-phase).

    • from-mod is a module path index (see +Compiled Modules and References) that indicates the defining module. It +is the “self” module path index if the binding refers to a +definition in the enclosing module of id-stx.

    • from-sym is a symbol for the identifier’s name +at its definition site in the originating module. This can be +different from the local name returned by +syntax->datum for several reasons: the identifier is +renamed on import, it is renamed on export, or it is +implicitly renamed because the binding site was generated by a +macro invocation. In that last case, it may be an +unreadable symbol, and it may be different from the +result of syntax->datum on the identifier in the +original source definition.

    • nominal-from-mod is a module path index (see +Compiled Modules and References) that indicates the binding’s module as +it appears locally in the source around id-stx: it +indicates a module required into the context of +id-stx to provide its binding, or it is the same +“self” as from-mod for a binding that refers to a +definition in the enclosing module of id-stx. It can +be different from from-mod due to a re-export in +nominal-from-mod of some imported identifier. If the +same binding is imported in multiple ways, an arbitrary +representative is chosen.

    • nominal-from-sym is a symbol for the binding’s +identifier as it appears locally in the source around +id-stx: it is the identifier’s name as exported by +nominal-from-mod, or it is the source identifier’s +symbol for a definition within the enclosing module of +id-stx. It can be different from from-sym +due to a renaming provide, even if from-mod +and nominal-from-mod are the same, or due to a +definition that was introduced by a macro expansion.

    • from-phase is an exact non-negative integer +representing the originating phase. For example, it is +1 if the definition is for-syntax.

    • import-phase+space-shift is 0 if the binding +import of nominal-from-mode is from a definition +or a plain require, 1 if it is from a +for-syntax import, a phase combined with a space name if it +is from a for-space import, etc.

    • nominal-export-phase+space is the phase level +and binding space +of the export from nominal-from-mod for an +imported binding, or it is the phase level of the definition for a +binding from the enclosing module of id-stx.

  • The result is (list top-sym) if id-stx +has a top-level binding and +top-level-symbol? is true. The top-sym +can different from the name returned by +syntax->datum when the binding definition was +generated by a macro invocation.

  • The result is #f if id-stx has a +top-level binding and top-level-symbol? is +#f or if id-stx is unbound. An +unbound identifier is typically treated the same as an +identifier whose top-level binding is a variable.

If id-stx is bound to a rename-transformer, the result +from identifier-binding is for the identifier in the +transformer, so that identifier-binding is consistent with +free-identifier=?.

Changed in version 6.6.0.4 of package base: Added the top-level-symbol? argument to report +information on top-level bindings.
Changed in version 8.2.0.3: Generalized phase results to phase–space combinations.

procedure

(identifier-transformer-binding id-stx 
  [rt-phase-level]) 
  
(or/c 'lexical
      #f
      (listof module-path-index?
              symbol?
              module-path-index?
              symbol?
              exact-nonnegative-integer?
              phase+space-shift?
              phase+space?))
  id-stx : identifier?
  rt-phase-level : (or/c exact-integer? #f)
   = (syntax-local-phase-level)
Same as (identifier-binding id-stx (and rt-phase-level (add1 rt-phase-level))).

Changed in version 8.2.0.3 of package base: Generalized phase results to phase–space combinations.

procedure

(identifier-template-binding id-stx)

  
(or/c 'lexical
      #f
      (listof module-path-index?
              symbol?
              module-path-index?
              symbol?
              phase+space?
              phase+space-shift?
              phase+space?))
  id-stx : identifier?

Changed in version 8.2.0.3 of package base: Generalized phase results to phase–space combinations.

procedure

(identifier-label-binding id-stx)

  
(or/c 'lexical
      #f
      (listof module-path-index?
              symbol?
              module-path-index?
              symbol?
              exact-nonnegative-integer?
              phase+space-shift?
              phase+space?))
  id-stx : identifier?
Same as (identifier-binding id-stx #f).

Changed in version 8.2.0.3 of package base: Generalized phase results to phase–space combinations.

procedure

(identifier-distinct-binding id-stx 
  wrt-id-stx 
  [phase-level]) 
  
(or/c 'lexical
      #f
      (list/c module-path-index?
              symbol?
              module-path-index?
              symbol?
              exact-nonnegative-integer?
              phase+space-shift?
              phase+space?)
      (list/c symbol?))
  id-stx : identifier?
  wrt-id-stx : identifier?
  phase-level : (or/c exact-integer? #f)
   = (syntax-local-phase-level)
Like (identifier-binding id-stx phase-level), but the result +is #f if the binding for id-stx has scopes that are +a subset of the scopes for wrt-id-stx. That is, if +id-stx and wrt-id-stx have the same symbolic name, a +binding for id-stx is returned only if the binding does not +also apply to wrt-id-stx.

Added in version 8.3.0.8 of package base.

procedure

(identifier-binding-symbol id-stx    
  [phase-level])  symbol?
  id-stx : identifier?
  phase-level : (or/c exact-integer? #f)
   = (syntax-local-phase-level)
Like identifier-binding, but produces a symbol that +corresponds to the binding. The symbol result is the same for any +identifiers that are free-identifier=?, but the result may +also be the same for identifiers that are not +free-identifier=? (i.e., different symbols imply different +bindings, but the same symbol does not imply the same binding).

When identifier-binding would produce a list, then the second +element of that list is the result that +identifier-binding-symbol produces.

procedure

(identifier-binding-portal-syntax id-stx 
  [phase-level]) 
  (or/c #f syntax?)
  id-stx : identifier?
  phase-level : (or/c exact-integer? #f)
   = (syntax-local-phase-level)
If id-stx is bound at phase-level to portal +syntax, either via define-syntax or #%require, then +the portal syntax content is returned. The module that binds +id-stx must be declared, but it need not be instantiated at +the relevant phase, and identifier-binding-portal-syntax does +not instantiate the module.

Added in version 8.3.0.8 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stxops.html b/clones/docs.racket-lang.org/reference/stxops.html new file mode 100644 index 00000000..c563a5cc --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stxops.html @@ -0,0 +1,171 @@ + +12.2 Syntax Object Content

12.2 Syntax Object Content

procedure

(syntax? v)  boolean?

  v : any/c
Returns #t if v is a syntax object, #f +otherwise. See also Syntax Objects.

Examples:
> (syntax? #'quinoa)

#t

> (syntax? #'(spelt triticale buckwheat))

#t

> (syntax? (datum->syntax #f 'millet))

#t

> (syntax? "barley")

#f

procedure

(identifier? v)  boolean?

  v : any/c
Returns #t if v is a syntax object and +(syntax-e stx) produces a symbol.

Examples:
> (identifier? #'linguine)

#t

> (identifier? #'(if wheat? udon soba))

#f

> (identifier? 'ramen)

#f

> (identifier? 15)

#f

procedure

(syntax-source stx)  any/c

  stx : syntax?
Returns the source component of the source location +for the syntax object stx, or #f +if none is known. The source is represented by an arbitrary value +(e.g., one passed to read-syntax), but it is typically a file +path string.

See also syntax-srcloc from racket/syntax-srcloc.

procedure

(syntax-line stx)  (or/c exact-positive-integer? #f)

  stx : syntax?
Returns the line number (positive exact integer) +of the source location for the start of the +syntax object in its source, or #f if the line number or +source is unknown. See also Counting Positions, Lines, and Columns.

Changed in version 7.0 of package base: Dropped a guarantee that syntax-line +and syntax-column both produce +#f or both produce integers.

procedure

(syntax-column stx)  (or/c exact-nonnegative-integer? #f)

  stx : syntax?
Returns the column number (non-negative exact integer) +of the source location for the start +of the syntax object in its source, or #f if the source +column is unknown. See also Counting Positions, Lines, and Columns.

Changed in version 7.0 of package base: Dropped a guarantee that syntax-line +and syntax-column both produce +#f or both produce integers.

procedure

(syntax-position stx)  (or/c exact-positive-integer? #f)

  stx : syntax?
Returns the character position (positive exact integer) +of the source location for the start +of the syntax object in its source, or #f if the source +position is unknown. See also Counting Positions, Lines, and Columns.

procedure

(syntax-span stx)  (or/c exact-nonnegative-integer? #f)

  stx : syntax?
Returns the span (non-negative exact integer) in characters +of the source location for +syntax object in its source, or #f if the span is +unknown.

procedure

(syntax-original? stx)  boolean?

  stx : syntax?
Returns #t if stx has the property that +read-syntax attaches to the +syntax objects that they generate (see Syntax Object Properties), and if +stx’s lexical information does not include any macro-introduction scopes (which indicate that the +object was introduced by a syntax transformer; see +Syntax Objects). The result is #f otherwise.

This predicate can be used to distinguish syntax objects in an expanded +expression that were directly present in the original expression, as +opposed to syntax objects inserted by macros.

The (hidden) property to represent original syntax is dropped for a +syntax object that is marshaled as part of compiled code; see also +current-compile.

procedure

(syntax-source-module stx [source?])

  (or/c module-path-index? symbol? path? resolved-module-path? #f)
  stx : syntax?
  source? : any/c = #f
Returns an indication of the module whose source contains +stx, or #f if no source module for stx +can be inferred from its lexical context. If +source? is #f, then result is a module path index or +symbol (see Compiled Modules and References) or a resolved module path; if source? is true, the +result is a path or symbol corresponding to the loaded module’s +source in the sense of current-module-declare-source.

Note that syntax-source-module does not consult the +source location of stx. The result is based on the +lexical information of stx.

procedure

(syntax-e stx)  any/c

  stx : syntax?
Unwraps the immediate datum structure from a syntax object, +leaving nested syntax structure (if any) in place. The result of +(syntax-e stx) is one of the following:

Examples:
> (syntax-e #'a)

'a

> (syntax-e #'(x . y))

'(#<syntax:eval:11:0 x> . #<syntax:eval:11:0 y>)

> (syntax-e #'#(1 2 (+ 3 4)))

'#(#<syntax:eval:12:0 1> #<syntax:eval:12:0 2> #<syntax:eval:12:0 (+ 3 4)>)

> (syntax-e #'#&"hello world")

'#&#<syntax:eval:13:0 "hello world">

> (syntax-e #'#hash((imperial . "yellow") (festival . "green")))

'#hash((festival . #<syntax:eval:14:0 "green">)

       (imperial . #<syntax:eval:14:0 "yellow">))

> (syntax-e #'#(point 3 4))

'#(#<syntax:eval:15:0 point> #<syntax:eval:15:0 3> #<syntax:eval:15:0 4>)

> (syntax-e #'3)

3

> (syntax-e #'"three")

"three"

> (syntax-e #'#t)

#t

A syntax pair is a pair containing a syntax object as its +first element, and either the empty list, a syntax pair, or a syntax +object as its second element.

A syntax object that is the result of read-syntax reflects +the use of delimited . in the input by creating a syntax +object for every pair of parentheses in the source, and by creating a +pair-valued syntax object only for parentheses in the +source. See Reading Pairs and Lists for more information.

If stx is tainted, then any syntax object in the +result of (syntax-e stx) is tainted. The results from +multiple calls to syntax-e of stx are eq?.

procedure

(syntax->list stx)  (or/c list? #f)

  stx : syntax?
Returns a list of syntax objects or #f. The result is a list +of syntax objects when (syntax->datum stx) would produce a +list. In other words, syntax pairs in (syntax-e stx) +are flattened.

If stx is tainted, then any syntax +object in the result of (syntax->list stx) is tainted.

Examples:
> (syntax->list #'())

'()

> (syntax->list #'(1 (+ 3 4) 5 6))

'(#<syntax:eval:20:0 1>

  #<syntax:eval:20:0 (+ 3 4)>

  #<syntax:eval:20:0 5>

  #<syntax:eval:20:0 6>)

> (syntax->list #'a)

#f

procedure

(syntax->datum stx)  any/c

  stx : syntax?
Returns a datum by stripping the lexical information, source-location +information, properties, and tamper status from stx. Inside of +pairs, (immutable) vectors, (immutable) boxes, immutable hash +table values (not keys), and immutable prefab structures, +syntax objects are recursively stripped.

The stripping operation does not mutate stx; it creates new +pairs, vectors, boxes, hash tables, and prefab structures as +needed to strip lexical and source-location information recursively.

Examples:
> (syntax->datum #'a)

'a

> (syntax->datum #'(x . y))

'(x . y)

> (syntax->datum #'#(1 2 (+ 3 4)))

'#(1 2 (+ 3 4))

> (syntax->datum #'#&"hello world")

'#&"hello world"

> (syntax->datum #'#hash((imperial . "yellow") (festival . "green")))

'#hash((festival . "green") (imperial . "yellow"))

> (syntax->datum #'#(point 3 4))

'#(point 3 4)

> (syntax->datum #'3)

3

> (syntax->datum #'"three")

"three"

> (syntax->datum #'#t)

#t

procedure

(datum->syntax ctxt v [srcloc prop ignored])  syntax?

  ctxt : (or/c syntax? #f)
  v : any/c
  srcloc : 
(or/c #f
      syntax?
      srcloc?
      (list/c any/c
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f)
              (or/c exact-positive-integer? #f)
              (or/c exact-nonnegative-integer? #f))
      (vector/c any/c
               (or/c exact-positive-integer? #f)
               (or/c exact-nonnegative-integer? #f)
               (or/c exact-positive-integer? #f)
               (or/c exact-nonnegative-integer? #f)))
   = #f
  prop : (or/c syntax? #f) = #f
  ignored : (or/c syntax? #f) = #f
Converts the datum v to a syntax object. +If v is already a syntax object, then there is no conversion, +and v is returned unmodified. +The contents of pairs, vectors, and boxes, the fields of prefab +structures, and the values of immutable hash tables are recursively converted. +The keys of prefab structures and the keys of immutable hash tables are +not converted. Mutable vectors and boxes are replaced by immutable vectors and +boxes. For any kind of value other than a +pair, vector, box, immutable hash table, immutable +prefab structure, or syntax object, conversion means +wrapping the value with lexical information, source-location +information, and properties after the value is interned +via datum-intern-literal.

Converted objects in v are given the lexical context +information of ctxt and the source-location information of +srcloc. The resulting immediate syntax object from conversion is given the +properties (see Syntax Object Properties) of prop (even the +hidden ones that would not be visible via syntax-property-symbol-keys); if v +is a pair, vector, box, immutable hash table, or immutable +prefab structure, recursively converted values are not given +properties. If ctxt is tainted, then the resulting syntax object from +datum->syntax is tainted. The code inspector +of ctxt, if any, is compared to the code inspector of the +module for the macro currently being transformed, if any; if both +inspectors are available and if one is the same as or inferior to the +other, then the result syntax has the same/inferior inspector, +otherwise it has no code inspector.

Any of ctxt, srcloc, or prop can be +#f, in which case the resulting syntax has no lexical +context, source information, and/or new properties.

If srcloc is not #f, a srcloc instance, or a +syntax object, it must be a list or vector of five elements +that correspond to srcloc fields.

Graph structure is not preserved by the conversion of v to a +syntax object. Instead, v is essentially unfolded into +a tree. If v has a cycle through pairs, vectors, boxes, +immutable hash tables, and immutable prefab structures, +then the exn:fail:contract exception is raised.

The ignored argument is allowed for backward compatibility +and has no effect on the returned syntax object.

Changed in version 8.2.0.5 of package base: Allow a srcloc value as a +srcloc argument.

procedure

(syntax-binding-set? v)  boolean?

  v : any/c

procedure

(syntax-binding-set)  syntax-binding-set?

procedure

(syntax-binding-set->syntax binding-set    
  datum)  syntax?
  binding-set : syntax-binding-set?
  datum : any/c

procedure

(syntax-binding-set-extend 
  binding-set 
  symbol 
  phase 
  mpi 
  [#:source-symbol source-symbol 
  #:source-phase source-phase 
  #:nominal-module nominal-mpi 
  #:nominal-phase nominal-phase 
  #:nominal-symbol nominal-symbol 
  #:nominal-require-phase nominal-require-phase 
  #:inspector inspector]) 
  syntax-binding-set?
  binding-set : syntax-binding-set?
  symbol : symbol?
  phase : (or/c exact-integer? #f)
  mpi : module-path-index?
  source-symbol : symbol? = symbol
  source-phase : (or/c exact-integer? #f) = phase
  nominal-mpi : module-path-index? = mpi
  nominal-phase : (or/c exact-integer? #f) = source-phase
  nominal-symbol : symbol? = source-symbol
  nominal-require-phase : (or/c exact-integer? #f) = 0
  inspector : (or/c inspector? #f) = #f
A syntax binding set supports explicit construction of +binding information for a syntax object. Start by creating an empty +binding set with syntax-binding-set, add bindings with +syntax-binding-set-extend, and create a syntax object that has the +bindings as its lexical information using +syntax-binding-set->syntax.

The first three arguments to syntax-binding-set-extend +establish a binding of symbol at phase to an +identifier that is defined in the module referenced by mpi. +Supply source-symbol to make the binding of symbol +refer to a different provided variable from mpi, and so on; +the optional arguments correspond to the results of +identifier-binding.

Added in version 7.0.0.12 of package base.

procedure

(datum-intern-literal v)  any/c

  v : any/c
Converts some values to be consistent with an interned result +produced by the default reader in read-syntax mode.

If v is a number, character, string, +byte string, or regular expression, then the result is a +value that is equal? to v and eq? to a +potential result of the default reader. (Note that mutable strings and +byte strings are interned as immutable strings and byte +strings.)

If v is an uninterned or an unreadable symbol, +the result is still v, since an interned symbol would +not be equal? to v.

The conversion process does not traverse compound values. For example, +if v is a pair containing strings, then the strings +within v are not interned.

If v1 and v2 are equal? but not +eq?, then it is possible that (datum-intern-literal v1) will return v1 and—sometime after v1 +becomes unreachable as determined by the garbage collector (see +Garbage Collection)—(datum-intern-literal v2) can still +return v2. In other words, datum-intern-literal +may adopt a given value as an interned representative, but +if a former representative becomes otherwise unreachable, then +datum-intern-literal may adopt a new representative.

procedure

(syntax-shift-phase-level stx shift)  syntax?

  stx : syntax?
  shift : (or/c exact-integer? #f)
Returns a syntax object that is like stx, but with all of its +top-level and module bindings shifted by shift phase +levels. If shift is #f, then only bindings +at phase level 0 are shifted to the label phase level. +If shift is 0, then the result is stx.

procedure

(generate-temporaries stx-pair)  (listof identifier?)

  stx-pair : (or syntax? list?)
Returns a list of identifiers that are distinct from all other +identifiers. The list contains as many identifiers as +stx-pair contains elements. The stx-pair argument +must be a syntax pair that can be flattened into a list. The elements +of stx-pair can be anything, but string, symbol, keyword +(possibly wrapped as syntax), and identifier elements will be embedded +in the corresponding generated name, which is useful for debugging +purposes.

The generated identifiers are built with interned symbols (not +gensyms); see also Printing Compiled Code.

Examples:
> (generate-temporaries '(a b c d))

'(#<syntax a1> #<syntax b2> #<syntax c3> #<syntax d4>)

> (generate-temporaries #'(1 2 3 4))

'(#<syntax temp5> #<syntax temp6> #<syntax temp7> #<syntax temp8>)

> (define-syntax (set!-values stx)
    (syntax-case stx ()
      [(_ (id ...) expr)
       (with-syntax ([(temp ...) (generate-temporaries #'(id ...))])
         #'(let-values ([(temp ...) expr])
             (set! id temp) ... (void)))]))

procedure

(identifier-prune-lexical-context id-stx    
  [syms])  identifier?
  id-stx : identifier?
  syms : (listof symbol?) = (list (syntax-e id-stx))
Returns an identifier with the same binding as id-stx, but +without possibly lexical information from id-stx that does not apply +to the symbols in syms, where even further extension of the +lexical information drops information for other symbols. In +particular, transferring the lexical context via +datum->syntax from the result of this function to a symbol +other than one in syms may produce an identifier with no binding.

Currently, the result is always id-stx exactly. Pruning was +intended primarily as a kind of optimization in a previous version of +Racket, but it is less useful and difficult to implement efficiently +in the current macro expander.

See also quote-syntax/prune.

Changed in version 6.5 of package base: Always return id-stx.

procedure

(identifier-prune-to-source-module id-stx)  identifier?

  id-stx : identifier?
Returns an identifier with its lexical context minimized to that +needed for syntax-source-module. The minimized lexical +context does not include any bindings.

procedure

(syntax-recertify new-stx    
  old-stx    
  inspector    
  key)  syntax?
  new-stx : syntax?
  old-stx : syntax?
  inspector : inspector?
  key : any/c
For backward compatibility only; returns new-stx.

procedure

(syntax-debug-info stx [phase all-bindings?])  hash?

  stx : syntax?
  phase : (or/c exact-integer? #f) = (syntax-local-phase-level)
  all-bindings? : any/c = #f
Produces a hash table that describes the lexical information of +stx (not counting components when (syntax-e stx) +would return a compound value). The result can include—but is not +limited to—the following keys:

  • 'name the result of (syntax-e stx), if it is a symbol.

  • 'context a list of vectors, where each vector represents a scope +attached to stx.

    Each vector starts with a number that is distinct for every +scope. A symbol afterward provides a hint at the scope’s +origin: 'module for a module scope, +'macro for a macro-introduction scope, +'use-site for a macro use-site scope, or +'local for a local binding form. In the case of a +'module scope that corresponds to the inside edge, the +module’s name and a phase (since an inside-edge scope is +generated for each phase) are shown.

  • 'bindings a list of bindings, each represented by +a hash table. A binding table can include—but is not limited +to—the following keys:

    • 'name the symbolic name for the binding.

    • 'context the scopes, as a list of vectors, +for the binding.

    • 'local a symbol representing a local binding; +when this key is present, 'module is absent.

    • 'module an encoding of a import from another module; +when this key is present, 'local is absent.

    • 'free-identifier=? a hash table of debugging information +from an identifier for which the binding is an alias.

  • 'fallbacks a list of hash tables like the one +produced by syntax-debug-info for cross-namespace binding fallbacks.

Added in version 6.3 of package base.

12.2.1 Syntax Object Source Locations

The bindings documented in this section are provided by the racket/syntax-srcloc library, not racket/base or racket.

procedure

(syntax-srcloc stx)  (or/c #f srcloc?)

  stx : syntax?
Returns the source location for the syntax object +stx, or #f if none is known.

Added in version 8.2.0.5 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stxparam.html b/clones/docs.racket-lang.org/reference/stxparam.html new file mode 100644 index 00000000..c547d730 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stxparam.html @@ -0,0 +1,50 @@ + +12.5 Syntax Parameters

12.5 Syntax Parameters

The bindings documented in this section are provided by the racket/stxparam library, not racket/base or racket.

syntax

(define-syntax-parameter id expr)

Binds id as syntax to a syntax +parameter. The expr is an expression in the +transformer environment that serves as the default value for +the syntax parameter. The value is typically obtained by a transformer +using syntax-parameter-value.

The id can be used with syntax-parameterize +or syntax-parameter-value (in a transformer). If +expr produces a procedure of one argument or a +make-set!-transformer result, then id can be +used as a macro. If expr produces a +make-rename-transformer result, then id can be +used as a macro that expands to a use of the target identifier, but +syntax-local-value of id does not produce +the target’s value.

Examples:
> (define-syntax-parameter current-class #f)
> (define-syntax-parameter yield (make-rename-transformer #'abort))
> (define-syntax-parameter define/public
    (λ (stx)
      (raise-syntax-error #f "use of a class keyword not in a class" stx)))
> (begin-for-syntax (displayln (syntax-parameter-value #'current-class)))

#f

> (yield 5)

5

syntax

(syntax-parameterize ([id expr] ...) body-expr ...+)

Each id must be bound to a syntax parameter using +define-syntax-parameter. Each expr is an expression +in the transformer environment. During the expansion of the +body-exprs, the value of each expr is bound to the +corresponding id.

If an expr produces a procedure of one argument or a +make-set!-transformer result, then its id +can be used as a macro during the expansion of the +body-exprs. If expr produces a +make-rename-transformer result, then id can be +used as a macro that expands to a use of the target identifier, but +syntax-local-value of id does not produce +the target’s value.

Examples:
> (define-syntax-parameter abort (syntax-rules ()))
> (define-syntax forever
    (syntax-rules ()
      [(forever body ...)
       (call/cc (lambda (abort-k)
         (syntax-parameterize
             ([abort (syntax-rules () [(_) (abort-k)])])
           (let loop () body ... (loop)))))]))
> (define-syntax-parameter it (syntax-rules ()))
> (define-syntax aif
    (syntax-rules ()
      [(aif test then else)
       (let ([t test])
         (syntax-parameterize ([it (syntax-id-rules () [_ t])])
           (if t then else)))]))

Binds id as syntax to a syntax parameter that must +be bound to a make-rename-transformer result and, unlike +define-syntax-parameter, syntax-local-value of +id does produce the target’s value, including inside +of syntax-parameterize.

Examples:
> (define-syntax (test stx)
   (syntax-case stx ()
     [(_ t)
      #`#,(syntax-local-value #'t)]))
> (define-syntax one 1)
> (define-syntax two 2)
> (define-syntax-parameter not-num
    (make-rename-transformer #'one))
> (test not-num)

#<procedure:syntax-parameter>

> (define-rename-transformer-parameter num
    (make-rename-transformer #'one))
> (test num)

1

> (syntax-parameterize ([num (make-rename-transformer #'two)])
    (test num))

2

Added in version 6.3.0.14 of package base.

12.5.1 Syntax Parameter Inspection

 (require racket/stxparam-exptime) package: base

procedure

(syntax-parameter-value id-stx)  any

  id-stx : syntax?
This procedure is intended for use in a transformer +environment, where id-stx is an identifier bound in the +normal environment to a syntax parameter. The result is the current +value of the syntax parameter, as adjusted by +syntax-parameterize form.

This binding is provided for-syntax by +racket/stxparam, since it is normally used in a +transformer. It is provided normally by +racket/stxparam-exptime.

procedure

(make-parameter-rename-transformer id-stx)  any

  id-stx : syntax?
This procedure is intended for use in a transformer, where +id-stx is an identifier bound to a syntax parameter. The +result is a transformer that behaves as id-stx, but that cannot +be used with syntax-parameterize or +syntax-parameter-value.

Using make-parameter-rename-transformer is analogous to +defining a procedure that calls a parameter. Such a procedure can be +exported to others to allow access to the parameter value, but not to +change the parameter value. Similarly, +make-parameter-rename-transformer allows a syntax parameter +to be used as a macro, but not changed.

The result of make-parameter-rename-transformer is not +treated specially by syntax-local-value, unlike the result +of make-rename-transformer.

This binding is provided for-syntax by +racket/stxparam, since it is normally used in a +transformer. It is provided normally by +racket/stxparam-exptime.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stxprops.html b/clones/docs.racket-lang.org/reference/stxprops.html new file mode 100644 index 00000000..e9f15365 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stxprops.html @@ -0,0 +1,110 @@ + +12.7 Syntax Object Properties

12.7 Syntax Object Properties

Every syntax object has an associated syntax property list, +which can be queried or extended with +syntax-property. A property is set as +preserved or not; a preserved property is +maintained for a syntax object in a compiled form that is marshaled to a byte +string or ".zo" file, and other properties are discarded when +marshaling.

In read-syntax, the reader attaches a preserved 'paren-shape +property to any pair or vector syntax object generated from parsing a +pair [ and ] or { and +}; the property value is #\[ in the former case, +and #\{ in the latter case. The syntax form copies +any 'paren-shape property from the source of a template to +corresponding generated syntax.

Both the syntax input to a transformer and the syntax result of a +transformer may have associated properties. The two sets of properties +are merged by the syntax expander: each property in the original and +not present in the result is copied to the result, and the values of +properties present in both are combined with cons (result +value first, original value second) and the consed value is +preserved if either of the values were +preserved.

Before performing the merge, however, the syntax expander +automatically adds a property to the original syntax object using the +key 'origin. If the source syntax has no +'origin property, it is set to the empty list. Then, still +before the merge, the identifier that triggered the macro expansion +(as syntax) is consed onto the 'origin +property so far. The 'origin property thus records (in +reverse order) the sequence of macro expansions that produced an +expanded expression. Usually, the 'origin value is a +list of identifiers, but a transformer might return +syntax that has already been expanded, in which case an +'origin list can contain other lists after a merge. The +syntax-track-origin procedure implements this tracking. +The 'origin property is added as +non-preserved.

Besides 'origin tracking for general macro expansion, +Racket adds properties to expanded syntax (often using +syntax-track-origin) to record additional expansion details:

  • When a begin form is spliced into a sequence with +internal definitions (see Internal Definitions), +syntax-track-origin is applied to every spliced element from +the begin body. The second argument to +syntax-track-origin is the begin form, and the +third argument is the begin keyword (extracted from the +spliced form).

  • When an internal define-values or +define-syntaxes form is converted into a +letrec-syntaxes+values form (see Internal Definitions), +syntax-track-origin is applied to each generated binding +clause. The second argument to syntax-track-origin is the +converted form, and the third argument is the define-values +or define-syntaxes keyword form the converted form.

  • When a letrec-syntaxes+values expression is fully +expanded, syntax bindings disappear, and the result is either a +letrec-values form (if the unexpanded form contained +non-syntax bindings), or only the body of the +letrec-syntaxes+values form (wrapped with begin if +the body contained multiple expressions). To record the disappeared +syntax bindings, a property is added to the expansion result: an +immutable list of identifiers from the disappeared bindings, as a +'disappeared-binding property.

  • When a subtyping struct form is expanded, the +identifier used to reference the base type does not appear in the +expansion. Therefore, the struct transformer adds the +identifier to the expansion result as a +'disappeared-use property.

  • When a rename transformer is used to replace a +set! target, syntax-track-origin is used on the +target identifier (the same as when the identifier is used as an +expression).

  • When a reference to an unexported or protected identifier from +a module is discovered, the 'protected property is +added to the identifier with a #t value.

  • When read-syntax +generates a syntax object, it attaches a property to the object +(using a private key) to mark the object as originating from a +read. The syntax-original? predicate looks for the property +to recognize such syntax objects. (See Syntax Object Content for more +information. The property is not transferred by the expander from +a macro transformer input to its output or by syntax-track-origin.)

See also Check Syntax +for one client of the 'disappeared-use and 'disappeared-binding +properties.

See Information on Expanded Modules for information about properties generated +by the expansion of a module declaration. See lambda and +Inferred Value Names for information about properties recognized +when compiling a procedure. See current-compile for +information on properties and byte codes.

procedure

(syntax-property stx key v [preserved?])  syntax?

  stx : syntax?
  key : (if preserved? (and/c symbol? symbol-interned?) any/c)
  v : any/c
  preserved? : any/c = (eq? key 'paren-shape)
(syntax-property stx key)  any
  stx : syntax?
  key : any/c
The three- or four-argument form extends stx by associating +an arbitrary property value v with the key key; the +result is a new syntax object with the association (while stx +itself is unchanged). The property is added as +preserved if preserved? is true, in +which case key must be an interned symbol, and v +should be a value as described below that can be saved in marshaled bytecode.

The two-argument form returns an arbitrary property value associated +to stx with the key key, or #f if no value +is associated to stx for key. If stx is tainted, +then syntax objects with the result value are tainted.

To support marshaling to bytecode, a value for a preserved syntax +property must be a non-cyclic value that is either

  • a pair containing allowed preserved-property values;

  • a vector (unmarshaled as immutable) containing allowed preserved-property values;

  • a box (unmarshaled as immutable) containing allowed preserved-property values;

  • an immutable prefab structure containing allowed preserved-property values;

  • an immutable hash table whose keys and values are allowed preserved-property values;

  • a syntax object; or

  • an empty list, symbol, number, character, +string, byte string, or regexp +value.

Any other value for a preserved property triggers an exception at an +attempt to marshal the owning syntax object to bytecode form.

Changed in version 6.4.0.14 of package base: Added the preserved? argument.

procedure

(syntax-property-remove stx key)  syntax?

  stx : syntax?
  key : any/c
Returns a syntax object like stx, but without a property (if +any) for key.

Added in version 6.90.0.20 of package base.

procedure

(syntax-property-preserved? stx key)  boolean?

  stx : syntax?
  key : (and/c symbol? symbol-interned?)
Returns #t if stx has a +preserved property value for key, +#f otherwise.

Added in version 6.4.0.14 of package base.

procedure

(syntax-property-symbol-keys stx)  list?

  stx : syntax?
Returns a list of all symbols that as keys have associated properties +in stx. Uninterned symbols (see Symbols) +are not included in the result list.

procedure

(syntax-track-origin new-stx    
  orig-stx    
  id-stx)  any
  new-stx : syntax?
  orig-stx : syntax?
  id-stx : identifier?
Adds properties to new-stx in the same way that macro +expansion adds properties to a transformer result. In particular, it +merges the properties of orig-stx into new-stx, +first adding id-stx as an 'origin property and removing +the property recognized by syntax-original?, and it +returns the property-extended syntax object. Use the +syntax-track-origin procedure in a macro transformer that +discards syntax (corresponding to orig-stx with a keyword +id-stx) leaving some other syntax in its place (corresponding +to new-stx).

For example, the expression

(or x y)

expands to

(let ([or-part x]) (if or-part or-part (or y)))

which, in turn, expands to

(let-values ([(or-part) x]) (if or-part or-part y))

The syntax object for the final expression will have an +'origin property whose value is (list (quote-syntax let) (quote-syntax or)).

Changed in version 7.0 of package base: Included the syntax-original? +property among the ones transferred to +new-stx.
Changed in version 8.2.0.7: Corrected back to removing the syntax-original? +property from the set transferred to +new-stx.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/stxtrans.html b/clones/docs.racket-lang.org/reference/stxtrans.html new file mode 100644 index 00000000..94b1b0f0 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/stxtrans.html @@ -0,0 +1,729 @@ + +12.4 Syntax Transformers
On this page:
set!-transformer?
make-set!-transformer
set!-transformer-procedure
prop:  set!-transformer
rename-transformer?
make-rename-transformer
rename-transformer-target
prop:  rename-transformer
local-expand
syntax-local-expand-expression
local-transformer-expand
local-expand/  capture-lifts
local-transformer-expand/  capture-lifts
syntax-local-apply-transformer
internal-definition-context?
syntax-local-make-definition-context
internal-definition-context-add-scopes
internal-definition-context-splice-binding-identifier
syntax-local-bind-syntaxes
internal-definition-context-binding-identifiers
internal-definition-context-introduce
internal-definition-context-seal
identifier-remove-from-definition-context
prop:  expansion-contexts
syntax-local-value
syntax-local-value/  immediate
syntax-local-lift-expression
syntax-local-lift-values-expression
syntax-local-lift-context
syntax-local-lift-module
syntax-local-lift-module-end-declaration
syntax-local-lift-require
syntax-local-lift-provide
syntax-local-name
syntax-local-context
syntax-local-phase-level
syntax-local-module-exports
syntax-local-submodules
syntax-local-module-interned-scope-symbols
syntax-local-get-shadower
syntax-local-make-delta-introducer
syntax-local-certifier
syntax-transforming?
syntax-transforming-with-lifts?
syntax-transforming-module-expression?
syntax-local-identifier-as-binding
syntax-local-introduce
make-syntax-introducer
make-interned-syntax-introducer
make-syntax-delta-introducer
syntax-local-transforming-module-provides?
syntax-local-module-defined-identifiers
syntax-local-module-required-identifiers
prop:  liberal-define-context
liberal-define-context?
12.4.1 require Transformers
expand-import
make-require-transformer
prop:  require-transformer
require-transformer?
import
import-source
current-require-module-path
convert-relative-module-path
syntax-local-require-certifier
12.4.2 provide Transformers
expand-export
pre-expand-export
make-provide-transformer
make-provide-pre-transformer
prop:  provide-transformer
prop:  provide-pre-transformer
provide-transformer?
provide-pre-transformer?
export
syntax-local-provide-certifier
12.4.3 Keyword-Argument Conversion Introspection
syntax-procedure-alias-property
syntax-procedure-converted-arguments-property
12.4.4 Portal Syntax Bindings
portal-syntax?
make-portal-syntax
portal-syntax-content

12.4 Syntax Transformers

procedure

(set!-transformer? v)  boolean?

  v : any/c
Returns #t if v is a value created by +make-set!-transformer or an instance of a structure type with +the prop:set!-transformer property, #f otherwise.

procedure

(make-set!-transformer proc)  set!-transformer?

  proc : (syntax? . -> . syntax?)
Creates an assignment transformer that cooperates with +set!. If the result of make-set!-transformer is +bound to id as a transformer binding, then +proc is applied as a transformer when id is +used in an expression position, or when it is used as the target of a +set! assignment as (set! id expr). When the +identifier appears as a set! target, the entire set! +expression is provided to the transformer.

Example:
> (let ([x 1]
        [y 2])
    (let-syntax ([x (make-set!-transformer
                      (lambda (stx)
                        (syntax-case stx (set!)
                          ; Redirect mutation of x to y
                          [(set! id v) #'(set! y v)]
                          ; Normal use of x really gets x
                          [id (identifier? #'id)  #'x])))])
      (begin
        (set! x 3)
        (list x y))))

'(1 3)

procedure

(set!-transformer-procedure transformer)

  (syntax? . -> . syntax?)
  transformer : set!-transformer?
Returns the procedure that was passed to +make-set!-transformer to create transformer or that +is identified by the prop:set!-transformer property of +transformer.

A structure type property to identify structure types that act +as assignment transformers like the ones created by +make-set!-transformer.

The property value must be an exact integer or procedure of one or two +arguments. In the former case, the integer designates a field within +the structure that should contain a procedure; the integer must be +between 0 (inclusive) and the number of non-automatic fields +in the structure type (exclusive, not counting supertype fields), and +the designated field must also be specified as immutable.

If the property value is a procedure of one argument, then the +procedure serves as a syntax transformer and for set! +transformations. If the property value is a procedure of two +arguments, then the first argument is the structure whose type has +prop:set!-transformer property, and the second argument is a +syntax object as for a syntax transformer and for set! +transformations; set!-transformer-procedure applied to the +structure produces a new function that accepts just the syntax object +and calls the procedure associated through the property. Finally, if the +property value is an integer, the target identifier is extracted from +the structure instance; if the field value is not a procedure of one +argument, then a procedure that always calls +raise-syntax-error is used, instead.

If a value has both the prop:set!-transformer and +prop:rename-transformer properties, then the latter takes +precedence. If a structure type has the prop:set!-transformer +and prop:procedure properties, then the former takes +precedence for the purposes of macro expansion.

procedure

(rename-transformer? v)  boolean?

  v : any/c
Returns #t if v is a value created by +make-rename-transformer or an instance of a structure type +with the prop:rename-transformer property, #f +otherwise.

Examples:
> (rename-transformer? (make-rename-transformer #'values))

#t

> (rename-transformer? 'not-a-rename-transformer)

#f

procedure

(make-rename-transformer id-stx)  rename-transformer?

  id-stx : syntax?
Creates a rename transformer that, when used as a +transformer binding, acts as a transformer that inserts the +identifier id-stx in place of whatever identifier binds the +transformer, including in non-application positions, in set! +expressions.

Such a transformer could be written manually, but the one created by +make-rename-transformer triggers special cooperation with the +parser and other syntactic forms when id is bound to the +rename transformer:

  • The parser installs a free-identifier=? and +identifier-binding equivalence between id +and id-stx, as long as id-stx does not have +a true value for the 'not-free-identifier=? +syntax property.

  • A provide of id provides the binding +indicated by id-stx instead of id, as long +as id-stx does not have a true value for the +'not-free-identifier=? syntax property +and as long as id-stx has a binding.

  • If provide exports id, it uses a +symbol-valued 'nominal-id property of +id-stx to specify the “nominal source identifier” of +the binding as reported by identifier-binding.

  • If id-stx has a true value for the +'not-provide-all-defined syntax +property, then id (or its target) is not exported by +all-defined-out.

  • The syntax-local-value function recognizes +rename-transformer bindings and consult their targets.

Examples:
> (define-syntax my-or (make-rename-transformer #'or))
> (my-or #f #t)

#t

> (free-identifier=? #'my-or #'or)

#t

Changed in version 6.3 of package base: Removed an optional second argument.
Changed in version 7.4.0.10: Adjust rename-transformer expansion +to add a macro-introduction scope, the +same as regular macro expansion.

procedure

(rename-transformer-target transformer)  identifier?

  transformer : rename-transformer?
Returns the identifier passed to make-rename-transformer to +create transformer or as indicated by a +prop:rename-transformer property on transformer.

Example:

A structure type property to identify structure types that act +as rename transformers like the ones created by +make-rename-transformer.

The property value must be an exact integer, an identifier +syntax object, or a procedure that takes one argument. +In the former case, the integer designates a +field within the structure that should contain an identifier; the +integer must be between 0 (inclusive) and the number of +non-automatic fields in the structure type (exclusive, not counting +supertype fields), and the designated field must also be specified as +immutable.

If the property value is an identifier, the identifier serves as the +target for renaming, just like the first argument to +make-rename-transformer. If the property value is an integer, +the target identifier is extracted from the structure instance; if the +field value is not an identifier, then an identifier ? +with an empty context is used, instead.

If the property value is a procedure that takes one argument, then the +procedure is called to obtain the identifier that the rename +transformer will use as a target identifier. The returned identifier +should probably have the 'not-free-identifier=? syntax +property. If the procedure returns any value that is not an +identifier, the exn:fail:contract exception is raised.

Examples:
; Example of a procedure argument for prop:rename-transformer
> (define-syntax slv-1 'first-transformer-binding)
> (define-syntax slv-2 'second-transformer-binding)
> (begin-for-syntax
    (struct slv-cooperator (redirect-to-first?)
      #:property prop:rename-transformer
      (λ (inst)
        (if (slv-cooperator-redirect-to-first? inst)
            #'slv-1
            #'slv-2))))
> (define-syntax (slv-lookup stx)
    (syntax-case stx ()
      [(_ id)
       #`'#,(syntax-local-value #'id)]))
> (define-syntax slv-inst-1 (slv-cooperator #t))
> (define-syntax slv-inst-2 (slv-cooperator #f))
> (slv-lookup slv-inst-1)

'first-transformer-binding

> (slv-lookup slv-inst-2)

'second-transformer-binding

Changed in version 6.3 of package base: the property now accepts a procedure of one argument.

procedure

(local-expand stx    
  context-v    
  stop-ids    
  [intdef-ctx])  syntax?
  stx : any/c
  context-v : (or/c 'expression 'top-level 'module 'module-begin list?)
  stop-ids : (or/c (listof identifier?) empty #f)
  intdef-ctx : 
(or/c internal-definition-context?
      #f
      (listof internal-definition-context?))
 = #f
Expands stx in the lexical context of the expression +currently being expanded. The context-v argument is used as +the result of syntax-local-context for immediate expansions; +a list indicates an internal-definition context, and more +information on the form of the list is below. If stx is not +already a syntax object, it is coerced with +(datum->syntax #f stx) before expansion.

The stop-ids argument controls how far local-expand expands stx:

  • If stop-ids is an empty list, then stx is recursively expanded (i.e. +expansion proceeds to sub-expressions). The result is guaranteed to be a fully-expanded form, +which can include the bindings listed in Fully Expanded Programs, plus #%expression +in any expression position.

  • If stop-ids is a list containing just module*, then expansion proceeds as if +stop-ids were an empty list, except that expansion does not recur to submodules +defined with module* (which are left unexpanded in the result).

  • If stop-ids is any other list, then begin, quote, set!, +#%plain-lambda, case-lambda, let-values, letrec-values, +if, begin0, with-continuation-mark, letrec-syntaxes+values, +#%plain-app, #%expression, #%top, and #%variable-reference +are implicitly added to stop-ids. Expansion proceeds recursively, stopping when the +expander encounters any of the forms in stop-ids, and the result is the +partially-expanded form.

    When the expander would normally implicitly introduce a #%app, #%datum, +or #%top identifier as described in Expansion Steps, it checks to see if an +identifier with the same binding as the one to be introduced appears in +stop-ids. If so, the identifier is not introduced; the result of expansion is +the bare application, literal data expression, or unbound identifier rather than one wrapped in +the respective explicit form.

    When #%plain-module-begin is not in stop-ids, the +#%plain-module-begin transformer detects and expands sub-forms (such as +define-values) regardless of the identifiers presence in stop-ids.

    Expansion does not replace the scopes in a local-variable +reference to match the binding identifier.

  • If stop-ids is #f instead of a list, then stx is expanded only as +long as the outermost form of stx is a macro (i.e. expansion does not proceed +to sub-expressions, and it does not replace the scopes in a local-variable reference to match the +binding identifier). The #%app, #%datum, and #%top identifiers are +never introduced.

Independent of stop-ids, when local-expand encounters an identifier that has a local +binding but no binding in the current expansion context, the variable is left as-is (as opposed to +triggering an “out of context” syntax error).

When context-v is 'module-begin, and the result of +expansion is a #%plain-module-begin form, then a +'submodule syntax property is added to each enclosed +module form (but not module* forms) in the same way as by +module expansion.

If the intdef-ctx argument is an internal-definition context, its bindings and +bindings from all parent internal-definition contexts are added to the +local binding context during the dynamic extent of the call to local-expand. +Additionally, unless #f was provided for the add-scope? argument to +syntax-local-make-definition-context when the internal-definition context was created, +its inside-edge scope (but not the scopes of any parent internal-definition contexts) is +added to the lexical information for both stx prior to its expansion and the expansion +result (because the expansion might introduce bindings or references to internal-definition bindings).

For backwards compatibility, when intdef-ctx is a list all bindings from all of the provided internal-definition +contexts and their parents are added to the local binding context, and the inside-edge scope from +each context for which add-scope? was not #f is added in the same way.

Expansion records use-site scopes for removal from definition bindings. When the +intdef-ctx argument is an internal-definition context, use-site scopes are recorded +with that context. When intdef-ctx is #f or (for backwards compatibility) a list, +use-site scopes are recorded with the current expand context.

For a particular internal-definition context, generate a unique +value and put it into a list for context-v. To allow +liberal expansion of define forms, the generated value +should be an instance of a structure with a true value for +prop:liberal-define-context. If the internal-definition +context is meant to be self-contained, the list for context-v +should contain only the generated value; if the internal-definition +context is meant to splice into an immediately enclosing context, then +when syntax-local-context produces a list, cons the +generated value onto that list.

When expressions are expanded via local-expand with an +internal-definition context intdef-ctx, and when the expanded +expressions are incorporated into an overall form new-stx, +then typically internal-definition-context-track should be +applied to intdef-ctx and new-stx to provide +expansion history to external tools.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Examples:
> (define-syntax-rule (do-print x ...)
    (printf x ...))
> (define-syntax-rule (hello x)
    (do-print "hello ~a" x))
> (define-syntax (show stx)
    (syntax-case stx ()
      [(_ x)
       (let ([partly (local-expand #'(hello x)
                                   'expression
                                   (list #'do-print))]
             [fully (local-expand #'(hello x)
                                  'expression
                                  #f)])
         (printf "partly expanded: ~s\n" (syntax->datum partly))
         (printf "fully expanded: ~s\n" (syntax->datum fully))
         fully)]))
> (show 1)

partly expanded: (do-print "hello ~a" 1)

fully expanded: (printf "hello ~a" 1)

hello 1

This procedure’s binding is provided as +protected in the sense of protect-out.

Changed in version 6.0.1.3 of package base: Changed treatment of #%top +so that it is never introduced as +an explicit wrapper.
Changed in version 6.0.90.27: Loosened the contract on the intdef-ctx argument to +allow an empty list.
Changed in version 8.2.0.4: Changined binding to protected.

procedure

(syntax-local-expand-expression stx 
  [opaque-only?]) 
  
(if opaque-only? #f syntax?) syntax?
  stx : any/c
  opaque-only? : any/c = #f
Like local-expand given 'expression and an empty +stop list, but with two results: a syntax object for the fully +expanded expression, and a syntax object whose content is opaque.

The latter can be used in place of the former (perhaps in a larger +expression produced by a macro transformer), and when the macro +expander encounters the opaque object, it substitutes the fully +expanded expression without re-expanding it; the +exn:fail:syntax exception is raised if the expansion context includes +scopes that were not present for the original expansion, in +which case re-expansion might produce different results. Consistent +use of syntax-local-expand-expression and the opaque object +thus avoids quadratic expansion times when local expansions are +nested.

If opaque-only? is true, then the first result is #f +instead of the expanded expression. Obtaining only the second, opaque +result can be more efficient in some expansion contexts.

Unlike local-expand, syntax-local-expand-expression +normally produces an expanded expression that contains no +#%expression forms. However, if +syntax-local-expand-expression is used within an expansion +that is triggered by an enclosing local-expand call, then the +result of syntax-local-expand-expression can include +#%expression forms.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.
This procedure’s binding is provided as +protected in the sense of protect-out.

Changed in version 6.90.0.13 of package base: Added the opaque-only? argument.
Changed in version 8.2.0.4: Changined binding to protected.

procedure

(local-transformer-expand stx    
  context-v    
  stop-ids    
  [intdef-ctx])  syntax?
  stx : any/c
  context-v : (or/c 'expression 'top-level list?)
  stop-ids : (or/c (listof identifier?) #f)
  intdef-ctx : 
(or/c internal-definition-context?
      #f
      (listof internal-definition-context?))
 = #f
Like local-expand, but stx is expanded as a +transformer expression instead of a run-time expression.

Any lifted expressions—from calls to +syntax-local-lift-expression during the expansion of +stxare captured in the result. If context-v is +'top-level, then lifts are captured in a begin form, +otherwise lifts are captured in let-values forms. If no +expressions are lifted during expansion, then no begin +or let-values wrapper is added.

This procedure’s binding is provided as +protected in the sense of protect-out.

Changed in version 6.5.0.3 of package base: Allow and capture lifts in a +'top-level context.
Changed in version 8.2.0.4: Changined binding to protected.

procedure

(local-expand/capture-lifts stx    
  context-v    
  stop-ids    
  [intdef-ctx    
  lift-ctx])  syntax?
  stx : any/c
  context-v : (or/c 'expression 'top-level 'module 'module-begin list?)
  stop-ids : (or/c (listof identifier?) #f)
  intdef-ctx : 
(or/c internal-definition-context?
      #f
      (listof internal-definition-context?))
 = #f
  lift-ctx : any/c = (gensym 'lifts)
Like local-expand, but the result is a syntax object that +represents a begin expression. Lifted expressions—from +calls to syntax-local-lift-expression during the expansion of +stxappear with their identifiers in define-values +forms, and the expansion of stx is the last expression in the +begin. The lift-ctx value is reported by +syntax-local-lift-context during local expansion. The lifted +expressions are not expanded, but instead left as provided in the +begin form.

If context-v is 'top-level or 'module, then +module forms can appear in the result as added via +syntax-local-lift-module. If context-v is +'module, then module* forms can appear, too.

This procedure’s binding is provided as +protected in the sense of protect-out.

Changed in version 8.2.0.4 of package base: Changined binding to protected.

procedure

(local-transformer-expand/capture-lifts stx    
  context-v    
  stop-ids    
  [intdef-ctx    
  lift-ctx])  syntax?
  stx : any/c
  context-v : (or/c 'expression 'top-level list?)
  stop-ids : (or/c (listof identifier?) #f)
  intdef-ctx : 
(or/c internal-definition-context?
      #f
      (listof internal-definition-context?))
 = #f
  lift-ctx : any/c = (gensym 'lifts)
Like local-expand/capture-lifts, but stx is expanded +as a transformer expression instead of a run-time expression. Lifted +expressions are reported as define-values forms (in the +transformer environment).

This procedure’s binding is provided as +protected in the sense of protect-out.

Changed in version 8.2.0.4 of package base: Changined binding to protected.

procedure

(syntax-local-apply-transformer transformer    
  binding-id    
  context-v    
  intdef-ctx    
  v ...)  any
  transformer : procedure?
  binding-id : (or/c identifier? #f)
  context-v : (or/c 'expression 'top-level 'module 'module-begin list?)
  intdef-ctx : (or/c internal-definition-context? #f)
  v : any/c
Applies the procedure transformer to the vs in a new +expansion context and local binding context. Adds and flips +macro-introduction scopes and use-site scopes on the arguments +and return values in the same manner as syntax transformer application. +The arguments and returns may be any value; scopes are manipulated only for +those that are syntax objects.

The context-v argument is as in local-expand, and the +intdef-ctx is an internal-definition context value or +#f. The binding-id specifies a binding associated with +the transformer, which the expander uses to determine whether to add +use-site scopes and which code inspector to use during +expansion.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Added in version 8.2.0.7 of package base.

procedure

(internal-definition-context? v)  boolean?

  v : any/c
Returns #t if v is an internal-definition +context, #f otherwise.

procedure

(syntax-local-make-definition-context [parent-ctx 
  add-scope?]) 
  internal-definition-context?
  parent-ctx : (or/c internal-definition-context? #f) = #f
  add-scope? : any/c = #t
Creates an opaque internal-definition context value to be used with local-expand and +other functions. A transformer should create one context for each set of internal definitions to be +expanded.

Before expanding forms whose lexical context should include the definitions, the transformer +should use internal-definition-context-add-scopes to apply the context’s scopes to the syntax. +Calls to procedures such as local-expand to expand the forms should +provide the internal-definition context value as an argument.

After discovering an internal define-values or define-syntaxes form, use +syntax-local-bind-syntaxes to add bindings to the context.

An internal-definition context internally creates an outside-edge +scope and an inside-edge scope to represent the context. The +inside-edge scope is added to any form that is expanded within the +context or that appears as the result of a (partial) expansion within the +context. For backward compatibility, providing #f for +add-scope? disables this behavior.

If parent-ctx is not #f, then parent-ctx is made the parent +internal-definition context for the new internal-definition context. Whenever the new context’s +bindings are added to the local binding context (e.g. by providing the context to +local-expand, syntax-local-bind-syntaxes, or syntax-local-value), then the +bindings from parent-ctx are also added as well. If parent-ctx was also created with a +parent internal-definition context, bindings from its parent are also added, and so on +recursively. Note that the scopes of parent contexts are not added implicitly, only the +bindings, even when the inside-edge scope of the child context would be implicitly added. If the +scopes of parent definition contexts should be added, the parent contexts must be provided +explicitly.

Additionally, if the created definition context is intended to be spliced into a surrounding +definition context, the surrounding context should always be provided for the parent-ctx +argument to ensure the necessary use-site scopes are added to macros expanded in the context. +Otherwise, expansion of nested definitions can be inconsistent with the expansion of definitions in +the surrounding context.

An internal-definition context also tracks use-site scopes created during expansion +within the definition context, so that they can be removed from bindings created in the context, +at syntax-local-identifier-as-binding, and at internal-definition-context-splice-binding-identifier.

The scopes associated with a new definition context are pruned from +quote-syntax forms only when it is created during the dynamic +extent of a syntax transformer application or in a +begin-for-syntax form (potentially nested) within a module +being expanded.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Changed in version 6.3 of package base: Added the add-scope? argument, +and made calling +internal-definition-context-seal +no longer necessary.
Changed in version 8.2.0.7: Added the outside-edge scope and use-site scope +tracking behaviors.

procedure

(internal-definition-context-add-scopes intdef-ctx    
  stx)  syntax?
  intdef-ctx : internal-definition-context?
  stx : syntax?
Adds the outside-edge scope and inside-edge scope for +intdef-ctx to stx.

Use this function to apply the definition context scopes to syntax that +originates within the definition context before expansion.

Added in version 8.2.0.7 of package base.

procedure

(internal-definition-context-splice-binding-identifier 
  intdef-ctx 
  id) 
  syntax?
  intdef-ctx : internal-definition-context?
  id : identifier?
Removes scopes associated with the intdef-ctx from id: the +outside-edge scope, the inside-edge scope, and use-site +scopes created by expansions within the definition context.

Use when splicing a binding originating within the intdef-ctx into a +surrounding context.

Added in version 8.2.0.7 of package base.

procedure

(syntax-local-bind-syntaxes id-list 
  expr 
  intdef-ctx 
  [extra-intdef-ctxs]) 
  (listof identifier?)
  id-list : (listof identifier?)
  expr : (or/c syntax? #f)
  intdef-ctx : internal-definition-context?
  extra-intdef-ctxs : 
(or/c internal-definition-context?
      (listof internal-definition-context?))
   = '()
Binds each identifier in id-list within the +internal-definition context represented by intdef-ctx, where +intdef-ctx is the result of +syntax-local-make-definition-context. +Returns identifiers with lexical information matching the new bindings.

For backwards compatibility, the lexical information of each element of extra-intdef-ctxs +is also added to each identifier in id-list before binding.

Supply #f for +expr when the identifiers correspond to +define-values bindings, and supply a compile-time expression +when the identifiers correspond to define-syntaxes bindings. +In the latter case, the number of values produced by the expression should +match the number of identifiers, otherwise the +exn:fail:contract:arity exception is raised.

When expr is not #f, it is expanded in an expression context and evaluated in +the current transformer environment. In this case, the bindings and lexical +information from both intdef-ctx and extra-intdef-ctxs are used to enrich +expr’s lexical information and extend the local binding context in the same way +as the fourth argument to local-expand. If expr is #f, the value provided +for extra-intdef-ctxs is ignored.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Changed in version 6.90.0.27 of package base: Added the extra-intdef-ctxs argument.
Changed in version 8.2.0.7: Changed the return value from #<void> to the list of bound identifiers.

Returns a list of all binding identifiers registered for +intdef-ctx through syntax-local-bind-syntaxes. Each +identifier in the returned list includes the internal-definition +context’s scope.

Added in version 6.3.0.4 of package base.

procedure

(internal-definition-context-introduce intdef-ctx    
  stx    
  [mode])  syntax?
  intdef-ctx : internal-definition-context?
  stx : syntax?
  mode : (or/c 'flip 'add 'remove) = 'flip
Flips, adds, or removes (depending on mode) the scope +for intdef-ctx for all parts of stx.

This function is provided for backwards compatibility; +internal-definition-context-add-scopes and +internal-definition-context-splice-binding-identifier are preferred.

Added in version 6.3 of package base.

procedure

(internal-definition-context-seal intdef-ctx)  void?

  intdef-ctx : internal-definition-context?
For backward compatibility only; has no effect.

procedure

(identifier-remove-from-definition-context id-stx 
  intdef-ctx) 
  identifier?
  id-stx : identifier?
  intdef-ctx : 
(or/c internal-definition-context?
      (listof internal-definition-context?))
Removes all of the scopes of intdef-ctx (or of each +element in a list intdef-ctx) from id-stx.

The identifier-remove-from-definition-context function is +provided for backward compatibility; the +internal-definition-context-splice-binding-identifier function is preferred.

Changed in version 6.3 of package base: Simplified the operation to scope removal.

A structure type property to constrain the use of macro +transformers and rename transformers. The property’s +value must be a list of symbols, where the allowed symbols are +'expression, 'top-level, 'module, +'module-begin, and 'definition-context. Each symbol +corresponds to an expansion context in the same way as for +local-expand or as reported by syntax-local-context, +except that 'definition-context is used (instead of a list) +to represent an internal-definition context.

If an identifier is bound to a transformer whose list does not include +a symbol for a particular use of the identifier, then the use is +adjusted as follows: +
  • In a 'module-begin context, then the use is wrapped in +a begin form.

  • In a 'module, 'top-level, +'internal-definition or context, if +'expression is present in the list, then the use is +wrapped in an #%expression form.

  • Otherwise, a syntax error is reported.

The prop:expansion-contexts property is most useful in +combination with prop:rename-transformer, since a general +transformer procedure can use syntax-local-context. +Furthermore, a prop:expansion-contexts property makes the +most sense when a rename transformer’s identifier has the +'not-free-identifier=? property, otherwise a definition of +the binding creates a binding alias that effectively routes around the +prop:expansion-contexts property.

Added in version 6.3 of package base.

procedure

(syntax-local-value id-stx    
  [failure-thunk    
  intdef-ctx])  any
  id-stx : identifier?
  failure-thunk : (or/c (-> any) #f) = #f
  intdef-ctx : 
(or/c internal-definition-context?
      #f
      (listof internal-definition-context?))
 = #f
Returns the transformer binding value of the identifier id-stx in the context of the +current expansion. If intdef-ctx is not #f, bindings from all provided definition +contexts are also considered. Unlike the fourth argument to local-expand, the +scopes associated with the provided definition contexts are not used to enrich +id-stx’s lexical information.

If id-stx is bound to a rename transformer created +with make-rename-transformer, syntax-local-value +effectively calls itself with the target of the rename and returns +that result, instead of the rename transformer.

If id-stx has no transformer binding (via +define-syntax, let-syntax, etc.) in that +environment, the result is obtained by applying failure-thunk +if not #f. If failure-thunk is false, the +exn:fail:contract exception is raised.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Examples:
> (define-syntax swiss-cheeses? #t)
> (define-syntax (transformer stx)
    (if (syntax-local-value #'swiss-cheeses?)
        #''(gruyère emmental raclette)
        #''(roquefort camembert boursin)))
> (transformer)

'(gruyère emmental raclette)

Examples:
> (define-syntax (transformer-2 stx)
    (syntax-local-value #'something-else (λ () (error "no binding"))))
> (transformer-2)

no binding

Examples:
> (define-syntax nachos #'(printf "nachos~n"))
> (define-syntax chips (make-rename-transformer #'nachos))
> (define-syntax (transformer-3 stx)
    (syntax-local-value #'chips))
> (transformer-3)

nachos

This procedure’s binding is provided as +protected in the sense of protect-out.

Changed in version 6.90.0.27 of package base: Changed intdef-ctx to accept a list of internal-definition +contexts in addition to a single internal-definition context or +#f.
Changed in version 8.2.0.4: Changed binding to protected.

procedure

(syntax-local-value/immediate id-stx    
  [failure-thunk    
  intdef-ctx])  any
  id-stx : syntax?
  failure-thunk : (or/c (-> any) #f) = #f
  intdef-ctx : 
(or/c internal-definition-context?
      #f
      (listof internal-definition-context?))
 = #f
Like syntax-local-value, but the result is normally two +values. If id-stx is bound to a rename transformer, +the results are the rename transformer and the identifier in the +transformer. Beware that provide on an +id bound to a rename transformer may export the +target of the rename instead of id. See +make-rename-transformer for more information. If +id-stx is not bound to a rename transformer, then the +results are the value that syntax-local-value would produce +and #f.

If id-stx has no transformer binding, then +failure-thunk is called (and it can return any number of +values), or an exception is raised if failure-thunk is +#f.

Examples:
> (define-syntax agent-007 (make-rename-transformer #'james-bond))
> (define-syntax (show-secret-identity stx)
    (syntax-parse stx
      [(_ name:id)
       (define-values [_ orig-name] (syntax-local-value/immediate #'name))
       #`'(name #,orig-name)]))
> (show-secret-identity agent-007)

'(agent-007 james-bond)

This procedure’s binding is provided as +protected in the sense of protect-out.

Changed in version 8.2.0.4 of package base: Changined binding to protected.

procedure

(syntax-local-lift-expression stx)  identifier?

  stx : syntax?
Returns a fresh identifier, and cooperates with the module, +letrec-syntaxes+values, define-syntaxes, +begin-for-syntax, and top-level expanders to bind the +generated identifier to the expression stx.

A run-time expression within a module is lifted to the module’s top +level, just before the expression whose expansion requests the +lift. Similarly, a run-time expression outside of a module is lifted +to a top-level definition. A compile-time expression in a +letrec-syntaxes+values or define-syntaxes binding is +lifted to a let wrapper around the corresponding right-hand +side of the binding. A compile-time expression within +begin-for-syntax is lifted to a define +declaration just before the requesting expression within the +begin-for-syntax.

Other syntactic forms can capture lifts by using +local-expand/capture-lifts or +local-transformer-expand/capture-lifts.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.
In addition, this procedure can be called only when +a lift target is available, as indicated by +syntax-transforming-with-lifts?.

Like syntax-local-lift-expression, but binds the result to +n identifiers, and returns a list of the n +identifiers.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Returns a value that represents the target for expressions lifted via +syntax-local-lift-expression. That is, for different +transformer calls for which this procedure returns the same value (as +determined by eq?), lifted expressions for the two +transformer are moved to the same place. Thus, the result is useful +for caching lift information to avoid redundant lifts.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

procedure

(syntax-local-lift-module stx)  void?

  stx : syntax?
Cooperates with the module form or top-level expansion to add +stx as a module declaration in the enclosing module or top-level. +The stx form must start with module or module*, +where the latter is only allowed within the expansion of a module.

The module is not immediately declared when +syntax-local-lift-module returns. Instead, the module +declaration is recorded for processing when expansion returns to the +enclosing module body or top-level sequence.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.
If the current expression being transformed is not +within a module form or within a top-level expansion, then +the exn:fail:contract exception is raised. If stx form does not start with +module or module*, or if it starts with module* +in a top-level context, the exn:fail:contract exception is raised.

Added in version 6.3 of package base.

procedure

(syntax-local-lift-module-end-declaration stx)  void?

  stx : syntax?
Cooperates with the module form to insert stx as +a top-level declaration at the end of the module currently being +expanded. If the current expression being +transformed is in phase level 0 and not in the module top-level, then stx is +eventually expanded in an expression context. If the current expression being +transformed is in a higher phase level (i.e., nested within some +number of begin-for-syntaxes within a module top-level), then the lifted declaration +is placed at the very end of the module (under a suitable number of +begin-for-syntaxes), instead of merely the end of the +enclosing begin-for-syntax.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.
If the current expression being transformed is not +within a module form (see syntax-transforming-module-expression?), +then the exn:fail:contract exception is raised.

procedure

(syntax-local-lift-require raw-require-spec    
  stx)  syntax?
  raw-require-spec : any/c
  stx : syntax?
Lifts a #%require form corresponding to +raw-require-spec (either as a syntax object or datum) +to the top-level or to the top of the module currently being expanded + or to an enclosing begin-for-syntax.

The resulting syntax object is the same as stx, except that a +fresh scope is added. The same scope is +added to the lifted #%require form, so that the +#%require form can bind uses of imported identifiers in the +resulting syntax object (assuming that the lexical information of +stx includes the binding environment into which the +#%require is lifted).

If raw-require-spec and stx are part of the input to +a transformer, then typically syntax-local-introduce should be +applied to each before passing them to +syntax-local-lift-require, and then +syntax-local-introduce should be applied to the result of +syntax-local-lift-require. Otherwise, marks added +by the macro expander can prevent access to the new imports.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Changed in version 6.90.0.27 of package base: Changed the scope added to inputs from a +macro-introduction scope to one that does not affect whether or +not the resulting syntax is considered original as reported by +syntax-original?.

procedure

(syntax-local-lift-provide raw-provide-spec-stx)  void?

  raw-provide-spec-stx : syntax?
Lifts a #%provide form corresponding to +raw-provide-spec-stx to the top of the module currently being +expanded or to an enclosing begin-for-syntax.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.
If the current expression being transformed is not +within a module form (see syntax-transforming-module-expression?), +then the exn:fail:contract exception is raised.

procedure

(syntax-local-name)  any/c

Returns an inferred name for the expression position being +transformed, or #f if no such name is available. A name is +normally a symbol or an identifier. See also Inferred Value Names.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

procedure

(syntax-local-context)

  (or/c 'expression 'top-level 'module 'module-begin list?)
Returns an indication of the context for expansion that triggered a +syntax transformer call. See Expansion Context +for more information on contexts.

The symbol results indicate that the expression is being expanded for +an expression context, a top-level context, a +module context, or a module-begin context.

A list result indicates expansion in an internal-definition +context. The identity of the list’s first element (i.e., its +eq?ness) reflects the identity of the internal-definition +context; in particular two transformer expansions receive the same +first value if and only if they are invoked for the same +internal-definition context. Later values in the list similarly +identify internal-definition contexts that are still being expanded, +and that required the expansion of nested internal-definition +contexts.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

During the dynamic extent of a syntax transformer application +by the expander, the result is the phase level of the form +being expanded. Otherwise, the result is 0.

Examples:
; a macro bound at phase 0
> (define-syntax (print-phase-level stx)
    (printf "phase level: ~a~n" (syntax-local-phase-level))
    #'(void))
> (require (for-meta 2 racket/base))
> (begin-for-syntax
    ; a macro bound at phase 1
    (define-syntax (print-phase-level stx)
      (printf "phase level: ~a~n" (syntax-local-phase-level))
      #'(void)))
> (print-phase-level)

phase level: 0

> (begin-for-syntax (print-phase-level))

phase level: 1

procedure

(syntax-local-module-exports mod-path)

  (listof (cons/c phase+space? (listof symbol?)))
  mod-path : 
(or/c module-path?
      (syntax/c module-path?))
Returns an association list from phase level and +binding space combinations to lists of symbols, +where the symbols are the names of provided +bindings from mod-path at the corresponding phase level.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Changed in version 8.2.0.3 of package base: Generalized result to phase–space combinations.

Returns a list of submodule names that are declared via +module (as opposed to module*) in the current +expansion context.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Returns a list of distinct interned symbols corresponding to +binding spaces that have been used, so far, for binding within +the current expansion context’s module or top-level namespace. The +result is conservative in the sense that it may include additional +symbols that have not been used in the current module or namespace.

The current implementation returns all symbols for reachable +interned scopes, but that behavior may change in the future to return +a less conservative list of symbols.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Added in version 8.2.0.7 of package base.

procedure

(syntax-local-get-shadower id-stx    
  [only-generated?])  identifier?
  id-stx : identifier?
  only-generated? : any/c = #f
Adds scopes to id-stx so that it refers to bindings +in the current expansion context or could bind any identifier obtained +via (syntax-local-get-shadower id-stx) in more nested contexts. +If only-generated? is true, the phase-spanning scope +of the enclosing module or namespace is omitted from the added scopes, +however, which limits the bindings that can be referenced (and +therefore avoids certain ambiguous references).

This function is intended for the implementation of +syntax-parameterize and local-require.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Changed in version 6.3 of package base: Simplified to the minimal functionality +needed for syntax-parameterize +and local-require.

procedure

(syntax-local-make-delta-introducer id-stx)  procedure?

  id-stx : identifier?
For (limited) backward compatibility only; raises exn:fail:unsupported.

Changed in version 6.3 of package base: changed to raise exn:fail:supported.

procedure

(syntax-local-certifier [active?])

  
((syntax?) (any/c (or/c procedure? #f))
 . ->* . syntax?)
  active? : boolean? = #f
For backward compatibility only; returns a procedure that returns its +first argument.

Returns #t during the dynamic extent of a syntax +transformer application by the expander and while a module is being +visited, #f otherwise.

Returns #t if (syntax-transforming?) produces +#t and a target context is available for lifting expressions +(via syntax-local-lift-expression), #f otherwise.

Currently, (syntax-transforming?) implies +(syntax-transforming-with-lifts?).

Added in version 6.3.0.9 of package base.

Returns #t during the dynamic extent of a syntax +transformer application by the expander for an expression +within a module form, #f otherwise.

procedure

(syntax-local-identifier-as-binding id-stx    
  [intdef-ctx])  identifier?
  id-stx : identifier?
  intdef-ctx : (or/c internal-definition-context? #f) = #f
Returns an identifier like id-stx, but without use-site +scopes that were previously added to the identifier as part of a +macro expansion. When the intdef-ctx is an internal-definition +context, the function removes use-site scopes created during expansion +in that context. When it is #f (the default), it removes use-site +scopes created during expansion in the current expansion context.

In a syntax transformer that runs in a non-expression context +and forces the expansion of subforms with local-expand, use +syntax-local-identifier-as-binding on an identifier from the +expansion before moving it into a binding position or comparing it +with bound-identifier=?. Otherwise, the results can be +inconsistent with the way that define works in the same +definition context.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Added in version 6.3 of package base.
Changed in version 8.2.0.7: Added the optional +intdef-ctx argument.

procedure

(syntax-local-introduce stx)  syntax?

  stx : syntax?
Produces a syntax object that is like stx, except that the +presence of scopes for the current expansion—both the +macro-introduction scope and the use-site scope, if any—is flipped +on all parts of the syntax object. See Transformer Bindings for information +on macro-introduction and use-site scopes.

This procedure must be called during the +dynamic extent of a syntax transformer application by the +expander or while a module is visited (see +syntax-transforming?), otherwise the +exn:fail:contract exception is raised.

Example:
> (module example racket
    (define-syntax (require-math stx)
      (syntax-local-introduce #'(require racket/math)))
    (require-math)
    pi)

procedure

(make-syntax-introducer [as-use-site?])

  ((syntax?) ((or/c 'flip 'add 'remove)) . ->* . syntax?)
  as-use-site? : any/c = #f
Produces a procedure that encapsulates a fresh scope and flips, +adds, or removes it in a given syntax object. By default, the fresh +scope is a macro-introduction scope, but providing a true value for +as-use-site? creates a scope that is like a use-site scope; +the difference is in how the scopes are treated by +syntax-original?.

The action of the generated procedure can be 'flip (the +default) to flip the presence of a scope in each part of a given +syntax object, 'add to add the scope to each regardless of +whether it is present already, or 'remove to remove the scope +when it is currently present in any part.

Multiple applications of the same +make-syntax-introducer result procedure use the same scope, +and different result procedures use distinct scopes.

Changed in version 6.3 of package base: Added the optional +as-use-site? argument, and +added the optional operation argument +in the result procedure.

procedure

(make-interned-syntax-introducer key)

  ((syntax?) ((or/c 'flip 'add 'remove)) . ->* . syntax?)
  key : (and/c symbol? symbol-interned?)
Like make-syntax-introducer, but the encapsulated scope is interned. Multiple calls to +make-interned-syntax-introducer with the same key will produce procedures that flip, +add, or remove the same scope, even across phases and module instantiations. +Furthermore, the scope remains consistent even when embedded in compiled code, so a scope +created with make-interned-syntax-introducer will retain its identity in syntax objects +loaded from compiled code. (In this sense, the relationship between make-syntax-introducer +and make-interned-syntax-introducer is analogous to the relationship between +gensym and quote.)

This function is intended for the implementation of separate binding spaces within a single +phase, for which the scope associated with each environment must be the same across modules.

Unlike make-syntax-introducer, the scope added by a procedure created with +make-interned-syntax-introducer is always treated like a use-site scope, not a +macro-introduction scope, so it does not affect originalness as reported by syntax-original?.

Added in version 6.90.0.28 of package base.
Changed in version 8.2.0.4: Added the constraint that key is interned.

procedure

(make-syntax-delta-introducer ext-stx 
  base-stx 
  [phase-level]) 
  ((syntax?) ((or/c 'flip 'add 'remove)) . ->* . syntax?)
  ext-stx : identifier?
  base-stx : (or/c syntax? #f)
  phase-level : (or/c #f exact-integer?)
   = (syntax-local-phase-level)
Produces a procedure that behaves like the result of +make-syntax-introducer, but using a set of scopes from +ext-stx and with a default action of 'add.

  • If the scopes of base-stx are a subset of the scopes +of ext-stx, then the result of +make-syntax-delta-introducer adds, removes, or flips +scopes that are in the set for ext-stx and not in the +set for base-stx.

  • If the scopes of base-stx are not a subset of the +scopes of ext-stx, but if it has a binding, then the +set of scopes associated with the binding id subtracted from +the set of scopes for ext-stx, and the result of +make-syntax-delta-introducer adds, removes, or flips +that difference.

A #f value for base-stx is equivalent to a syntax +object with no scopes.

This procedure is potentially useful when some m-id has a +transformer binding that records some orig-id, and a use of +m-id introduces a binding of orig-id. In that +case, the scopes one the use of m-id added since the +binding of m-id should be transferred to the binding +instance of orig-id, so that it captures uses with the same +lexical context as the use of m-id.

If ext-stx is tainted, then an +identifier result from the created procedure is tainted.

Returns #t while a provide transformer is running (see +make-provide-transformer) or while an expand sub-form of +#%provide is expanded, #f otherwise.

Can be called only while +syntax-local-transforming-module-provides? returns +#t.

It returns a hash table mapping a phase-level number (such as +0) to a list of all definitions at that phase level +within the module being expanded. This information is used for +implementing provide sub-forms like all-defined-out.

Beware that the phase-level keys are absolute relative to the +enclosing module, and not relative to the current transformer phase +level as reported by syntax-local-phase-level.

procedure

(syntax-local-module-required-identifiers mod-path 
  shift) 
  
(or/c (listof (cons/c phase+space?
                      (listof identifier?)))
      #f)
  mod-path : (or/c module-path? #f)
  shift : (or/c #t phase+space-shift?)
Can be called only while +syntax-local-transforming-module-provides? returns +#t.

It returns an association list mapping phase level and +binding space combinations to lists of +identifiers. Each list of identifiers includes all bindings imported +(into the module being expanded) using the module path +mod-path, or all modules if mod-path is +#f. The association list includes all identifiers imported +with a phase level and binding space shift as represented by shift, +or all shifts if shift is #t. If shift is +not #t, the result can be #f if no identifiers +are imported at that shift.

When an identifier is renamed on import, the result association list +includes the identifier by its internal name. Use +identifier-binding to obtain more information about the +identifier.

Beware that the phase-level shifts are absolute relative to the +enclosing module, and not relative to the current transformer phase +level as reported by syntax-local-phase-level.

Changed in version 8.2.0.3 of package base: Generalized shift and result +to phase–space combinations.

An instance of a structure type with a true value for the +prop:liberal-define-context property can be used as an +element of an internal-definition context representation in the +result of syntax-local-context or the second argument of +local-expand. Such a value indicates that the context +supports liberal expansion of define forms into +potentially multiple define-values and +define-syntaxes forms. The 'module and +'module-body contexts implicitly allow liberal +expansion.

The liberal-define-context? predicate returns #t if +v is an instance of a structure with a true value for the +prop:liberal-define-context property, #f otherwise.

12.4.1 require Transformers

The bindings documented in this section are provided by the racket/require-transform library, not racket/base or racket.

A transformer binding whose value is a structure with the +prop:require-transformer property implements a derived +require-spec for require as a require +transformer.

A require transformer is called with the syntax object representing its use +as a require-spec within a require form, and the +result must be two lists: a list of imports and a list of +import-sources.

If the derived form contains a sub-form that is a +require-spec, then it can call expand-import to +transform the sub-require-spec to lists of imports and +import sources.

See also define-require-syntax, which supports macro-style +require transformers.

procedure

(expand-import require-spec)

  
(listof import?) (listof import-source?)
  require-spec : syntax?
Expands the given require-spec to lists of imports and +import sources. The latter specifies modules to be +instantiated or visited, so the modules that it +represents should be a superset of the modules represented in the +former list (so that a module will be instantiated or +visited even if all of imports are eventually filtered from the +former list).

procedure

(make-require-transformer proc)  require-transformer?

  proc : 
(syntax? . -> . (values
                 (listof import?)
                 (listof import-source?)))
Creates a require transformer using the given procedure as the +transformer. +Often used in combination with expand-import.

Examples:
> (require (for-syntax racket/require-transform))
> (define-syntax printing
    (make-require-transformer
     (lambda (stx)
       (syntax-case stx ()
         [(_ path)
          (begin
            (printf "Importing: ~a~n" #'path)
            (expand-import #'path))]))))
> (require (printing racket/match))

Importing: #<syntax:eval:37:0 racket/match>

A property to identify require transformers. The property +value must be a procedure that takes the structure and returns a transformer +procedure; the returned transformer procedure takes a syntax object and returns +import and import-source lists.

procedure

(require-transformer? v)  boolean?

  v : any/c
Returns #t if v has the +prop:require-transformer property, #f otherwise.

struct

(struct import (local-id
    src-sym
    src-mod-path
    mode
    req-mode
    orig-mode
    orig-stx)
    #:extra-constructor-name make-import)
  local-id : identifier?
  src-sym : symbol?
  src-mod-path : 
(or/c module-path?
      (syntax/c module-path?))
  mode : phase+space?
  req-mode : phase+space-shift?
  orig-mode : phase+space?
  orig-stx : syntax?
A structure representing a single imported identifier:

  • local-id the identifier to be bound within the +importing module, but without any space-specific scope +implied by mode.

  • src-sym the external name of the binding as +exported from its source module.

  • src-mod-path a module path (relative to the +importing module) for the source of the imported binding.

  • mode the phase level and binding +space of the binding in the importing module, which must be the +same as (phase+space+ orig-mode req-mode).

  • req-mode the phase level shift and +binding space shift of the import relative to the +exporting module.

  • orig-mode the phase level and binding +space of the binding as exported by the exporting module.

  • orig-stx a syntax object for the source of +the import, used for error reporting.

Changed in version 8.2.0.3 of package base: Generalized modes to phase–space combinations.

struct

(struct import-source (mod-path-stx mode)
    #:extra-constructor-name make-import-source)
  mod-path-stx : (syntax/c module-path?)
  mode : phase+space-shift?
A structure representing an imported module, which must be +instantiated or visited even if no binding is imported +into a module.

  • mod-path-stx a module path (relative +to the importing module) for the source of the imported binding.

  • mode the phase level shift and +binding space shift of the import.

Changed in version 8.2.0.3 of package base: Generalized mode to phase–space combinations.

parameter

(current-require-module-path)  (or/c #f module-path-index?)

(current-require-module-path module-path)  void?
  module-path : (or/c #f module-path-index?)
A parameter that determines how relative require-level module +paths are expanded to #%require-level module paths by +convert-relative-module-path (which is used implicitly by all +built-in require sub-forms).

When the value of current-require-module-path is #f, +relative module paths are left as-is, which means that the +require context determines the resolution of the module +path.

The require form parameterizes +current-require-module-path as #f while invoking +sub-form transformers, while relative-in parameterizes +to a given module path.

procedure

(convert-relative-module-path module-path)

  
(or/c module-path?
      (syntax/c module-path?))
  module-path : 
(or/c module-path?
      (syntax/c module-path?))
Converts module-path according to current-require-module-path.

If module-path is not relative or if the value of +current-require-module-path is #f, then +module-path is returned. Otherwise, module-path is +converted to an absolute module path that is equivalent to +module-path relative to the value of +current-require-module-path.

procedure

(syntax-local-require-certifier)

  
((syntax?) (or/c #f (syntax? . -> . syntax?))
 . ->* . syntax?)
For backward compatibility only; returns a procedure that returns its +first argument.

12.4.2 provide Transformers

The bindings documented in this section are provided by the racket/provide-transform library, not racket/base or racket.

A transformer binding whose value is a structure with the +prop:provide-transformer property implements a derived +provide-spec for provide as a provide transformer. +A provide transformer is applied as part of the last phase of +a module’s expansion, after all other declarations and expressions within +the module are expanded.

A transformer binding whose value is a structure with the +prop:provide-pre-transformer property implements a derived +provide-spec for provide as a provide +pre-transformer. A provide pre-transformer is applied as part +of the first phase of a module’s expansion. Since it is used in the +first phase, a provide pre-transformer can use functions such +as syntax-local-lift-expression to introduce expressions and +definitions in the enclosing module.

An identifier can have a transformer binding to a value that +acts both as a provide transformer and provide +pre-transformer. The result of a provide +pre-transformer is not automatically re-expanded, so a +provide pre-transformer can usefully expand to itself in that case.

A transformer is called with the syntax object representing its use as +a provide-spec within a provide form and a list of +symbols representing the export modes specified by enclosing +provide-specs. The result of a provide transformer +must be a list of exports, while the result of a +provide pre-transformer is a syntax object to be used as a +provide-spec in the last phase of module expansion.

If a derived form contains a sub-form that is a +provide-spec, then it can call expand-export or +pre-expand-export to transform the sub-provide-spec +sub-form.

See also define-provide-syntax, which supports macro-style +provide transformers.

procedure

(expand-export provide-spec modes)  (listof export?)

  provide-spec : syntax?
  modes : (listof phase+space?)
Expands the given provide-spec to a list of exports. The +modes list controls the expansion of +sub-provide-specs; for example, an identifier refers to a +binding in the phase level of the enclosing provide +form, unless the modes list specifies otherwise. Normally, +modes is either empty or contains a single element.

Changed in version 8.2.0.3 of package base: Generalized modes to phase–space combinations.

procedure

(pre-expand-export provide-spec modes)  syntax?

  provide-spec : syntax?
  modes : (listof phase+space?)
Expands the given provide-spec at the level of provide +pre-transformers. The modes argument is the same as for +expand-export.

Changed in version 8.2.0.3 of package base: Generalized modes to phase–space combinations.

procedure

(make-provide-transformer proc)  provide-transformer?

  proc : 
(syntax? (listof phase+space?)
 . -> . (listof export?))
(make-provide-transformer proc pre-proc)
  (and/c provide-transformer? provide-pre-transformer?)
  proc : 
(syntax? (listof phase+space?)
 . -> . (listof export?))
  pre-proc : 
(syntax? (listof phase+space?)
 . -> . syntax?)
Creates a provide transformer (i.e., a structure with the +prop:provide-transformer property) using the given procedure +as the transformer. If a pre-proc is provided, then the result is also a +provide pre-transformer. +Often used in combination with expand-export and/or +pre-expand-export.

procedure

(make-provide-pre-transformer pre-proc)

  provide-pre-transformer?
  pre-proc : 
(syntax? (listof phase+space?)
 . -> . syntax?)
Like make-provide-transformer, but for a value that is a +provide pre-transformer, only. +Often used in combination with pre-expand-export.

Examples:
> (module m racket
    (require
      (for-syntax racket/provide-transform syntax/parse syntax/stx))
  
    (define-syntax wrapped-out
      (make-provide-pre-transformer
       (lambda (stx modes)
         (syntax-parse stx
           [(_ f ...)
            #:with (wrapped-f ...)
                   (stx-map
                    syntax-local-lift-expression
                    #'((lambda args
                         (printf "applying ~a, args: ~a\n" 'f args)
                         (apply f args)) ...))
            (pre-expand-export
             #'(rename-out [wrapped-f f] ...) modes)]))))
  
    (provide (wrapped-out + -)))
> (require 'm)
> (- 1 (+ 2 3))

applying +, args: (2 3)

applying -, args: (1 5)

-4

A property to identify provide transformers. The property +value must be a procedure that takes the structure and returns a transformer +procedure; the returned transformer procedure takes a syntax object and mode list and +returns an export list.

A property to identify provide pre-transformers. The property +value must be a procedure that takes the structure and returns a transformer +procedure; the returned transformer procedure takes a syntax object and mode list and +returns a syntax object.

procedure

(provide-transformer? v)  boolean?

  v : any/c
Returns #t if v has the +prop:provide-transformer property, #f otherwise.

procedure

(provide-pre-transformer? v)  boolean?

  v : any/c
Returns #t if v has the +prop:provide-pre-transformer property, #f otherwise.

struct

(struct export (local-id out-sym mode protect? orig-stx)
    #:extra-constructor-name make-export)
  local-id : identifier?
  out-sym : symbol?
  mode : phase+space?
  protect? : any/c
  orig-stx : syntax?
A structure representing a single exported identifier:

  • local-id the identifier that is bound within the +exporting module.

  • out-sym the external name of the binding.

  • mode the phase level and binding +space of the export (which affects how it is imported).

  • protect? indicates whether the identifier should +be protected (see Code Inspectors).

  • orig-stx a syntax object for the source of +the export, used for error reporting.

Changed in version 8.2.0.3 of package base: Generalized mode to phase–space combinations.

procedure

(syntax-local-provide-certifier)

  
((syntax?) (or/c #f (syntax? . -> . syntax?))
 . ->* . syntax?)
For backward compatibility only; returns a procedure that returns its +first argument.

12.4.3 Keyword-Argument Conversion Introspection

The bindings documented in this section are provided by the racket/keyword-transform library, not racket/base or racket.

procedure

(syntax-procedure-alias-property stx)

  
(or/c #f
      (letrec ([val? (recursive-contract
                      (or/c (cons/c identifier? identifier?)
                            (cons/c val? val?)))])
        val?))
  stx : syntax?

procedure

(syntax-procedure-converted-arguments-property stx)

  
(or/c #f
      (letrec ([val? (recursive-contract
                      (or/c (cons/c identifier? identifier?)
                            (cons/c val? val?)))])
        val?))
  stx : syntax?
Reports the value of a syntax property that can be +attached to an identifier by the expansion of a keyword-application +form. See lambda for more +information about the property.

The property value is normally a pair consisting of the original +identifier and an identifier that appears in the +expansion. Property-value merging via syntax-track-origin can make +the value a pair of such values, and so on.

12.4.4 Portal Syntax Bindings

An identifier bound to portal syntax value created by +make-portal-syntax does not act as a transformer, but it +encapsulates a syntax object that can be accessed in inspected even +without instantiating the enclosing module. Portal syntax is also bound +using the portal form of #%require.

procedure

(portal-syntax? v)  boolean?

  v : any/c
Returns #t if v is a value created by +make-portal-syntax, #f otherwise.

Added in version 8.3.0.8 of package base.

procedure

(make-portal-syntax stx)  portal-syntax?

  stx : syntax?
Creates portal syntax with the content stx.

When define-syntax or define-syntaxes binds an +identifier to portal syntax immediately in a module body, then in +addition to being accessible via syntax-local-value while +expanding, the portal syntax content is accessible via +identifier-binding-portal-syntax.

Added in version 8.3.0.8 of package base.

procedure

(portal-syntax-content portal)  syntax?

  portal : portal-syntax?
Returns the content of portal syntax created with +make-portal-syntax.

Added in version 8.3.0.8 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/subprocess.html b/clones/docs.racket-lang.org/reference/subprocess.html new file mode 100644 index 00000000..2bfd1ad4 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/subprocess.html @@ -0,0 +1,248 @@ + +15.4 Processes

15.4 Processes

procedure

(subprocess stdout 
  stdin 
  stderr 
  [group] 
  command 
  arg ...) 
  
subprocess?
(or/c (and/c input-port? file-stream-port?) #f)
(or/c (and/c output-port? file-stream-port?) #f)
(or/c (and/c input-port? file-stream-port?) #f)
  stdout : (or/c (and/c output-port? file-stream-port?) #f)
  stdin : (or/c (and/c input-port? file-stream-port?) #f)
  stderr : (or/c (and/c output-port? file-stream-port?) #f 'stdout)
  group : (or/c #f 'new subprocess)
   = (and (subprocess-group-enabled) 'new)
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
(subprocess stdout 
  stdin 
  stderr 
  [group] 
  command 
  exact 
  arg) 
  
subprocess?
(or/c (and/c input-port? file-stream-port?) #f)
(or/c (and/c output-port? file-stream-port?) #f)
(or/c (and/c input-port? file-stream-port?) #f)
  stdout : (or/c (and/c output-port? file-stream-port?) #f)
  stdin : (or/c (and/c input-port? file-stream-port?) #f)
  stderr : (or/c (and/c output-port? file-stream-port?) #f)
  group : (or/c #f 'new subprocess)
   = (and (subprocess-group-enabled) 'new)
  command : path-string?
  exact : 'exact
  arg : string?
Creates a new process in the underlying operating system to execute +command asynchronously, providing the new process with +environment variables current-environment-variables. See also +system and process from +racket/system.

On Unix and Mac OS, subprocess creation is separate +from starting the program indicated by command. In +particular, if command refers to a non-existent or +non-executable file, an error will be reported (via standard error and +a non-0 exit code) in the subprocess, not in the creating +process.

The command argument is a path to a program executable, and +the args are command-line arguments for the program. See +find-executable-path for locating an executable based on +the PATH environment variable. On +Unix and Mac OS, command-line arguments are passed as byte strings, +and string args are converted using the current locale’s +encoding (see Encodings and Locales). On Windows, command-line +arguments are passed as strings, and byte strings are converted using +UTF-8.

On Windows, the first arg can be replaced with +'exact, which triggers a Windows-specific behavior: +the sole arg is used exactly as the command-line for the +subprocess. Otherwise, on Windows, a command-line string is +constructed from command and arg so that a typical +Windows console application can parse it back to an array of +arguments. If 'exact is provided on a non-Windows platform, +the exn:fail:contract exception is raised.

For information on the Windows command-line conventions, +search for “command line parsing” at +http://msdn.microsoft.com/.

When provided as a port, stdout is used for the launched +process’s standard output, stdin is used for the process’s +standard input, and stderr is used for the process’s standard +error. All provided ports must be file-stream ports. Any of the ports +can be #f, in which case a system pipe is created and +returned by subprocess. The stderr argument can be +'stdout, in which case the same file-stream port or system pipe +that is supplied as standard output is also used for standard error. +For each port or 'stdout that is provided, no +pipe is created and the corresponding returned value is #f. +If stdout or stderr is a port for which +port-waiting-peer? returns true, then subprocess +waits for the port to become ready for writing before proceeding with +the subprocess creation.

If group is 'new, then the new process is created as +a new OS-level process group. In that case, subprocess-kill +attempts to terminate all processes within the group, which may +include additional processes created by the subprocess. +Beware that creating a group may interfere with the job +control in an interactive shell, since job control is based on process +groups. See subprocess-kill for details. If group +is a subprocess, then that subprocess must have been created with +'new, and the new subprocess will be added to the group; +adding to the group will succeed only on Unix and Mac OS, and only in +the same cases that subprocess-kill would have an effect +(i.e., the subprocess is not known to have terminated), otherwise it +will fail silently.

The subprocess procedure returns four values:

  • a subprocess value representing the created process;

  • an input port piped from the process’s standard output, or +#f if stdout was a port;

  • an output port piped to the process’s standard input, or +#f if stdin was a port;

  • an input port piped from the process’s standard error, or +#f if stderr was a port or 'stdout.

Important: All ports returned from subprocess must be +explicitly closed, usually with close-input-port or +close-output-port.

A file-stream port for communicating with a +subprocess is normally a pipe with a limited capacity. Beware of +creating deadlock by serializing a write to a subprocess followed by a +read, while the subprocess does the same, so that both processes end +up blocking on a write because the other end must first read to make +room in the pipe. Beware also of waiting for a subprocess to finish +without reading its output, because the subprocess may be blocked attempting +to write output into a full pipe.

The returned ports are file-stream ports (see +File Ports), and they are placed into the management of +the current custodian (see Custodians). The +exn:fail exception is raised when a low-level error prevents the spawning of a +process or the creation of operating system pipes for process +communication.

The current-subprocess-custodian-mode parameter determines +whether the subprocess itself is registered with the current +custodian so that a custodian shutdown calls +subprocess-kill for the subprocess.

The current-subprocess-keep-file-descriptors parameter +determines how file descriptors and handles in the current process are +shared with the subprocess. File descriptors (on Unix and Mac OS) or +handles (on Windows) represented by stdin, stdout, +and stderr are always shared with the subprocess. With the +default parameter value of 'inherited, handles that are +inherited on Windows are also shared, while no other file descriptors +are shared on Unix and Mac OS. The parameter value 'all is +equivalent to 'inherited on Windows, but on Unix and Mac OS, +all file descriptors from the current process are shared with the +subprocess—except for file descriptors 0, 1, and 2 as replaced by +newly created pipes when the corresponding stdin, +stdout, and stderr argument is #f. The +parameter value '() is the same as 'inherited on +Unix and Mac OS , but it prevents sharing of inheritable handles on +Windows. (A future extension may support a list of specific file +descriptors or handles to share.)

A subprocess can be used as a synchronizable event (see Events). +A subprocess value is ready for synchronization when +subprocess-wait would not block; the synchronization result of a subprocess value is the subprocess value itself.

Example:

(define-values (sp out in err)
  (subprocess #f #f #f "/bin/ls" "-l"))
(printf "stdout:\n~a" (port->string out))
(printf "stderr:\n~a" (port->string err))
(close-input-port out)
(close-output-port in)
(close-input-port err)
(subprocess-wait sp)

Changed in version 6.11.0.1 of package base: Added the group argument.
Changed in version 7.4.0.5: Added waiting for a fifo without a reader +as stdout and/or stderr.
Changed in version 8.3.0.4: Added current-subprocess-custodian-mode support.

procedure

(subprocess-wait subproc)  void?

  subproc : subprocess?
Blocks until the process represented by subproc +terminates. The subproc value also can be used with +sync and sync/timeout.

procedure

(subprocess-status subproc)  
(or/c 'running
      exact-nonnegative-integer?)
  subproc : subprocess?
Returns 'running if the process represented by +subproc is still running, or its exit code otherwise. The +exit code is an exact integer, and 0 typically indicates +success. If the process terminated due to a fault or signal, the exit +code is non-zero.

procedure

(subprocess-kill subproc force?)  void?

  subproc : subprocess?
  force? : any/c
Terminates the subprocess represented by subproc. The precise +action depends on whether force? is true, whether the process +was created in its own group by setting the +subprocess-group-enabled parameter to a true value, and the +current platform:

  • force? is true, not a group, all platforms: Terminates +the process if the process still running.

  • force? is false, not a group, on Unix or Mac OS: +Sends the process an interrupt signal instead of a kill +signal.

  • force? is false, not a group, on Windows: No action +is taken.

  • force? is true, a group, on Unix or Mac OS: +Terminates all processes in the group, but only if +subprocess-status has never produced a +non-'running result for the subprocess and only if +functions like subprocess-wait and sync have +not detected the subprocess’s completion. Otherwise, no action +is taken (because the immediate process is known to have +terminated while the continued existence of the group is +unknown).

  • force? is true, a group, on Windows: Terminates +the process if the process still running.

  • force? is false, a group, on Unix or Mac OS: The +same as when force? is #t, but when the group +is sent a signal, it is an interrupt signal instead of a kill +signal.

  • force? is false, a group, on Windows: All processes +in the group receive a CTRL-BREAK signal (independent of +whether the immediate subprocess has terminated).

If an error occurs during termination, the exn:fail exception is raised.

procedure

(subprocess-pid subproc)  exact-nonnegative-integer?

  subproc : subprocess?
Returns the operating system’s numerical ID (if any) for the process +represented by subproc. The result is valid only as long as +the process is running.

procedure

(subprocess? v)  boolean?

  v : any/c
Returns #t if v is a subprocess value, #f +otherwise.

parameter

(current-subprocess-custodian-mode)

  (or/c #f 'kill 'interrupt)
(current-subprocess-custodian-mode mode)  void?
  mode : (or/c #f 'kill 'interrupt)
A parameter that determines whether a subprocess (as created by +subprocess or wrappers like process) is registered +with the current custodian. If the parameter value is +#f, then the subprocess is not registered with the +custodian—although any created ports are registered. If the +parameter value is 'kill or 'interrupt, then the +subprocess is shut down through subprocess-kill, where +'kill supplies a #t value for the force? +argument and 'interrupt supplies a #f value. The +shutdown may occur either before or after ports created for the +subprocess are closed.

Custodian-triggered shutdown is limited by details of process handling +in the host system. For example, process and system +may create an intermediate shell process to run a program, in which +case custodian-based termination shuts down the shell process and +probably not the process started by the shell. See also +subprocess-kill. Process groups (see +subprocess-group-enabled) can address some limitations, but +not all of them.

parameter

(subprocess-group-enabled)  boolean?

(subprocess-group-enabled on?)  void?
  on? : any/c
A parameter that determines whether a subprocess is created as +a new process group by default. See subprocess and +subprocess-kill for more information.

parameter

(current-subprocess-keep-file-descriptors)

  (or/c 'inherited 'all '())
(current-subprocess-keep-file-descriptors keeps)  void?
  keeps : (or/c 'inherited 'all '())
A parameter that determines how file descriptors (on Unix and +Mac OS) and handles (on Windows) are shared in a subprocess as created +by subprocess or wrappers like process. See +subprocess for more information.

Added in version 8.3.0.4 of package base.

procedure

(shell-execute verb    
  target    
  parameters    
  dir    
  show-mode)  #f
  verb : (or/c string? #f)
  target : string?
  parameters : string?
  dir : path-string?
  show-mode : symbol?
Performs the action specified by verb +on target in Windows. For platforms other than Windows, the +exn:fail:unsupported exception is raised.

For example,

(shell-execute #f "http://racket-lang.org" ""
               (current-directory) 'sw_shownormal)

Opens the Racket home page in a browser window.

The verb can be #f, in which case the operating +system will use a default verb. Common verbs include "open", +"edit", "find", "explore", and +"print".

The target is the target for the action, usually a filename +path. The file could be executable, or it could be a file with a +recognized extension that can be handled by an installed application.

The parameters argument is passed on to the system to perform +the action. For example, in the case of opening an executable, the +parameters is used as the command line (after the executable +name).

The dir is used as the current directory when performing the +action.

The show-mode sets the display mode for a Window affected by +the action. It must be one of the following symbols; the description +of each symbol’s meaning is taken from the Windows API documentation.

  • 'sw_hide or 'SW_HIDE +Hides the window and activates another window.

  • 'sw_maximize or 'SW_MAXIMIZE +— Maximizes the window.

  • 'sw_minimize or 'SW_MINIMIZE +— Minimizes the window and activates the next top-level window in +the z-order.

  • 'sw_restore or 'SW_RESTORE +— Activates and displays the window. If the window is minimized or +maximized, Windows restores it to its original size and position.

  • 'sw_show or 'SW_SHOW +Activates the window and displays it in its current size and +position.

  • 'sw_showdefault or +'SW_SHOWDEFAULT Uses a default.

  • 'sw_showmaximized or +'SW_SHOWMAXIMIZED Activates the window and +displays it as a maximized window.

  • 'sw_showminimized or +'SW_SHOWMINIMIZED Activates the window and +displays it as a minimized window.

  • 'sw_showminnoactive or +'SW_SHOWMINNOACTIVE Displays the window as a +minimized window. The active window remains active.

  • 'sw_showna or 'SW_SHOWNA +Displays the window in its current state. The active window remains +active.

  • 'sw_shownoactivate or +'SW_SHOWNOACTIVATE Displays a window in its most +recent size and position. The active window remains active.

  • 'sw_shownormal or +'SW_SHOWNORMAL Activates and displays a +window. If the window is minimized or maximized, Windows restores it +to its original size and position.

If the action fails, the exn:fail exception is raised. If the action succeeds, +the result is #f.

In future versions of Racket, the result may be a subprocess value if +the operating system did returns a process handle (but if a subprocess +value is returned, its process ID will be 0 instead of the +real process ID).

15.4.1 Simple Subprocesses

 (require racket/system) package: base
The bindings documented in this section are provided by the racket/system and racket libraries, but not racket/base.

procedure

(system command [#:set-pwd? set-pwd?])  boolean?

  command : (or/c string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Executes a Unix, Mac OS, or Windows shell command synchronously +(i.e., the call to system does not return until the +subprocess has ended). The command argument is a string or +byte string containing no nul characters. If the command succeeds, the +return value is #t, #f otherwise.

See also subprocess for notes about error +handling and the limited buffer capacity of subprocess pipes.

If set-pwd? is true, then the PWD environment +variable is set to the value of (current-directory) when +starting the shell process.

See also current-subprocess-custodian-mode and +subprocess-group-enabled, which affect the subprocess used to +implement system.

The resulting process writes to (current-output-port), reads +from (current-input-port), and logs errors to +(current-error-port). To gather the process’s non-error +output to a string, for example, use with-output-to-string, +which sets current-output-port while calling the given +function:

(with-output-to-string (lambda () (system "date")))

procedure

(system* command arg ... [#:set-pwd? set-pwd?])  boolean?

  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
(system* command    
  exact    
  arg    
  [#:set-pwd? set-pwd?])  boolean?
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Like system, except that command is a filename that +is executed directly (instead of through a shell command; see +find-executable-path for locating an executable based on +the PATH environment variable), and the +args are the arguments. The executed file is passed the +specified string arguments (which must contain no nul +characters).

On Windows, the first argument after command can be +'exact, and the final arg is a complete command +line. See subprocess for details.

procedure

(system/exit-code command    
  [#:set-pwd? set-pwd?])  byte?
  command : (or/c string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Like system, except that the result is the exit code returned +by the subprocess. A 0 result normally indicates success.

procedure

(system*/exit-code command    
  arg ...    
  [#:set-pwd? set-pwd?])  byte?
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
(system*/exit-code command    
  exact    
  arg    
  [#:set-pwd? set-pwd?])  byte?
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Like system*, but returns the exit code like +system/exit-code.

procedure

(process command [#:set-pwd? set-pwd?])

  
(list input-port?
      output-port?
      exact-nonnegative-integer?
      input-port?
      ((or/c 'status 'wait 'interrupt 'kill) . -> . any))
  command : (or/c string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Executes a shell command asynchronously (using sh on Unix +and Mac OS, cmd on Windows). The result is a list of five +values:

See also subprocess for notes about error +handling and the limited buffer capacity of subprocess pipes.

  • an input port piped from the subprocess’s standard output,

  • an output port piped to the subprocess’s standard input,

  • the system process id of the subprocess,

  • an input port piped from the subprocess’s standard +error, and

  • a procedure of one argument, either 'status, 'wait, +'interrupt, 'exit-code or 'kill:

    • 'status returns the status of the subprocess as one +of 'running, 'done-ok, or +'done-error.

    • 'exit-code returns the integer exit code of the +subprocess or #f if it is still running.

    • 'wait blocks execution in the current thread until +the subprocess has completed.

    • 'interrupt sends the subprocess an interrupt signal +on Unix and Mac OS, and takes no action on Windows. The result is +#<void>.

      On Unix and Mac OS, if command runs a +single program, then sh typically runs the program in +such a way that it replaces sh in the same process. For +reliable and precise control over process creation, however, use +process*.

    • 'kill terminates the subprocess and returns +#<void>. Note that the immediate process created by +process is a shell process that may run another program; +terminating the shell process may not terminate processes that +the shell starts, particularly on Windows.

Important: All three ports returned from process must +be explicitly closed with close-input-port or +close-output-port.

If set-pwd? is true, then PWD is set in the same way +as system.

See also current-subprocess-custodian-mode and +subprocess-group-enabled, which affect the subprocess used to +implement process. In particular, the 'interrupt and +'kill process-control messages are implemented via +subprocess-kill, so they can affect a process group instead +of a single process.

procedure

(process* command    
  arg ...    
  [#:set-pwd? set-pwd?])  list?
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
(process* command    
  exact    
  arg    
  [#:set-pwd? set-pwd?])  list?
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Like process, except that command is a filename that +is executed directly like system*, and the args are the arguments. On +Windows, as for system*, the first arg can be +replaced with 'exact.

procedure

(process/ports out    
  in    
  error-out    
  command    
  [#:set-pwd? set-pwd?])  list?
  out : (or/c #f output-port?)
  in : (or/c #f input-port?)
  error-out : (or/c #f output-port? 'stdout)
  command : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Like process, except that out is used for the +process’s standard output, in is used for the process’s +standard input, and error-out is used for the process’s +standard error. Any of the ports can be #f, in which case a +system pipe is created and returned, as in process. If +error-out is 'stdout, then standard error is +redirected to standard output. For each port or 'stdout that +is provided, no pipe is created, and the corresponding value in the +returned list is #f.

procedure

(process*/ports out    
  in    
  error-out    
  command    
  arg ...    
  [#:set-pwd? set-pwd?])  list?
  out : (or/c #f output-port?)
  in : (or/c #f input-port?)
  error-out : (or/c #f output-port? 'stdout)
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))
(process*/ports out    
  in    
  error-out    
  command    
  exact    
  arg    
  [#:set-pwd? set-pwd?])  list?
  out : (or/c #f output-port?)
  in : (or/c #f input-port?)
  error-out : (or/c #f output-port? 'stdout)
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))
Like process*, but with the port handling of +process/ports.

The contracts of system and related functions may signal a +contract error with references to the following functions.

procedure

(string-no-nuls? x)  boolean?

  x : any/c
Ensures that x is a string and does not contain "\u0000".

procedure

(bytes-no-nuls? x)  boolean?

  x : any/c
Ensures that x is a byte-string and does not contain #"\0".

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/symbols.html b/clones/docs.racket-lang.org/reference/symbols.html new file mode 100644 index 00000000..32cdb2e3 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/symbols.html @@ -0,0 +1,46 @@ + +4.7 Symbols

4.7 Symbols

+Symbols in The Racket Guide introduces symbols.

A symbol is like an immutable string, but symbols are +normally interned, so that two symbols with the same +character content are normally eq?. All symbols produced by +the default reader (see Reading Symbols) are interned.

The two procedures string->uninterned-symbol and +gensym generate uninterned symbols, i.e., symbols +that are not eq?, eqv?, or equal? to any +other symbol, although they may print the same as other symbols.

The procedure string->unreadable-symbol returns an +unreadable symbol that is partially interned. The default +reader (see Reading Symbols) never produces a unreadable +symbol, but two calls to string->unreadable-symbol with +equal? strings produce eq? results. An unreadable +symbol can print the same as an interned or uninterned +symbol. Unreadable symbols are useful in expansion and +compilation to avoid collisions with symbols that appear in the +source; they are usually not generated directly, but they can appear +in the result of functions like identifier-binding.

Interned and unreadable symbols are only weakly held by the internal +symbol table. This weakness can never affect the result of an +eq?, eqv?, or equal? test, but a symbol may +disappear when placed into a weak box (see Weak Boxes), used as +the key in a weak hash table (see Hash Tables), or +used as an ephemeron key (see Ephemerons).

See Reading Symbols + for information on reading + symbols and Printing Symbols + for information on printing symbols.

procedure

(symbol? v)  boolean?

  v : any/c
Returns #t if v is + a symbol, #f otherwise.

Examples:
> (symbol? 'Apple)

#t

> (symbol? 10)

#f

procedure

(symbol-interned? sym)  boolean?

  sym : symbol?
Returns #t if sym is + interned, #f otherwise.

Examples:

procedure

(symbol-unreadable? sym)  boolean?

  sym : symbol?
Returns #t if sym is + an unreadable symbol, #f otherwise.

Examples:

procedure

(symbol->string sym)  string?

  sym : symbol?
Returns a freshly + allocated mutable string whose characters are the same as in + sym.

See also symbol->immutable-string from +racket/symbol.

Example:
> (symbol->string 'Apple)

"Apple"

procedure

(string->symbol str)  symbol?

  str : string?
Returns an + interned symbol whose characters are the same as in + str.

Examples:
> (string->symbol "Apple")

'Apple

> (string->symbol "1")

'|1|

procedure

(string->uninterned-symbol str)  symbol?

  str : string?
Like + (string->symbol str), but the resulting symbol is a new + uninterned symbol. Calling string->uninterned-symbol + twice with the same str returns two distinct symbols.

Examples:
> (string->uninterned-symbol "Apple")

'Apple

> (eq? 'a (string->uninterned-symbol "a"))

#f

> (eq? (string->uninterned-symbol "a")
       (string->uninterned-symbol "a"))

#f

procedure

(string->unreadable-symbol str)  symbol?

  str : string?
Like + (string->symbol str), but the resulting symbol is a new + unreadable symbol. Calling string->unreadable-symbol + twice with equivalent strs returns the same symbol, but + read never produces the symbol.

Examples:
> (string->unreadable-symbol "Apple")

'Apple

> (eq? 'a (string->unreadable-symbol "a"))

#f

> (eq? (string->unreadable-symbol "a")
       (string->unreadable-symbol "a"))

#t

procedure

(gensym [base])  symbol?

  base : (or/c string? symbol?) = "g"
Returns a +new uninterned symbol with an automatically-generated name. The +optional base argument is a prefix symbol or string.

Example:
> (gensym "apple")

'apple9289506

procedure

(symbol<? a-sym b-sym ...)  boolean?

  a-sym : symbol?
  b-sym : symbol?
Returns #t if the arguments are sorted, where the comparison +for each pair of symbols is the same as using +symbol->string with string->bytes/utf-8 and +bytes<?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.7.1 Additional Symbol Functions

 (require racket/symbol) package: base
The bindings documented in this section are provided by the racket/symbol and racket libraries, but not racket/base.

Added in version 7.6 of package base.

procedure

(symbol->immutable-string sym)  (and/c string? immutable?)

  sym : symbol?
Like symbol->string, but the result is an immutable string, +not necessarily freshly allocated.

Examples:

Added in version 7.6 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/sync.html b/clones/docs.racket-lang.org/reference/sync.html new file mode 100644 index 00000000..032a1ce9 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/sync.html @@ -0,0 +1,144 @@ + +11.2.1 Events
11.2.1 Events

A synchronizable event (or just event for short) +works with the sync procedure to coordinate synchronization +among threads. Certain kinds of objects double as events, including +ports and threads. Other kinds of objects exist only for their use as +events. Racket’s event system is based on Concurrent ML [Reppy99].

At any point in time, an event is either ready for +synchronization, or it is not; depending on the kind of event and how +it is used by other threads, an event can switch from not ready to +ready (or back), at any time. If a thread synchronizes on an event +when it is ready, then the event produces a particular +synchronization result.

Synchronizing an event may affect the state of the event. For example, +when synchronizing a semaphore, then the semaphore’s internal count is +decremented, just as with semaphore-wait. For most kinds of +events, however (such as a port), synchronizing does not modify the +event’s state.

Racket values that act as synchronizable events include +asynchronous channels, +channels, +custodian boxes, +log receivers, +place channels, +ports, +semaphores, +subprocesses, +TCP listeners, +threads, and +will executors. +Libraries can define new synchronizable events, especially +though prop:evt.

procedure

(evt? v)  boolean?

  v : any/c
Returns #t if v is a synchronizable event, +#f otherwise.

Examples:
> (evt? never-evt)

#t

> (evt? (make-channel))

#t

> (evt? 5)

#f

procedure

(sync evt ...)  any

  evt : evt?
Blocks as long as none of the synchronizable events +evts are ready, as defined above.

When at least one evt is ready, its synchronization +result (often evt itself) is returned. If multiple +evts are ready, one of the evts is chosen +pseudo-randomly for the result; the +current-evt-pseudo-random-generator parameter sets the +random-number generator that controls this choice.

Examples:
> (define ch (make-channel))
> (thread (λ () (displayln (sync ch))))

#<thread>

> (channel-put ch 'hellooooo)

hellooooo

Changed in version 6.1.0.3 of package base: Allow 0 arguments instead of 1 or more.

procedure

(sync/timeout timeout evt ...)  any

  timeout : (or/c #f (and/c real? (not/c negative?)) (-> any))
  evt : evt?
Like sync if timeout is #f. If +timeout is a real number, then the result is #f +if timeout seconds pass without a +successful synchronization. If timeout is a procedure, then +it is called in tail position if polling the evts discovers +no ready events.

A zero value for timeout is equivalent to (lambda () #f). In either case, each evt is checked at least once +before returning #f or calling timeout.

See also alarm-evt for an alternative timeout mechanism.

Examples:
; times out before waking up
> (sync/timeout
   0.5
   (thread (λ () (sleep 1) (displayln "woke up!"))))

#f

> (sync/timeout
   (λ () (displayln "no ready events"))
   never-evt)

no ready events

Changed in version 6.1.0.3 of package base: Allow 1 argument instead of 2 or more.

procedure

(sync/enable-break evt ...)  any

  evt : evt?
Like sync, but breaking is enabled (see +Breaks) while waiting on the evts. If +breaking is disabled when sync/enable-break is called, then +either all evts remain unchosen or the exn:break +exception is raised, but not both.

procedure

(sync/timeout/enable-break timeout evt ...)  any

  timeout : (or/c #f (and/c real? (not/c negative?)) (-> any))
  evt : evt?
Like sync/enable-break, but with a timeout as for sync/timeout.

procedure

(choice-evt evt ...)  evt?

  evt : evt?
Creates and returns a single event that combines the +evts. Supplying the result to sync is the same as +supplying each evt to the same call.

That is, an event returned by choice-evt is ready for +synchronization when one or more of the evts supplied to +choice-evt are ready for synchronization. If the +choice event is chosen, one of its ready evts is chosen +pseudo-randomly, and the synchronization result is the chosen +evt’s synchronization result.

Examples:
> (define ch1 (make-channel))
> (define ch2 (make-channel))
> (define either-channel (choice-evt ch1 ch2))
> (thread (λ () (displayln (sync either-channel))))

#<thread>

> (channel-put
   (if (> (random) 0.5) ch1 ch2)
   'tuturuu)

tuturuu

procedure

(wrap-evt evt wrap)  evt?

  evt : evt?
  wrap : (any/c ... . -> . any)
Creates an event that is ready for synchronization when +evt is ready for synchronization, but whose +synchronization result is determined by applying wrap +to the synchronization result of evt. The number +of arguments accepted by wrap must match the number of values +for the synchronization result of evt.

The call to wrap is +parameterize-breaked to disable breaks initially.

Examples:
> (define ch (make-channel))
> (define evt (wrap-evt ch (λ (v) (format "you've got mail: ~a" v))))
> (thread (λ () (displayln (sync evt))))

#<thread>

> (channel-put ch "Dear Alice ...")

you've got mail: Dear Alice ...

procedure

(handle-evt evt handle)  handle-evt?

  evt : evt?
  handle : (any/c ... . -> . any)
Like wrap-evt, except that handle is called in tail +position with respect to the synchronization request—and without +breaks explicitly disabled—when it is not wrapped by wrap-evt, +chaperone-evt, or another handle-evt.

Examples:
> (define msg-ch (make-channel))
> (define exit-ch (make-channel))
> (thread
   (λ ()
     (let loop ([val 0])
       (printf "val = ~a~n" val)
       (sync (handle-evt
              msg-ch
              (λ (val) (loop val)))
             (handle-evt
              exit-ch
              (λ (val) (displayln val)))))))

val = 0

#<thread>

> (channel-put msg-ch 5)

val = 5

> (channel-put msg-ch 7)

val = 7

> (channel-put exit-ch 'done)

done

procedure

(guard-evt maker)  evt?

  maker : (-> (or/c evt? any/c))
Creates a value that behaves as an event, but that is actually an +event maker.

An event guard returned by guard-evt generates an +event when guard is used with sync +(or whenever it is part of a choice event used with sync, +etc.), where the generated event is the result of calling +maker. The maker procedure may be called by +sync at most once for a given call to sync, but +maker may not be called if a ready event is chosen before +guard is even considered.

If maker returns a non-event, then maker’s +result is replaced with an event that is ready for +synchronization and whose synchronization result is +guard.

procedure

(nack-guard-evt maker)  evt?

  maker : (evt? . -> . (or/c evt? any/c))
Like guard-evt, but when maker is called, it is +given a NACK (“negative acknowledgment”) event. After starting the +call to maker, if the event from maker is not +ultimately chosen as the ready event, then the NACK event supplied to +maker becomes ready for synchronization with a +#<void> value.

The NACK event becomes ready for synchronization when the event +is abandoned when either some other event is chosen, the synchronizing +thread is dead, or control escapes from the call to sync +(even if nack-guard’s maker has not yet returned a +value). If the event returned by maker is chosen, then the +NACK event never becomes ready for synchronization.

procedure

(poll-guard-evt maker)  evt?

  maker : (boolean? . -> . (or/c evt? any/c))
Like guard-evt, but when maker is called, it is +provided a boolean value that indicates whether the event will be used +for a poll, #t, or for a blocking synchronization, +#f.

If #t is supplied to maker, if breaks are +disabled, if the polling thread is not terminated, and if polling the +resulting event produces a synchronization result, then the event +will certainly be chosen for its result.

procedure

(replace-evt evt maker)  evt?

  evt : evt?
  maker : (any/c ... . -> . (or/c evt? any/c))
Like guard-evt, but maker is called only after +evt becomes ready for synchronization, and the +synchronization result of evt is passed to maker.

The attempt to synchronize on evt proceeds concurrently as +the attempt to synchronize on the result guard from +replace-evt; despite that concurrency, if maker is +called, it is called in the thread that is synchronizing on +guard. Synchronization can succeed for both evt and +another synchronized with guard at the same time; the +single-choice guarantee of synchronization applies only to the result +of maker and other events synchronized with guard.

If maker returns a non-event, then maker’s +result is replaced with an event that is ready for +synchronization and whose synchronization result is +guard.

Added in version 6.1.0.3 of package base.

value

always-evt : evt?

A constant event that is always ready +for synchronization, with itself as its synchronization result.

Example:
> (sync always-evt)

#<always-evt>

value

never-evt : evt?

A constant event that is never ready +for synchronization.

Example:

procedure

(system-idle-evt)  evt?

Returns an event that is ready for synchronization when the +system is otherwise idle: if the result event were replaced by +never-evt, no thread in the system would be available to run. +In other words, all threads must be suspended or blocked on events +with timeouts that have not yet expired. The system-idle event’s +synchronization result is #<void>. The result of the +system-idle-evt procedure is always the same event.

Examples:
> (define th (thread (λ () (let loop () (loop)))))
> (sync/timeout 0.1 (system-idle-evt))

#f

> (kill-thread th)
> (sync (system-idle-evt))

procedure

(alarm-evt msecs [monotonic?])  evt?

  msecs : real?
  monotonic? : any/c = #f
Returns a synchronizable event that is not ready for synchronization when +(milliseconds) would return a value that is +less than msecs, and it is ready for synchronization when +(milliseconds) would return a value that is +more than msecs. The value of milliseconds is +current-inexact-milliseconds when monotonic? is #f, +or current-inexact-monotonic-milliseconds otherwise. The synchronization result of a alarm event is the alarm event itself.

Examples:
> (define alarm (alarm-evt (+ (current-inexact-milliseconds) 100)))
> (sync alarm)

#<alarm-evt>

Changed in version 8.3.0.9 of package base: Added the monotonic? argument.

procedure

(handle-evt? evt)  boolean?

  evt : evt?
Returns #t if evt was created by handle-evt +or by choice-evt applied to another event for which +handle-evt? produces #t. For any other event, +handle-evt? produces #f.

Examples:

A structure type property that identifies structure types whose + instances can serve as synchronizable events. The property value can + be any of the following:

  • An event evt: In this case, using the structure as an +event is equivalent to using evt.

  • A procedure proc of one argument: In this case, the +structure is similar to an event generated +by guard-evt, except that the would-be guard +procedure proc receives the structure as an argument, instead +of no arguments; also, a non-event result from proc +is replaced with an event that is already ready for synchronization +and whose synchronization result is the structure.

  • An exact, non-negative integer between 0 (inclusive) +and the number of non-automatic fields in the structure type +(exclusive, not counting supertype fields): The integer identifies a +field in the structure, and the field must be designated as +immutable. If the field contains an object or an event-generating +procedure of one argument, the event or procedure is used as +above. Otherwise, the structure acts as an event that is never +ready.

For working with foreign libraries, a prop:evt +value can also be a result of unsafe-poller, +although that possibility is omitted from the safe +contract of prop:evt.

Instances of a structure type with the prop:input-port or +prop:output-port property are also synchronizable events by virtue +of being a port. If the structure type has more than one of +prop:evt, prop:input-port, and +prop:output-port, then the prop:evt value (if any) +takes precedence for determining the instance’s behavior as an event, +and the prop:input-port property takes precedence over +prop:output-port for synchronization.

Examples:
> (struct wt (base val)
    #:property prop:evt (struct-field-index base))
> (define sema (make-semaphore))
> (sync/timeout 0 (wt sema #f))

#f

> (semaphore-post sema)
> (sync/timeout 0 (wt sema #f))

#<semaphore>

> (semaphore-post sema)
> (sync/timeout 0 (wt (lambda (self) (wt-val self)) sema))

#<semaphore>

> (semaphore-post sema)
> (define my-wt (wt (lambda (self)
                      (wrap-evt
                       (wt-val self)
                       (lambda (x) self)))
                    sema))
> (sync/timeout 0 my-wt)

#<wt>

> (sync/timeout 0 my-wt)

#f

A parameter that determines the pseudo-random number generator used by +sync for events created by choice-evt.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/syntax-model.html b/clones/docs.racket-lang.org/reference/syntax-model.html new file mode 100644 index 00000000..6da88917 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/syntax-model.html @@ -0,0 +1,655 @@ + +1.2 Syntax Model

1.2 Syntax Model

The syntax of a Racket program is defined by

  • a read pass that processes a character stream into a +syntax object; and

  • an expand pass that processes a syntax object to +produce one that is fully parsed.

For details on the read pass, see The Reader. Source +code is normally read in read-syntax mode, which produces a +syntax object.

The expand pass recursively processes a syntax object +to produce a complete parse of the program. Binding +information in a syntax object drives the expansion +process, and when the expansion process encounters a +binding form, it extends syntax objects for sub-expressions with +new binding information.

1.2.1 Identifiers, Binding, and Scopes

+Identifiers and Binding in The Racket Guide introduces binding.

An identifier is a source-program entity. Parsing (i.e., +expanding) a Racket program reveals that some identifiers +correspond to variables, some refer to syntactic forms +(such as lambda, which is the syntactic form for +functions), some refer to transformers for macro expansion, and +some are quoted to produce symbols or syntax objects. An +identifier binds another (i.e., it is a binding) +when the former is parsed as a variable or syntactic form and +the latter is parsed as a reference to the former; the +latter is bound.

For example, as a fragment of source, the text

(let ([x 5]) x)

includes two identifiers: let and x (which +appears twice). When this source is parsed in a context where +let has its usual meaning, the first x binds +the second x.

Bindings and references are determined through scope sets. A +scope corresponds to a region of the program that is either +in part of the source or synthesized through elaboration of the +source. Nested binding contexts (such as nested functions) create +nested scopes, while macro expansion creates scopes that +overlap in more complex ways. Conceptually, each scope is +represented by a unique token, but the token is not directly +accessible. Instead, each scope is represented by a value that +is internal to the representation of a program.

A form is a fragment of a program, such as an identifier or +a function call. A form is represented as a syntax +object, and each syntax object has an associated set of scopes +(i.e., a scope set). In the above example, +the representations of the xs include the scope that +corresponds to the let form.

When a form parses as the binding of a particular identifier, +parsing updates a global table that maps a combination of an +identifier’s symbol and scope set to its meaning: a +variable, a syntactic form, or a transformer. An +identifier refers to a particular binding when the reference’s symbol +and the identifier’s symbol are the same, and when the reference’s +scope set is a superset of the binding’s +scope set. For a given identifier, multiple bindings may have +scope sets that are subsets of the identifier’s; in that case, +the identifier refers to the binding whose set is a superset of all +others; if no such binding exists, the reference is ambiguous (and triggers a syntax +error if it is parsed as an expression). A binding shadows +any binding (i.e., it is shadowing any binding) +with the same symbol but a subset of scopes.

For example, in

(let ([x 5]) x)

in a context where let corresponds to the usual +syntactic form, the parsing of let introduces a new +scope for the binding of x. Since the second x +receives that scope as part of the let body, the first +x binds the second x. In the more complex +case

(let ([x 5])
  (let ([x 6])
    x))

the inner let creates a second scope for the second +x, so its scope set is a superset of the first +x’s scope setwhich means that the binding for the +second x shadows the one for the first x, and +the third x refers to the binding created by the second one.

A top-level binding is a binding from a definition at +the top-level; a module binding is a binding from a +definition in a module; all other bindings are local +bindings. Within a module, references to top-level bindings +are disallowed. An identifier without a binding is unbound.

Throughout the documentation, identifiers are typeset to +suggest the way that they are parsed. A hyperlinked identifier +like lambda indicates a reference to a syntactic form or +variable. A plain identifier like x is a +variable or a reference to an unspecified top-level +variable.

Every binding has a phase level in which it can be +referenced, where a phase level normally corresponds to an +integer (but the special label phase level does not +correspond to an integer). Phase level 0 corresponds to the +run time of the enclosing module (or the run time of top-level +expressions). Bindings in phase level 0 constitute the +base environment. Phase level 1 corresponds to the +time during which the enclosing module (or top-level expression) is +expanded; bindings in phase level 1 constitute the +transformer environment. Phase level -1 corresponds to the +run time of a different module for which the enclosing module is +imported for use at phase level 1 (relative to the importing +module); bindings in phase level -1 constitute the +template environment. The label phase level does not +correspond to any execution time; it is used to track bindings (e.g., +to identifiers within documentation) without implying an execution +dependency.

An identifier can have different bindings in different phase +levels. More precisely, the scope set associated with a +form can be different at different phase levels; a top-level or +module context implies a distinct scope at every phase level, while +scopes from macro expansion or other syntactic forms are added to a +form’s scope sets at all phases. The context of each binding +and reference determines the phase level whose scope set is +relevant.

A binding space is a convention that distinguishes bindings +by having a specific scope for the space; an identifier is +“bound in a space” if its binding includes the space’s scope in its +scope set. A space’s scope is accessed indirectly by using +make-interned-syntax-introducer; that is, a space is just the +set of bindings with a scope that is interned with that space’s name, +where the default binding space corresponds to having no +interned scopes. The require and provide forms +include support for bindings spaces through subforms like +for-space and only-space-in. No other forms provided +by the racket module bind or reference identifier in a +specified space; such forms are intended to be implemented by new +macros. By convention, when an identifier is bound in a space, a +corresponding identifier also should be bound in the default binding +space; that convention helps avoid mismatches between imports or +mismatches due to local bindings that shadow only in some spaces.

Changed in version 6.3 of package base: Changed local bindings to have a +specific phase level, like top-level +and module bindings.
Changed in version 8.2.0.3: Added binding spaces.

1.2.2 Syntax Objects

+Syntax Objects in The Racket Guide introduces the use of syntax objects.

A syntax object combines a simpler Racket value, such as a symbol or pair, with +lexical information, source-location information, syntax properties, and +whether the syntax object is +tainted. The lexical information of a syntax object comprises a set of scope +sets, one for each phase level. In particular, an identifier is represented as a syntax +object containing a symbol, and its lexical information can be combined with the global +table of bindings to determine its binding (if any) at each phase level.

For example, a car identifier might have +lexical information that designates it as the car from +the racket/base language (i.e., the built-in +car). Similarly, a lambda identifier’s +lexical information may indicate that it represents a procedure +form. Some other identifier’s lexical information may +indicate that it references a top-level variable.

When a syntax object represents a more complex expression than +an identifier or simple constant, its internal components can +be extracted. Even for extracted identifiers, detailed information +about binding is available mostly indirectly; two identifiers can be +compared to determine whether they refer to the same binding (i.e., +free-identifier=?), or whether the identifiers have the same +scope set so that each identifier would bind the +other if one were in a binding position and the other in an expression +position (i.e., bound-identifier=?).

For example, when the program written as

(let ([x 5]) (+ x 6))

is represented as a syntax object, then two syntax +objects can be extracted for the two xs. Both the +free-identifier=? and bound-identifier=? predicates +will indicate that the xs are the same. In contrast, the +let identifier is not free-identifier=? or +bound-identifier=? to either x.

The lexical information in a syntax object is +independent of the rest of the syntax object, and it can be copied to a new syntax +object in combination with an arbitrary other Racket value. Thus, +identifier-binding information in a syntax object is +predicated on the symbolic name of the identifier as well as +the identifier’s lexical information; the same question with +the same lexical information but different base value can +produce a different answer.

For example, combining the lexical information from let in +the program above to 'x would not produce an identifier that +is free-identifier=? to either x, since it does not +appear in the scope of the x binding. Combining the lexical +context of the 6 with 'x, in contrast, would produce +an identifier that is bound-identifier=? to both xs.

The quote-syntax form bridges the evaluation of a program and +the representation of a program. Specifically, (quote-syntax datum #:local) produces a syntax object that preserves all of the +lexical information that datum had when it was parsed as +part of the quote-syntax form. Note that the +(quote-syntax datum) form is similar, but it removes certain +scopes from the datum’s scope sets; +see quote-syntax for more information.

1.2.3 Expansion (Parsing)

Expansion recursively processes a syntax object in a +particular phase level, starting with phase level 0. Bindings +from the syntax object’s lexical information drive the +expansion process, and cause new bindings to be introduced for the +lexical information of sub-expressions. In some cases, a +sub-expression is expanded in a phase deeper (having a +bigger phase level number) than the enclosing expression.

1.2.3.1 Fully Expanded Programs

A complete expansion produces a syntax object matching the +following grammar:

Beware that the symbolic names of identifiers in a fully +expanded program may not match the symbolic names in the grammar. Only +the binding (according to free-identifier=?) matters.

  top-level-form = general-top-level-form
  | (#%expression expr)
  | 
(module id module-path
  (#%plain-module-begin
   module-level-form ...))
  | (begin top-level-form ...)
  | (begin-for-syntax top-level-form ...)
     
  module-level-form = general-top-level-form
  | (#%provide raw-provide-spec ...)
  | (begin-for-syntax module-level-form ...)
  | submodule-form
  | (#%declare declaration-keyword ...)
     
  submodule-form = 
(module id module-path
  (#%plain-module-begin
   module-level-form ...))
  | 
(module* id module-path
  (#%plain-module-begin
   module-level-form ...))
  | 
(module* id #f
  (#%plain-module-begin
   module-level-form ...))
     
  general-top-level-form = expr
  | (define-values (id ...) expr)
  | (define-syntaxes (id ...) expr)
  | (#%require raw-require-spec ...)
     
  expr = id
  | (#%plain-lambda formals expr ...+)
  | (case-lambda (formals expr ...+) ...)
  | (if expr expr expr)
  | (begin expr ...+)
  | (begin0 expr expr ...)
  | 
(let-values ([(id ...) expr] ...)
  expr ...+)
  | 
(letrec-values ([(id ...) expr] ...)
  expr ...+)
  | (set! id expr)
  | (quote datum)
  | (quote-syntax datum)
  | (quote-syntax datum #:local)
  | (with-continuation-mark expr expr expr)
  | (#%plain-app expr ...+)
  | (#%top . id)
  | (#%variable-reference id)
  | (#%variable-reference (#%top . id))
  | (#%variable-reference)
     
  formals = (id ...)
  | (id ...+ . id)
  | id

A fully-expanded syntax object corresponds to a parse +of a program (i.e., a parsed program), and lexical +information on its identifiers indicates the +parse.

More specifically, the typesetting of identifiers in the above grammar +is significant. For example, the second case for expr is a +syntax-object list whose first element is an identifier, +where the identifier’s lexical information specifies a +binding to the #%plain-lambda of the +racket/base language (i.e., the identifier is +free-identifier=? to one whose binding is +#%plain-lambda). In all cases, identifiers above typeset as +syntactic-form names refer to the bindings defined in +Syntactic Forms.

In a fully expanded program for a namespace whose base phase is +0, the relevant phase level for a binding in the program is +N if the binding has N surrounding +begin-for-syntax and/or define-syntaxes forms—not +counting any begin-for-syntax forms that wrap a +module or module* form for the body of the module +or module*, unless a module* form has #f in place +of a module-path after the id. The +datum in a quote-syntax form +preserves its information for all phase levels.

A reference to a local binding in a fully expanded program has +a scope set that matches its binding identifier exactly. +Additional scopes, if any, are removed. As a result, +bound-identifier=? can be used to correlate local binding +identifiers with reference identifiers, while +free-identifier=? must be used to relate references to +module bindings or top-level bindings.

In addition to the grammar above, #%expression can appear in +a fully local-expanded expression position. For example, +#%expression can appear in the result from +local-expand when the stop list is empty. +Reference-identifier scope sets are reduced in local-expanded +expressions only when the local-expand stop list is empty.

Changed in version 6.3 of package base: Added the #:local variant of +quote-syntax; removed +letrec-syntaxes+values from +possibly appearing in a fully +local-expanded form.

1.2.3.2 Expansion Steps

In a recursive expansion, each single step in expanding a syntax +object at a particular phase level depends on the immediate shape of +the syntax object being expanded:

Thus, the possibilities that do not fail lead to an identifier +with a particular binding. This binding refers to one of three +things:

When a #%top, #%app, or +#%datum identifier is added by the expander, it is +given implicit-made-explicit properties: an +'implicit-made-explicit syntax property whose value is +#t, and a hidden property to indicate that the implicit +identifier is original in the sense of syntax-original? if +the syntax object that gives the identifier its lexical information +has that property.

Changed in version 7.9.0.13 of package base: Added implicit-made-explicit +properties.

1.2.3.3 Expansion Context

Each expansion step occurs in a particular context, and +transformers and core syntactic forms may expand differently for +different contexts. For example, a module form is +allowed only in a top-level context or module context, and it fails in other +contexts. The possible contexts are as follows:

  • top-level context : outside of any module, definition, or +expression, except that sub-expressions of a top-level +begin form are also expanded as top-level forms.

  • module-begin context : inside the body of a module, as the +only form within the module.

  • module context : in the body of a module (inside the +module-begin layer).

  • internal-definition context : in a nested context that allows +both definitions and expressions.

  • expression context : in a context where only +expressions are allowed.

Different core syntactic forms parse sub-forms using different +contexts. For example, a let form always parses the +right-hand expressions of a binding in an expression context, +but it starts parsing the body in an internal-definition +context.

1.2.3.4 Introducing Bindings

Bindings are introduced during expansion when certain +core syntactic forms are encountered:

For example, in

(let-values ([(x) 10]) (+ x y))

the binding introduced for x applies to the x in the +body, because a fresh scope is created and added to both the binding +x and reference x. The same scope is added to the +y, but since it has a different symbol than the binding +x, it does not refer to the new binding. Any x +outside of this let-values form does not receive the fresh +scope and therefore does not refer to the new binding.

1.2.3.5 Transformer Bindings

In a top-level context or module context, when the +expander encounters a define-syntaxes form, the binding that +it introduces for the defined identifiers is a transformer +binding. The value of the binding exists at expansion +time, rather than run time (though the two times can overlap), though +the binding itself is introduced with phase level 0 (i.e., in +the base environment).

The value for the binding is obtained by evaluating the +expression in the define-syntaxes form. This expression must +be expanded (i.e., parsed) before it can be evaluated, and it is +expanded at phase level 1 (i.e., in the transformer +environment) instead of phase level 0.

If the resulting value is a procedure of one argument or +the result of make-set!-transformer on a procedure, then it +is used as a syntax transformer (a.k.a. macro). +The procedure is expected to accept a syntax object and return a +syntax object. A use of the binding (at phase level 0) triggers +a call of the syntax transformer by the expander; see +Expansion Steps.

Before the expander passes a syntax object to a transformer, +the syntax object is extended with a fresh macro-introduction scope +(that applies to all sub-syntax objects) to distinguish syntax objects +at the macro’s use site from syntax objects that are introduced by the macro; +in the result of the transformer the presence of the scope is +flipped, so that introduced syntax objects retain the scope, +and use-site syntax objects do not have it. In addition, if +the use of a transformer is in the same definition context as its binding, +the use-site syntax object is extended with an additional fresh +use-site scope that is not flipped in the transformer’s result, +so that only use-site syntax objects have the use-site scope.

The scope-introduction process for macro expansion helps keep +binding in an expanded program consistent with the lexical structure +of the source program. For example, the expanded form of the program

(define x 12)
(define-syntax m
  (syntax-rules ()
    [(_ id) (let ([x 10]) id)]))
(m x)

is

(define x 12)
(define-syntax m ....)
(let ([x 10]) x)

However, the result of the last expression is 12, not +10. The reason is that the transformer bound to m +introduces the binding x, but the referencing x is +present in the argument to the transformer. The introduced x +is left with one fresh scope, while the reference x has a different fresh scope, +so the binding x is not bound-identifier=? to the +body x.

A use-site scope on a binding identifier is ignored when the +definition is in the same context where the use-site scope was +introduced. This special treatment of use-site scopes allows a +macro to expand to a visible definition. For example, the expanded +form of the program

(define-syntax m
  (syntax-rules ()
    [(_ id) (define id 5)]))
(m x)
x

is

(define-syntax m ....)
(define x 5)
x

where the x in the define form has a use-site +scope that is not present on the final x. The final +x nevertheless refers to the definition, because the +use-site scope is effectively removed before installing the +definition’s binding. In contrast, the expansion of

(define-syntax m
  (syntax-rules ()
    [(_ id) (let ([x 4])
              (let ([id 5])
                x))]))
(m x)

is

(define-syntax m ....)
(let ([x 4])
  (let ([x 5])
    x))

where the second x has a use-site scope that prevents +it from binding the final x. The use-site scope is not +ignored in this case, because the binding is not part of the definition +context where (m x) was expanded.

The set! form works with the make-set!-transformer +and prop:set!-transformer property to support +assignment transformers that transform set! +expressions. An assignment transformer contains a procedure +that is applied by set! in the same way as a normal +transformer by the expander.

The make-rename-transformer procedure or +prop:rename-transformer property creates a value that is also +handled specially by the expander and by set! as a +transformer binding’s value. When id is bound to a +rename transformer produced by +make-rename-transformer, it is replaced with the target +identifier passed to make-rename-transformer. In addition, as +long as the target identifier does not have a true value for the +'not-free-identifier=? syntax property, the +binding table is extended to indicate that id is an alias +for the identifier in the rename transformer. The +free-identifier=? function follows aliasing chains to determine +equality of bindings, the identifier-binding function +similarly follows aliasing chains, and the provide form +exports id as the target identifier. Finally, the +syntax-local-value function follows rename transformer +chains even when binding aliases are not installed.

In addition to using scopes to track introduced identifiers, the +expander tracks the expansion history of a form through syntax +properties such as 'origin. See Syntax Object Properties for +more information.

The expander’s handling of letrec-syntaxes+values is similar +to its handling of define-syntaxes. A +letrec-syntaxes+values can be expanded in an arbitrary phase +level n (not just 0), in which case the expression for the +transformer binding is expanded at phase level n+1.

The expressions in a begin-for-syntax form are expanded and +evaluated in the same way as for define-syntaxes. However, +any introduced bindings from definition within +begin-for-syntax are at phase level 1 (not a +transformer binding at phase level 0).

1.2.3.6 Local Binding Context

Although the binding of an identifier can be uniquely determined from the combination of +its lexical information and the global binding table, the expander also maintains a +local binding context that records additional information about local bindings to +ensure they are not used outside of the lexical region in which they are bound.

Due to the way local binding forms like let add a fresh scope to both bound +identifiers and body forms, it isn’t ordinarily possible for an identifier to reference +a local binding without appearing in the body of the let. However, if macros use +compile-time state to stash bound identifiers, or use local-expand to extract +identifiers from an expanded binding form, they can violate this constraint. For example, the +following stash-id and unstash-id macros cooperate to move a reference to a +locally-bound x identifier outside of the lexical region in which it is bound:

> (begin-for-syntax
    (define stashed-id #f))
> (define-syntax (stash-id stx)
    (syntax-case stx ()
      [(_ id)
       (begin
         (set! stashed-id #'id)
         #'(void))]))
> (define-syntax (unstash-id stx)
    stashed-id)
> (let ([x 42])
    (stash-id x)
    (unstash-id))

42

> (unstash-id)

eval:5:0: x: identifier used out of context

  in: x

In general, an identifier’s lexical information is not sufficient to know whether or not +its binding is available in the enclosing context, since the scope set for the +identifier stored in stashed-id unambiguously refers to a binding in the global +binding table. This can be observed by the fact that identifier-binding produces +'lexical, not #f:

> (define-syntax (stashed-id-binding stx)
    #`'#,(identifier-binding stashed-id))
> (stashed-id-binding)

'lexical

However, the reference produced by (unstash-id) in the above program is still illegal, even +if it isn’t technically unbound. To record the fact that x’s binding is in scope only +within the body of its corresponding let form, the expander adds x’s binding +to the local binding context while expanding the let body. More generally, the +expander adds all local variable bindings to the local binding context while +expanding expressions in which a reference to the variable would be legal. When the expander +encounters an identifier bound to a local variable, and the associated binding is +not in the current local binding context, it raises a syntax error.

The local binding context also tracks local transformer bindings (i.e. bindings +bound by forms like let-syntax) in a similar way, except that the context also stores the +compile-time value associated with the transformer. When an identifier that is locally +bound as a transformer is used in application position as a syntax transformer, or its +compile-time value is looked up using syntax-local-value, the local binding context is +consulted to retrieve the value. If the binding is in scope, its associated compile-time value +is used; otherwise, the expander raises a syntax error.

Examples:
> (define-syntax (stashed-id-local-value stx)
    #`'#,(syntax-local-value stashed-id))
> (let-syntax ([y 42])
    (stash-id y)
    (stashed-id-local-value))

42

> (stashed-id-local-value)

syntax-local-value: identifier is not bound to syntax:

#<syntax:eval:11:0 y>

1.2.3.7 Partial Expansion

In certain contexts, such as an internal-definition context or +module context, partial expansion is used to determine +whether forms represent definitions, expressions, or other declaration +forms. Partial expansion works by cutting off the normal recursive +expansion when the relevant binding is for a primitive syntactic form.

As a special case, when expansion would otherwise add an +#%app, #%datum, or #%top +identifier to an expression, and when the binding turns out to be the +primitive #%app, #%datum, or #%top form, +then expansion stops without adding the identifier.

1.2.3.8 Internal Definitions

An internal-definition context supports local definitions mixed +with expressions. Forms that allow internal definitions document such +positions using the body meta-variable. Definitions in an +internal-definition context are equivalent to local binding via +letrec-syntaxes+values; macro expansion converts internal +definitions to a letrec-syntaxes+values form.

Expansion relies on partial expansion of each body in +an internal-definition sequence. Partial expansion of each +body produces a form matching one of the following cases:

  • A define-values form: The binding table is immediately enriched +with bindings for the define-values form. Further +expansion of the definition is deferred, and partial expansion +continues with the rest of the body.

  • A define-syntaxes form: The right-hand side is +expanded and evaluated (as for a +letrec-syntaxes+values form), and a transformer +binding is installed for the body sequence before partial +expansion continues with the rest of the body.

  • A primitive expression form other than begin: Further +expansion of the expression is deferred, and partial expansion +continues with the rest of the body.

  • A begin form: The sub-forms of the begin are +spliced into the internal-definition sequence, and partial +expansion continues with the first of the newly-spliced forms +(or the next form, if the begin had no sub-forms).

After all body forms are partially expanded, if no definitions were +encountered, then the expressions are collected into a begin +form as the internal-definition context’s expansion. Otherwise, at +least one expression must appear after the last definition, and any +expr that appears between definitions is converted to +(define-values () (begin expr (values))); the definitions +are then converted to bindings in a letrec-syntaxes+values +form, and all expressions after the last definition become the body of +the letrec-syntaxes+values form.

Before partial expansion begins, expansion of an internal-definition +context begins with the introduction of a fresh outside-edge +scope on the content of the internal-definition context. This +outside-edge scope effectively identifies syntax objects that are +present in the original form. An inside-edge scope is also +created and added to the original content; furthermore, the +inside-edge scope is added to the result of any partial expansion. +This inside-edge scope ensures that all bindings introduced by the +internal-definition context have a particular scope in common.

1.2.3.9 Module Expansion, Phases, and Visits

Expansion of a module form proceeds in a similar way to +expansion of an internal-definition context: +an outside-edge scope is created for the original module +content, and an inside-edge scope is added to both the original +module and any form that appears during a partial expansion of the +module’s top-level forms to uncover definitions and imports.

A require form not only introduces bindings at +expansion time, but also visits the referenced module when +it is encountered by the expander. That is, the expander instantiates +any variables defined in the module within begin-for-syntax, +and it also evaluates all expressions for define-syntaxes +transformer bindings.

Module visits propagate through requires in the same +way as module instantiation. Moreover, when a module is +visited at phase 0, any module that it requires +for-syntax is instantiated at phase 1, while +further requires for-template leading back +to phase 0 causes the required module to be visited at +phase 0 (i.e., not instantiated).

During compilation, the top-level of module context is itself +implicitly visited. Thus, when the expander encounters +(require (for-syntax ....)), it immediately +instantiates the required module at phase 1, in addition +to adding bindings at phase level 1 (i.e., the +transformer environment). Similarly, the expander immediately +evaluates any form that it encounters within +begin-for-syntax.

Phases beyond 0 are visited on demand. For example, +when the right-hand side of a phase-0 let-syntax is to +be expanded, then modules that are available at phase 1 +are visited. More generally, initiating expansion at phase +n visits modules at phase n, which in turn +instantiates modules at phase n+1. These +visits and instantiations apply to available +modules in the enclosing namespace’s module registry; +a per-registry lock prevents multiple threads from concurrently +instantiating and visiting available modules. On-demand instantiation +of available modules uses the same reentrant lock as +namespace-call-with-registry-lock.

When the expander encounters require and (require (for-syntax ....)) within a module context, the resulting +visits and instantiations are specific to the expansion +of the enclosing module, and are kept separate from visits and +instantiations triggered from a top-level context or +from the expansion of a different module. Along the same lines, when a +module is attached to a namespace through +namespace-attach-module, modules that it requires +are transitively attached, but instances are attached only at +phases at or below the namespace’s base phase.

1.2.3.10 Macro-Introduced Bindings

When a top-level definition binds an identifier that originates from a + macro expansion, the definition captures only uses of the identifier + that are generated by the same expansion due to the fresh scope + that is generated for the expansion.

Examples:
> (define-syntax def-and-use-of-x
    (syntax-rules ()
      [(def-and-use-of-x val)
       ; x below originates from this macro:
       (begin (define x val) x)]))
> (define x 1)
> x

1

> (def-and-use-of-x 2)

2

> x

1

> (define-syntax def-and-use
    (syntax-rules ()
      [(def-and-use x val)
       ; "x" below was provided by the macro use:
       (begin (define x val) x)]))
> (def-and-use x 3)

3

> x

3

For a top-level definition (outside of a module), the order of + evaluation affects the binding of a generated definition for a + generated identifier use. If the use precedes the definition, then + the use is resolved with the bindings that are in place at that + point, which will not include the binding from the subsequently + macro-generated definition. (No such dependency on order occurs + within a module, since a module binding covers the entire module + body.) To support the declaration of an identifier before its use, + the define-syntaxes form avoids binding an identifier if the + body of the define-syntaxes declaration produces zero + results.

Examples:
> (define bucket-1 0)
> (define bucket-2 0)
> (define-syntax def-and-set!-use-of-x
    (syntax-rules ()
      [(def-and-set!-use-of-x val)
       (begin (set! bucket-1 x) (define x val) (set! bucket-2 x))]))
> (define x 1)
> (def-and-set!-use-of-x 2)
> x

1

> bucket-1

1

> bucket-2

2

> (define-syntax defs-and-uses/fail
    (syntax-rules ()
      [(def-and-use)
       (begin
         ; Initial reference to even precedes definition:
         (define (odd x) (if (zero? x) #f (even (sub1 x))))
         (define (even x) (if (zero? x) #t (odd (sub1 x))))
         (odd 17))]))
> (defs-and-uses/fail)

even: undefined;

 cannot reference an identifier before its definition

  in module: top-level

> (define-syntax defs-and-uses
    (syntax-rules ()
      [(def-and-use)
       (begin
         ; Declare before definition via no-values define-syntaxes:
         (define-syntaxes (odd even) (values))
         (define (odd x) (if (zero? x) #f (even (sub1 x))))
         (define (even x) (if (zero? x) #t (odd (sub1 x))))
         (odd 17))]))
> (defs-and-uses)

#t

Macro-generated require and provide + clauses also introduce and reference generation-specific bindings + (due to the added scope) with the same ordering effects as + for definitions. The bindings depend on the scope set attached + to specific parts of the form:

  • In require, for a require-spec of the form +(rename-in [orig-id bind-id]) or (only-in .... [orig-id bind-id]), the bind-id supplies the +scope set for the binding. In require for other +require-specs, the generator of the require-spec +determines the scope set.

  • In provide, for a provide-spec of the form +id, the exported identifier is the one that binds +id, but the +external name is the plain, symbolic part of id. The exceptions for +all-except-out are similarly determined, as is the orig-id binding of a +rename-out form, and plain symbols are used for the +external names. For all-defined-out, only identifiers with +definitions having only the scopes of +(all-defined-out) form are exported; the external name is +the plain symbol from the definition.

1.2.4 Compilation

Before expanded code is evaluated, it is first compiled. A +compiled form has essentially the same information as the +corresponding expanded form, though the internal representation +naturally dispenses with identifiers for syntactic forms and local +bindings. One significant difference is that a compiled form is almost +entirely opaque, so the information that it contains cannot be +accessed directly (which is why some identifiers can be dropped). At +the same time, a compiled form can be marshaled to and from a byte +string, so it is suitable for saving and re-loading code.

Although individual read, expand, compile, and evaluate operations are +available, the operations are often combined automatically. For +example, the eval procedure takes a syntax object and expands +it, compiles it, and evaluates it.

1.2.5 Namespaces

+See Namespaces for functions that +manipulate namespaces.

A namespace is both a starting point for parsing and a +starting point for running compiled code. A namespace +also has a module registry that maps module names to module +declarations (see Modules and Module-Level Variables). This registry is +shared by all phase levels, and it applies both to parsing and +to running compiled code.

As a starting point for parsing, a namespace provides scopes +(one per phase level, plus one that spans all phase +levels). Operations such as namespace-require create initial +bindings using the namespace’s scopes, and the further +expansion and evaluation in the namespace can create additional +bindings. Evaluation of a form with a namespace always adds the +namespace’s phase-specific scopes to the form and to the result +of expanding a top-level form; as a consequence, every binding identifier +has at least one scope. The namespace’s additional scope is added +only on request (e.g., by using eval as opposed to +eval-syntax); if requested, the additional scope is added at all +phase levels. Except for +namespaces generated by a module (see module->namespace), +every namespace uses the same scope as the one added to all +phase levels, while the scopes specific to a phase +level are always distinct.

As a starting point for evaluating compiled code, each namespace +encapsulates a distinct set of top-level variables at various +phases, as well as a potentially distinct set of module +instances in each phase. That is, even though module +declarations are shared for all phase levels, module instances +are distinct for each phase. Each namespace has a base +phase, which corresponds to the phase used by reflective operations +such as eval and dynamic-require. In particular, +using eval on a require form instantiates a +module in the namespace’s base phase.

After a namespace is created, module instances from existing +namespaces can be attached to the new namespace. In terms of the +evaluation model, top-level variables from different namespaces +essentially correspond to definitions with different prefixes, but +attaching a module uses the same prefix for the module’s definitions +in namespaces where it is attached. The first step in evaluating any +compiled expression is to link its top-level variable and module-level +variable references to specific variables in the namespace.

At all times during evaluation, some namespace is designated as the +current namespace. The current namespace has no particular +relationship, however, with the namespace that was used to expand the +code that is executing, or with the namespace that was used to link +the compiled form of the currently evaluating code. In particular, +changing the current namespace during evaluation does not change the +variables to which executing expressions refer. The current namespace +only determines the behavior of reflective operations to expand code +and to start evaluating expanded/compiled code.

Examples:
> (define x 'orig) ; define in the original namespace
; The following let expression is compiled in the original
; namespace, so direct references to x see 'orig.
> (let ([n (make-base-namespace)]) ; make new namespace
    (parameterize ([current-namespace n])
      (eval '(define x 'new)) ; evals in the new namespace
      (display x) ; displays 'orig
      (display (eval 'x)))) ; displays 'new

orignew

If an identifier is bound to syntax or to an import, then +defining the identifier as a variable shadows the syntax +or import in future uses of the environment. Similarly, if an +identifier is bound to a top-level variable, then +binding the identifier to syntax or an import shadows the variable; +the variable’s value remains unchanged, however, and may be accessible +through previously evaluated expressions.

Examples:
> (define x 5)
> (define (f) x)
> x

5

> (f)

5

> (define-syntax x (syntax-id-rules () [_ 10]))
> x

10

> (f)

5

> (define x 7)
> x

7

> (f)

7

> (module m racket (define x 8) (provide x))
> (require 'm)
> x

8

> (f)

7

Like a top-level namespace, each module form has an +associated scope to span all phase levels of the +module’s content, plus a scope at each phase level. The +latter is added to every form, original or appearing through partial +macro expansion, within the module’s immediate body. Those same scopes +are propagated to a namespace created by module->namespace +for the module. Meanwhile, parsing of a module form begins by +removing the all scopes that correspond to the enclosing top-level or +(in the case of submodules) module and +module* forms.

1.2.6 Inferred Value Names

To improve error reporting, names are inferred at compile-time for +certain kinds of values, such as procedures. For example, evaluating +the following expression:

(let ([f (lambda () 0)]) (f 1 2 3))

produces an error message because too many arguments are provided to +the procedure. The error message is able to report f as +the name of the procedure. In this case, Racket decides, at +compile-time, to name as 'f all procedures created by the +let-bound lambda.

+See procedure-rename to override a procedure’s +inferred name at runtime.

Names are inferred whenever possible for procedures. Names closer to +an expression take precedence. For example, in

(define my-f
  (let ([f (lambda () 0)]) f))

the procedure bound to my-f will have the inferred name +'f.

When an 'inferred-name property is attached to a +syntax object for an expression (see Syntax Object Properties), the +property value is used for naming the expression, and it overrides any +name that was inferred from the expression’s context. Normally, the +property value should be a symbol. A 'inferred-name +property value of #<void> hides a name that would otherwise be +inferred from context (perhaps to avoid exposing an identifier from an +automatically generated binding).

To support the propagation and merging of consistent properties during +expansions, the value of the 'inferred-name property can be a +tree formed with cons where all of the leaves are the same. +For example, (cons 'name 'name) is equivalent to +'name, and (cons (void) (void)) is equivalent to +#<void>.

When an inferred name is not available, but a source location is +available, a name is constructed using the source location +information. Inferred and property-assigned names are also available +to syntax transformers, via syntax-local-name.

1.2.7 Cross-Phase Persistent Module Declarations

A module is cross-phase persistent only if it fits the following grammar, +which uses non-terminals from Fully Expanded Programs, only if +it includes (#%declare #:cross-phase-persistent), only +it includes no uses of quote-syntax or #%variable-reference, +and only if no module-level binding is set!ed.

  cross-module = 
(module id module-path
  (#%plain-module-begin
    cross-form ...))
     
  cross-form = (#%declare #:cross-phase-persistent)
  | (begin cross-form ...)
  | (#%provide raw-provide-spec ...)
  | submodule-form
  | (define-values (id ...) cross-expr)
  | (#%require raw-require-spec ...)
     
  cross-expr = id
  | (quote cross-datum)
  | (#%plain-lambda formals expr ...+)
  | (case-lambda (formals expr ...+) ...)
  | (#%plain-app cons cross-expr ...+)
  | (#%plain-app list cross-expr ...+)
  | (#%plain-app make-struct-type cross-expr ...+)
  | 
(#%plain-app make-struct-type-property
             cross-expr ...+)
  | (#%plain-app gensym)
  | (#%plain-app gensym string)
  | (#%plain-app string->uninterned-symbol string)
  | 
(#%plain-app variable-reference-from-unsafe?
             (#%variable-reference))
     
  cross-datum = number
  | boolean
  | identifier
  | string
  | bytes
  | ()

This grammar applies after expansion, but because a cross-phase persistent +module imports only from other cross-phase persistent modules, the only relevant +expansion steps are the implicit introduction of +#%plain-module-begin, implicit introduction of #%plain-app, +and implicit introduction and/or expansion of #%datum. +

Changed in version 7.5.0.12 of package base: Allow (#%plain-app variable-reference-from-unsafe? (#%variable-reference)).

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/syntax-util.html b/clones/docs.racket-lang.org/reference/syntax-util.html new file mode 100644 index 00000000..7c12fbac --- /dev/null +++ b/clones/docs.racket-lang.org/reference/syntax-util.html @@ -0,0 +1,60 @@ + +12.12 Syntax Utilities

12.12 Syntax Utilities

 (require racket/syntax) package: base
The bindings documented in this section are provided by the racket/syntax library, not racket/base or racket.

12.12.1 Creating formatted identifiers

procedure

(format-id lctx    
  fmt    
  v ...    
  [#:source src    
  #:props props    
  #:cert ignored    
  #:subs? subs?    
  #:subs-intro subs-introducer])  identifier?
  lctx : (or/c syntax? #f)
  fmt : string?
  v : (or/c string? symbol? identifier? keyword? char? number?)
  src : (or/c syntax? #f) = #f
  props : (or/c syntax? #f) = #f
  ignored : (or/c syntax? #f) = #f
  subs? : boolean? = #f
  subs-introducer : (-> syntax? syntax?)
   = (if (syntax-transforming?) syntax-local-introduce values)
Like format, but produces an identifier using lctx +for the lexical context, src for the source location, and +props for the properties. An argument supplied with +#:cert is ignored. (See datum->syntax.)

The format string must use only ~a placeholders. Identifiers +in the argument list are automatically converted to symbols.

Examples:
> (define-syntax (make-pred stx)
    (syntax-case stx ()
      [(make-pred name)
       (format-id #'name "~a?" (syntax-e #'name))]))
> (make-pred pair)

#<procedure:pair?>

> (make-pred none-such)

none-such?: undefined;

 cannot reference an identifier before its definition

  in module: top-level

> (define-syntax (better-make-pred stx)
    (syntax-case stx ()
      [(better-make-pred name)
       (format-id #'name #:source #'name
                  "~a?" (syntax-e #'name))]))
> (better-make-pred none-such)

none-such?: undefined;

 cannot reference an identifier before its definition

  in module: top-level

(Scribble doesn’t show it, but the DrRacket pinpoints the location of +the second error but not of the first.)

If subs? is #t, then a 'sub-range-binders +syntax property is added to the result that records the position of +each identifier in the vs. The subs-intro procedure +is applied to each identifier, and its result is included in the +sub-range binder record. This property value overrides a +'sub-range-binders property copied from props.

Example:
> (syntax-property (format-id #'here "~a/~a-~a" #'point 2 #'y #:subs? #t)
                   'sub-range-binders)

'(#(#<syntax point/2-y> 8 1 0.5 0.5 #<syntax:eval:8:0 y> 0 1 0.5 0.5)

  #(#<syntax point/2-y> 0 5 0.5 0.5 #<syntax:eval:8:0 point> 0 5 0.5 0.5))

Changed in version 7.4.0.5 of package base: Added the #:subs? and +#:subs-intro arguments.

procedure

(format-symbol fmt v ...)  symbol?

  fmt : string?
  v : (or/c string? symbol? identifier? keyword? char? number?)
Like format, but produces a symbol. The format string must +use only ~a placeholders. Identifiers in the argument list +are automatically converted to symbols.

Example:
> (format-symbol "make-~a" 'triple)

'make-triple

12.12.2 Pattern variables

syntax

(define/with-syntax pattern stx-expr)

 
  stx-expr : syntax?
Definition form of with-syntax. That is, it matches the +syntax object result of stx-expr against pattern and +creates pattern variable definitions for the pattern variables of +pattern.

Examples:
> (define/with-syntax (px ...) #'(a b c))
> (define/with-syntax (tmp ...) (generate-temporaries #'(px ...)))
> #'([tmp px] ...)

#<syntax:eval:12:0 ((a9 a) (b10 b) (c11 c))>

> (define/with-syntax name #'Alice)
> #'(hello name)

#<syntax:eval:14:0 (hello Alice)>

12.12.3 Error reporting

The current contextual syntax object, defaulting to #f. It +determines the special form name that prefixes syntax errors created +by wrong-syntax.

procedure

(wrong-syntax stx format-string v ...)  any

  stx : syntax?
  format-string : string?
  v : any/c
Raises a syntax error using the result of +(current-syntax-context) as the “major” syntax object and +the provided stx as the specific syntax object. (The latter, +stx, is usually the one highlighted by DrRacket.) The error +message is constructed using the format string and arguments, and it +is prefixed with the special form name as described under +current-syntax-context.

Examples:
> (wrong-syntax #'here "expected ~s" 'there)

eval:15:0: ?: expected there

  at: here

> (parameterize ([current-syntax-context #'(look over here)])
    (wrong-syntax #'here "expected ~s" 'there))

eval:16:0: look: expected there

  at: here

  in: (look over here)

A macro using wrong-syntax might set the syntax context at the very +beginning of its transformation as follows: +
(define-syntax (my-macro stx)
  (parameterize ([current-syntax-context stx])
    (syntax-case stx ()
      __)))
Then any calls to wrong-syntax during the macro’s +transformation will refer to my-macro (more precisely, the name that +referred to my-macro where the macro was used, which may be +different due to renaming, prefixing, etc).

12.12.4 Recording disappeared uses

Parameter for tracking disappeared uses. Tracking is “enabled” when +the parameter has a non-false value. This is done automatically by +forms like with-disappeared-uses.

syntax

(with-disappeared-uses body-expr ... stx-expr)

 
  stx-expr : syntax?
Evaluates the body-exprs and stx-expr, catching identifiers +looked up using syntax-local-value/record. Adds the caught identifiers +to the 'disappeared-use syntax property of the syntax object produced +by stx-expr.

Changed in version 6.5.0.7 of package base: Added the option to include body-exprs.

procedure

(syntax-local-value/record id predicate)  any/c

  id : identifier?
  predicate : (-> any/c boolean?)
Looks up id in the syntactic environment (as +syntax-local-value). If the lookup succeeds and returns a +value satisfying the predicate, the value is returned and id +is recorded as a disappeared use by calling record-disappeared-uses. +If the lookup fails or if the value +does not satisfy the predicate, #f is returned and the +identifier is not recorded as a disappeared use.

procedure

(record-disappeared-uses id [intro?])  void?

  id : (or/c identifier? (listof identifier?))
  intro? : boolean? = (syntax-transforming?)
Add id to (current-recorded-disappeared-uses). If +id is a list, perform the same operation on all the +identifiers. If intro? is true, then +syntax-local-introduce is first called on the identifiers.

If not used within the extent of a with-disappeared-uses +form or similar, has no effect.

Changed in version 6.5.0.7 of package base: Added the option to pass a single identifier instead of +requiring a list.
Changed in version 7.2.0.11: Added the intro? argument.

12.12.5 Miscellaneous utilities

procedure

(generate-temporary [name-base])  identifier?

  name-base : any/c = 'g
Generates one fresh identifier. Singular form of +generate-temporaries. If name-base is supplied, it +is used as the basis for the identifier’s name.

procedure

(internal-definition-context-apply intdef-ctx    
  stx)  syntax?
  intdef-ctx : internal-definition-context?
  stx : syntax?
Equivalent to (internal-definition-context-introduce intdef-ctx stx 'add). The +internal-definition-context-apply function is provided for backwards compatibility; the + internal-definition-context-add-scopes function is preferred.

procedure

(syntax-local-eval stx [intdef-ctx])  any

  stx : any/c
  intdef-ctx : 
(or/c internal-definition-context?
      #f
      (listof internal-definition-context?))
   = '()
Evaluates stx as an expression in the current transformer environment (that is, at +phase level 1). If intdef-ctx is not #f, the value provided for +intdef-ctx is used to enrich stx’s lexical information and extend the +local binding context in the same way as the fourth argument to local-expand.

Examples:
> (define-syntax (show-me stx)
    (syntax-case stx ()
      [(show-me expr)
       (begin
         (printf "at compile time produces ~s\n"
                 (syntax-local-eval #'expr))
         #'(printf "at run time produces ~s\n"
                   expr))]))
> (show-me (+ 2 5))

at compile time produces 7

at run time produces 7

> (define-for-syntax fruit 'apple)
> (define fruit 'pear)
> (show-me fruit)

at compile time produces apple

at run time produces pear

Changed in version 6.90.0.27 of package base: Changed intdef-ctx to accept a list of internal-definition +contexts in addition to a single internal-definition context or +#f.

syntax

(with-syntax* ([pattern stx-expr] ...)
  body ...+)
 
  stx-expr : syntax?
Similar to with-syntax, but the pattern variables of each +pattern are bound in the stx-exprs of subsequent +clauses as well as the bodys, and the patterns need +not bind distinct pattern variables; later bindings shadow earlier +bindings.

Example:
> (with-syntax* ([(x y) (list #'val1 #'val2)]
                 [nest #'((x) (y))])
    #'nest)

#<syntax:eval:22:0 ((val1) (val2))>

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/syntax.html b/clones/docs.racket-lang.org/reference/syntax.html new file mode 100644 index 00000000..689d6578 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/syntax.html @@ -0,0 +1,22 @@ + +3 Syntactic Forms

3 Syntactic Forms

This section describes the core syntax forms that appear in a fully +expanded expression, plus many closely related non-core forms. +See Fully Expanded Programs for the core grammar.

    3.1 Modules: module, module*, ...

    3.2 Importing and Exporting: require and provide

      3.2.1 Additional require Forms

      3.2.2 Additional provide Forms

    3.3 Literals: quote and #%datum

    3.4 Expression Wrapper: #%expression

    3.5 Variable References and #%top

    3.6 Locations: #%variable-reference

    3.7 Procedure Applications and #%app

    3.8 Procedure Expressions: lambda and case-lambda

    3.9 Local Binding: let, let*, letrec, ...

    3.10 Local Definitions: local

    3.11 Constructing Graphs: shared

    3.12 Conditionals: if, cond, and, and or

    3.13 Dispatch: case

    3.14 Definitions: define, define-syntax, ...

      3.14.1 require Macros

      3.14.2 provide Macros

    3.15 Sequencing: begin, begin0, and begin-for-syntax

    3.16 Guarded Evaluation: when and unless

    3.17 Assignment: set! and set!-values

    3.18 Iterations and Comprehensions: for, for/list, ...

      3.18.1 Iteration and Comprehension Forms

      3.18.2 Deriving New Iteration Forms

      3.18.3 Do Loops

    3.19 Continuation Marks: with-continuation-mark

    3.20 Quasiquoting: quasiquote, unquote, and unquote-splicing

    3.21 Syntax Quoting: quote-syntax

    3.22 Interaction Wrapper: #%top-interaction

    3.23 Blocks: block

    3.24 Internal-Definition Limiting: #%stratified-body

    3.25 Performance Hints: begin-encourage-inline

    3.26 Importing Modules Lazily: lazy-require

Notation

Each syntactic form is described by a BNF-like notation that describes +a combination of (syntax-wrapped) pairs, symbols, and other data (not +a sequence of characters). These grammatical specifications are shown +as in the following specification of a something +form:

(something id thing-expr ...)
 
  thing-expr : number?

Within such specifications,

  • ... indicates zero or more repetitions of the +preceding datum; more generally, N consecutive +...s a row indicate a consecutive repetition of the +preceding N datums.

  • ...+ indicates one or more repetitions of the +preceding datum.

  • Italic meta-identifiers play the role of non-terminals. Some + meta-identifier names imply syntactic constraints:

    • A meta-identifier that ends in id stands for an +identifier.

    • A meta-identifier that ends in keyword stands +for a keyword.

    • A meta-identifier that ends with expr (such as +thing-expr) stands for a sub-form that is +expanded as an expression.

    • A meta-identifier that ends with body stands +for a sub-form that is expanded in an +internal-definition context (see +Internal Definitions).

  • Contracts indicate constraints on sub-expression results. For +example, thing-expr : number? indicates that +the expression thing-expr must produce a number.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/tcp.html b/clones/docs.racket-lang.org/reference/tcp.html new file mode 100644 index 00000000..7567349c --- /dev/null +++ b/clones/docs.racket-lang.org/reference/tcp.html @@ -0,0 +1,126 @@ + +15.3.1 TCP
15.3.1 TCP

 (require racket/tcp) package: base
The bindings documented in this section are provided by the racket/tcp and racket libraries, but not racket/base.

For information about TCP in general, see TCP/IP Illustrated, +Volume 1 by W. Richard Stevens.

procedure

(tcp-listen port-no    
  [max-allow-wait    
  reuse?    
  hostname])  tcp-listener?
  port-no : listen-port-number?
  max-allow-wait : exact-nonnegative-integer? = 4
  reuse? : any/c = #f
  hostname : (or/c string? #f) = #f
Creates a “listening” server on the local machine at the port number +specified by port-no. If port-no is 0 the socket binds +to an ephemeral port, which can be determined by calling +tcp-addresses. The max-allow-wait argument +determines the maximum number of client connections that can be +waiting for acceptance. (When max-allow-wait clients are +waiting acceptance, no new client connections can be made.)

If the reuse? argument is true, then tcp-listen will +create a listener even if the port is involved in a TIME_WAIT +state. Such a use of reuse? defeats certain guarantees of the +TCP protocol; see Stevens’s book for details. Furthermore, on many +modern platforms, a true value for reuse? overrides +TIME_WAIT only if the listener was previously created with a true +value for reuse?.

If hostname is #f (the default), then the listener +accepts connections to all of the listening machine’s addresses. +Otherwise, the listener accepts connections only at the interface(s) +associated with the given hostname. For example, providing +"127.0.0.1" as hostname creates a listener that +accepts only connections to "127.0.0.1" (the loopback +interface) from the local machine.

(Racket implements a listener with multiple sockets, if necessary, to +accommodate multiple addresses with different protocol families. On +Linux, if hostname maps to both IPv4 and IPv6 addresses, then +the behavior depends on whether IPv6 is supported and IPv6 sockets can +be configured to listen to only IPv6 connections: if IPv6 is not +supported or IPv6 sockets are not configurable, then the IPv6 +addresses are ignored; otherwise, each IPv6 listener accepts only IPv6 +connections.)

The return value of tcp-listen is a TCP +listener. This value can be used in future calls to +tcp-accept, tcp-accept-ready?, and +tcp-close. Each new TCP listener value is placed into the +management of the current custodian (see Custodians).

If the server cannot be started by tcp-listen, the +exn:fail:network exception is raised.

A TCP listener can be used as a synchronizable event (see Events). +A TCP listener is ready for synchronization when +tcp-accept would not block; the synchronization result of a TCP listener is the TCP listener itself.

procedure

(tcp-connect hostname    
  port-no    
  [local-hostname    
  local-port-no])  
input-port? output-port?
  hostname : string?
  port-no : port-number?
  local-hostname : (or/c string? #f) = #f
  local-port-no : (or/c port-number? #f) = #f
Attempts to connect as a client to a listening server. The +hostname argument is the server host’s Internet address name, +and port-no is the port number where the server is listening.

(If hostname is associated with multiple addresses, they are +tried one at a time until a connection succeeds. The name +"localhost" generally specifies the local machine.)

The optional local-hostname and local-port-no +specify the client’s address and port. If both are #f (the +default), the client’s address and port are selected automatically. If +local-hostname is not #f, then +local-port-no must be non-#f. If +local-port-no is non-#f and local-hostname +is #f, then the given port is used but the address is +selected automatically.

Two values are returned by tcp-connect: an input port and an +output port. Data can be received from the server through the input +port and sent to the server through the output port. If the server is +a Racket program, it can obtain ports to communicate to the +client with tcp-accept. These ports are placed into the +management of the current custodian (see Custodians).

Initially, the returned input port is block-buffered, and the returned +output port is block-buffered. Change the buffer mode using +file-stream-buffer-mode.

Both of the returned ports must be closed to terminate the TCP +connection. When both ports are still open, closing the output port +with close-output-port sends a TCP close to the server (which +is seen as an end-of-file if the server reads the connection through a +port). In contrast, tcp-abandon-port (see below) closes the +output port, but does not send a TCP close until the input port is +also closed.

Note that the TCP protocol does not support a state where one end is +willing to send but not read, nor does it include an automatic message +when one end of a connection is fully closed. Instead, the other end +of a connection discovers that one end is fully closed only as a +response to sending data; in particular, some number of writes on the +still-open end may appear to succeed, though writes will eventually +produce an error.

If a connection cannot be established by tcp-connect, the +exn:fail:network exception is raised.

procedure

(tcp-connect/enable-break hostname 
  port-no 
  [local-hostname] 
  local-port-no) 
  
input-port? output-port?
  hostname : string?
  port-no : port-number?
  local-hostname : (or/c string? #f) = #f
  local-port-no : (or/c port-number? #f)
Like tcp-connect, but breaking is enabled (see +Breaks) while trying to connect. If breaking is +disabled when tcp-connect/enable-break is called, then either +ports are returned or the exn:break exception is raised, but +not both.

procedure

(tcp-accept listener)  
input-port? output-port?
  listener : tcp-listener?
Accepts a client connection for the server associated with +listener. If no client connection is waiting on the +listening port, the call to tcp-accept will block. (See also +tcp-accept-ready?.)

Two values are returned by tcp-accept: an input port and an +output port. Data can be received from the client through the input +port and sent to the client through the output port. These ports are +placed into the management of the current custodian (see +Custodians).

In terms of buffering and connection states, the ports act the same as +ports from tcp-connect.

If a connection cannot be accepted by tcp-accept, or if the +listener has been closed, the exn:fail:network exception is raised.

procedure

(tcp-accept/enable-break listener)  
input-port? output-port?
  listener : tcp-listener?
Like tcp-accept, but breaking is enabled (see +Breaks) while trying to accept a connection. If +breaking is disabled when tcp-accept/enable-break is called, +then either ports are returned or the exn:break exception is +raised, but not both.

procedure

(tcp-accept-ready? listener)  boolean?

  listener : tcp-listener?
Tests whether an unaccepted client has connected to the server +associated with listener. If a client is +waiting, the return value is #t, otherwise it is +#f. A client is accepted with the tcp-accept +procedure, which returns ports for communicating with the client and +removes the client from the list of unaccepted clients.

If the listener has been closed, the exn:fail:network exception is raised.

procedure

(tcp-close listener)  void?

  listener : tcp-listener?
Shuts down the server associated with listener. All +unaccepted clients receive an end-of-file from the server; connections +to accepted clients are unaffected.

If the listener has already been closed, the exn:fail:network exception is raised.

The listener’s port number may not become immediately available for +new listeners (with the default reuse? argument of +tcp-listen). For further information, see Stevens’s +explanation of the TIME_WAIT TCP state.

procedure

(tcp-listener? v)  boolean?

  v : any/c
Returns #t if v is a TCP listener created by +tcp-listen, #f otherwise.

procedure

(tcp-accept-evt listener)  evt?

  listener : tcp-listener?
Returns a synchronizable event (see Events) that is +ready for synchronization when tcp-accept on listener would +not block. The synchronization result is a +list of two items, which correspond to the two results of +tcp-accept. (If the event is not chosen in a sync, no connections are +accepted.) The ports are placed into the management of the custodian +that is the current custodian (see Custodians) at the time that +tcp-accept-evt is called.

procedure

(tcp-abandon-port tcp-port)  void?

  tcp-port : tcp-port?
Like close-output-port or close-input-port +(depending on whether tcp-port is an input or output port), +but if tcp-port is an output port and its associated input +port is not yet closed, then the other end of the TCP connection does +not receive a TCP close message until the input port is also +closed.

The TCP protocol does not include a “no longer reading” state on +connections, so tcp-abandon-port is equivalent to +close-input-port on input TCP ports.

procedure

(tcp-addresses tcp-port [port-numbers?])

  
(or/c (values string? string?)
      (values string? port-number?
              string? listen-port-number?))
  tcp-port : (or/c tcp-port? tcp-listener? udp?)
  port-numbers? : any/c = #f
Returns two strings when port-numbers? is #f (the +default). The first string is the Internet address for the local +machine as viewed by the given TCP port’s connection, for the +TCP listener, or the UDP socket. (When a machine serves +multiple addresses, as it usually does if you count the loopback +device, the result is connection-specific or +listener-specific.) If a listener or UDP socket is given and it has no specific +host, the first string result is "0.0.0.0". The second string +is the Internet address for the other end of the connection, or always +"0.0.0.0" for a listener or unconnected UDP socket.

If port-numbers? is true, then four results are returned: a +string for the local machine’s address, an exact integer between +1 and 65535 for the local machine’s port number, a +string for the remote machine’s address, and an exact integer between +1 and 65535 for the remote machine’s port number or +0 for a listener.

If the given port, listener, or socket has been closed, the +exn:fail:network exception is raised.

procedure

(tcp-port? v)  boolean?

  v : any/c
Returns #t if v is a TCP portwhich is a +port returned by tcp-accept, tcp-connect, +tcp-accept/enable-break, or +tcp-connect/enable-break#f otherwise.

Equivalent to (integer-in 1 65535).

Added in version 6.3 of package base.

Equivalent to (integer-in 0 65535).

Added in version 6.3 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/thread-local-storage.html b/clones/docs.racket-lang.org/reference/thread-local-storage.html new file mode 100644 index 00000000..0852c1f2 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/thread-local-storage.html @@ -0,0 +1,4 @@ + +11.3 Thread-Local Storage

11.3 Thread-Local Storage

Thread cells provides primitive support for thread-local +storage. Parameters combine thread cells and continuation marks +to support thread-specific, continuation-specific binding.

    11.3.1 Thread Cells

    11.3.2 Parameters

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/threadcells.html b/clones/docs.racket-lang.org/reference/threadcells.html new file mode 100644 index 00000000..a10c72aa --- /dev/null +++ b/clones/docs.racket-lang.org/reference/threadcells.html @@ -0,0 +1,36 @@ + +11.3.1 Thread Cells
11.3.1 Thread Cells

A thread cell contains a thread-specific value; that +is, it contains a specific value for each thread, but it may contain +different values for different threads. A thread cell is created with +a default value that is used for all existing threads. When the cell’s +content is changed with thread-cell-set!, the cell’s value +changes only for the current thread. Similarly, +thread-cell-ref obtains the value of the cell that is +specific to the current thread.

A thread cell’s value can be preserved, which means +that when a new thread is created, the cell’s initial value for the +new thread is the same as the creating thread’s current value. If a +thread cell is non-preserved, then the cell’s initial value for a +newly created thread is the default value (which was supplied when the +cell was created).

Within the current thread, the current values of all preserved threads +cells can be captured through +current-preserved-thread-cell-values. The captured set of +values can be imperatively installed into the current thread through +another call to current-preserved-thread-cell-values. The +capturing and restoring threads can be different.

procedure

(thread-cell? v)  boolean?

  v : any/c
Returns #t if v is a thread cell, +#f otherwise.

procedure

(make-thread-cell v [preserved?])  thread-cell?

  v : any/c
  preserved? : any/c = #f
Creates and returns a new thread cell. Initially, v is the +cell’s value for all threads. If preserved? is true, then the +cell’s initial value for a newly created threads is the creating +thread’s value for the cell, otherwise the cell’s value is initially +v in all future threads.

procedure

(thread-cell-ref cell)  any

  cell : thread-cell?
Returns the +current value of cell for the current thread.

procedure

(thread-cell-set! cell v)  any

  cell : thread-cell?
  v : any/c
Sets the +value in cell to v for the current thread.

Examples:
> (define cnp (make-thread-cell '(nerve) #f))
> (define cp (make-thread-cell '(cancer) #t))
> (thread-cell-ref cnp)

'(nerve)

> (thread-cell-ref cp)

'(cancer)

> (thread-cell-set! cnp '(nerve nerve))
> (thread-cell-set! cp '(cancer cancer))
> (thread-cell-ref cnp)

'(nerve nerve)

> (thread-cell-ref cp)

'(cancer cancer)

> (define ch (make-channel))
> (thread (lambda ()
            (channel-put ch (thread-cell-ref cnp))
            (channel-put ch (thread-cell-ref cp))
            (channel-get ch)
            (channel-put ch (thread-cell-ref cp))))

#<thread>

> (channel-get ch)

'(nerve)

> (channel-get ch)

'(cancer cancer)

> (thread-cell-set! cp '(cancer cancer cancer))
> (thread-cell-ref cp)

'(cancer cancer cancer)

> (channel-put ch 'ok)
> (channel-get ch)

'(cancer cancer)

When called with no arguments, this procedure produces a +thread-cell-vals that represents the current values (in the +current thread) for all preserved thread cells.

When called with a thread-cell-vals generated by a previous +call to current-preserved-thread-cell-values, the values of +all preserved thread cells (in the current thread) are set to the +values captured in thread-cell-vals; if a preserved thread +cell was created after thread-cell-vals was generated, then +the thread cell’s value for the current thread reverts to its initial +value.

procedure

(thread-cell-values? v)  boolean?

  v : any/c
Returns #t if v is a set of thread cell values +produced by current-preserved-thread-cell-values, #f +otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/threadgroups.html b/clones/docs.racket-lang.org/reference/threadgroups.html new file mode 100644 index 00000000..4e657cdf --- /dev/null +++ b/clones/docs.racket-lang.org/reference/threadgroups.html @@ -0,0 +1,15 @@ + +14.8 Thread Groups

14.8 Thread Groups

A thread group is a collection of threads and other thread +groups that have equal claim to the CPU. By nesting thread groups and +by creating certain threads within certain groups, a programmer can +control the amount of CPU allocated to a set of threads. Every thread +belongs to a thread group, which is determined by the +current-thread-group parameter when the thread is +created. Thread groups and custodians (see Custodians) +are independent.

The root thread group receives all of the CPU that the operating +system gives Racket. Every thread or nested group in a particular +thread group receives equal allocation of the CPU (a portion of the +group’s access), although a thread may relinquish part of its +allocation by sleeping or synchronizing with other processes.

procedure

(make-thread-group [group])  thread-group?

  group : thread-group? = (current-thread-group)
Creates a new thread group that belongs to group.

procedure

(thread-group? v)  boolean?

  v : any/c
Returns #t if v is a thread group value, #f +otherwise.

parameter

(current-thread-group)  thread-group?

(current-thread-group group)  void?
  group : thread-group?
A parameter that determines the thread group for newly created +threads.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/threads.html b/clones/docs.racket-lang.org/reference/threads.html new file mode 100644 index 00000000..92e261fe --- /dev/null +++ b/clones/docs.racket-lang.org/reference/threads.html @@ -0,0 +1,137 @@ + +11.1 Threads

11.1 Threads

+Concurrency and Synchronization in The Racket Guide introduces threads.

See Threads for basic information on the Racket +thread model. See also Futures and Places.

When a thread is created, it is placed into the management of the +current custodian and added to the current thread +group. A thread can have any number of custodian managers added +through thread-resume.

A thread that has not terminated can be garbage collected (see +Garbage Collection) if it is unreachable and suspended or if it is +unreachable and blocked on only unreachable events through functions +such as semaphore-wait, semaphore-wait/enable-break, +channel-put, channel-get, sync, +sync/enable-break, or thread-wait. Beware, however, +of a limitation on place-channel blocking; see the +caveat in Places.

In GRacket, a handler thread for an eventspace is blocked on +an internal semaphore when its event queue is empty. Thus, the handler +thread is collectible when the eventspace is unreachable and contains +no visible windows or running timers.

A thread can be used as a synchronizable event (see +Events). A thread is ready for synchronization when +thread-wait would not block; the synchronization result of a thread is the thread itself.

11.1.1 Creating Threads

procedure

(thread thunk)  thread?

  thunk : (-> any)
Calls thunk with no arguments in a new thread of control. The +thread procedure returns immediately with a thread +descriptor value. When the invocation of thunk returns, the +thread created to invoke thunk terminates.

procedure

(thread? v)  thread?

  v : any/c
Returns #t if +v is a thread descriptor, #f otherwise.

procedure

(current-thread)  thread?

Returns the thread +descriptor for the currently executing thread.

procedure

(thread/suspend-to-kill thunk)  thread?

  thunk : (-> any)
Like thread, except that “killing” the thread through +kill-thread or custodian-shutdown-all merely +suspends the thread instead of terminating it.

procedure

(call-in-nested-thread thunk [cust])  any

  thunk : (-> any)
  cust : custodian? = (current-custodian)
Creates a nested thread managed by cust to execute +thunk. (The nested thread’s current custodian is inherited +from the creating thread, independent of the cust argument.) +The current thread blocks until thunk returns, and the result +of the call-in-nested-thread call is the result returned by +thunk.

The nested thread’s exception handler is initialized to a procedure +that jumps to the beginning of the thread and transfers the exception +to the original thread. The handler thus terminates the nested thread +and re-raises the exception in the original thread.

If the thread created by call-in-nested-thread dies before +thunk returns, the exn:fail exception is raised in the original +thread. If the original thread is killed before thunk +returns, a break is queued for the nested thread.

If a break is queued for the original thread (with +break-thread) while the nested thread is running, the break +is redirected to the nested thread. If a break is already queued on +the original thread when the nested thread is created, the break is +moved to the nested thread. If a break remains queued on the nested +thread when it completes, the break is moved to the original thread.

If the thread created by call-in-nested-thread dies while +itself in a call to call-in-nested-thread, the outer call to +call-in-nested-thread waits for the innermost nested thread +to complete, and any breaks pending on the inner threads are moved to +the original thread.

11.1.2 Suspending, Resuming, and Killing Threads

procedure

(thread-suspend thd)  void?

  thd : thread?
Immediately suspends the execution of thd if it is +running. If the thread has terminated or is already suspended, +thread-suspend has no effect. The thread remains suspended +(i.e., it does not execute) until it is resumed with +thread-resume. If the current custodian does not +solely manage thd (i.e., some custodian of thd +is not the current custodian or a subordinate), the +exn:fail:contract exception is raised, and the thread is not suspended.

procedure

(thread-resume thd [benefactor])  void?

  thd : thread?
  benefactor : (or/c thread? custodian? #f) = #f
Resumes the execution of thd if it is suspended and has at +least one custodian (possibly added through benefactor, as +described below). If the thread has terminated, or if the thread is +already running and benefactor is not supplied, or if the +thread has no custodian and benefactor is not supplied, then +thread-resume has no effect. Otherwise, if +benefactor is supplied, it triggers up to three +additional actions:

  • If benefactor is a thread, whenever it is resumed +from a suspended state in the future, then thd is also +resumed. (Resuming thd may trigger the resumption of other +threads that were previously attached to thd through +thread-resume.)

  • New custodians may be added to thd’s set of +managers. If benefactor is a thread, then all of the +thread’s custodians are added to thd. Otherwise, +benefactor is a custodian, and it is added to thd +(unless the custodian is already shut down). If thd +becomes managed by both a custodian and one or more of its +subordinates, the redundant subordinates are removed from +thd. If thd is suspended and a custodian is +added, then thd is resumed only after the addition.

  • If benefactor is a thread, whenever it receives a +new managing custodian in the future, then thd also +receives the custodian. (Adding custodians to thd may +trigger adding the custodians to other threads that were previously +attached to thd through thread-resume.)

procedure

(kill-thread thd)  void?

  thd : thread?
Terminates the specified thread immediately, or suspends the thread if +thd was created with +thread/suspend-to-kill. Terminating the main thread exits the +application. If thd has already terminated, +kill-thread does nothing. If the current custodian +does not manage thd (and none of its subordinates manages +thd), the exn:fail:contract exception is raised, and the thread is not +killed or suspended.

Unless otherwise noted, procedures provided by Racket (and GRacket) are +kill-safe and suspend-safe; that is, killing or suspending a thread +never interferes with the application of procedures in other +threads. For example, if a thread is killed while extracting a +character from an input port, the character is either completely +consumed or not consumed, and other threads can safely use the port.

procedure

(break-thread thd [kind])  void?

  thd : thread?
  kind : (or/c #f 'hang-up 'terminate) = #f
Registers a break with the specified +thread, where kind optionally indicates the kind of break to +register. If breaking is disabled in thd, the break will be +ignored until breaks are re-enabled (see Breaks).

procedure

(sleep [secs])  void?

  secs : (>=/c 0) = 0
Causes the current thread to sleep until at least secs +seconds have passed after it starts sleeping. A zero value for +secs simply acts as a hint to allow other threads to +execute. The value of secs can be a non-integer to request a +sleep duration to any precision; the precision of the actual sleep +time is unspecified.

procedure

(thread-running? thd)  any

  thd : thread?
Returns #t if thd +has not terminated and is not suspended, #f otherwise.

procedure

(thread-dead? thd)  any

  thd : thread?
Returns #t if thd has terminated, #f +otherwise.

11.1.3 Synchronizing Thread State

procedure

(thread-wait thd)  void?

  thd : thread?
Blocks execution of the current thread until thd has +terminated. Note that (thread-wait (current-thread)) +deadlocks the current thread, but a break can end the deadlock (if +breaking is enabled; see Breaks).

procedure

(thread-dead-evt thd)  evt?

  thd : thread?
Returns a synchronizable event (see Events) that is +ready for synchronization if and only if thd has terminated. Unlike using +thd directly, however, a reference to the event does not +prevent thd from being garbage collected (see +Garbage Collection). For a given thd, +thread-dead-evt always returns the same (i.e., eq?) +result. The synchronization result of a thread-dead event is the thread-dead event itself.

procedure

(thread-resume-evt thd)  evt?

  thd : thread?
Returns a synchronizable event (see Events) that +becomes ready for synchronization when thd is running. (If thd has +terminated, the event never becomes ready.) If thd runs and +is then suspended after a call to thread-resume-evt, the +result event remains ready; after each suspend of thd a fresh +event is generated to be returned by thread-resume-evt. The +result of the event is thd, but if thd is never +resumed, then reference to the event does not prevent thd +from being garbage collected (see Garbage Collection).

procedure

(thread-suspend-evt thd)  evt?

  thd : thread?
Returns a synchronizable event (see Events) that +becomes ready for synchronization when thd is suspended. (If thd has +terminated, the event will never unblock.) If thd is +suspended and then resumes after a call to +thread-suspend-evt, the result event remains ready; after +each resume of thd created a fresh event to be returned by +thread-suspend-evt. The +result of the event is thd, but if thd is never +resumed, then reference to the event does not prevent thd +from being garbage collected (see Garbage Collection).

11.1.4 Thread Mailboxes

Each thread has a mailbox through which it can receive +arbitrary messages. In other words, each thread has a built-in +asynchronous channel.

+See also Buffered Asynchronous Channels.

procedure

(thread-send thd v [fail-thunk])  any

  thd : thread?
  v : any/c
  fail-thunk : (or/c (-> any) #f)
   = (lambda () (raise-mismatch-error ....))
Queues v as a message to thd without blocking. If +the message is queued, the result is #<void>. If thd +stops running—as in thread-running?before the message is +queued, then fail-thunk is called (through a tail call) if it is +a procedure to produce the result, or #f is returned if +fail-thunk is #f.

procedure

(thread-receive)  any/c

Receives and dequeues a message queued for the current thread, if +any. If no message is available, thread-receive blocks until +one is available.

procedure

(thread-try-receive)  any/c

Receives and dequeues a message queued for the current thread, if any, +or returns #f immediately if no message is available.

procedure

(thread-receive-evt)  evt?

Returns a constant synchronizable event (see Events) +that becomes ready for synchronization when the synchronizing thread has a message to +receive. The synchronization result of a thread-receive event is the thread-receive event itself.

procedure

(thread-rewind-receive lst)  void?

  lst : list?
Pushes the elements of lst back onto the front of the current +thread’s queue. The elements are pushed one by one, so that the first +available message is the last element of lst.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/time.html b/clones/docs.racket-lang.org/reference/time.html new file mode 100644 index 00000000..612adec7 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/time.html @@ -0,0 +1,83 @@ + +15.6 Time

15.6 Time

Returns the current time in seconds since the epoch: +midnight UTC, January 1, 1970.

Returns the current time in milliseconds since midnight UTC, January +1, 1970. The result may contain fractions of a millisecond.

Example:
> (current-inexact-milliseconds)

1289513737015.418

In this example, 1289513737015 is in milliseconds and 418 +is in microseconds.

Returns the number of milliseconds since an unspecified starting time. +Unlike current-inexact-milliseconds, which is sensitive to +the system clock and may therefore retreat or advance more quickly +than real time if the system clock is adjusted, results from +current-inexact-monotonic-milliseconds will always advance +with real time within a Racket process, but results across processes +are not comparable.

Example:

Added in version 8.1.0.4 of package base.

procedure

(seconds->date secs-n [local-time?])  date*?

  secs-n : real?
  local-time? : any/c = #t
Takes secs-n, a platform-specific time in seconds returned by +current-seconds, file-or-directory-modify-seconds, +or 1/1000th of current-inexact-milliseconds, and returns an +instance of the date* structure type. Note that +secs-n can include fractions of a second. If secs-n +is too small or large, the exn:fail exception is raised.

The resulting date* reflects the time according to the local +time zone if local-time? is #t, otherwise it +reflects a date in UTC.

struct

(struct date (second
    minute
    hour
    day
    month
    year
    week-day
    year-day
    dst?
    time-zone-offset)
    #:extra-constructor-name make-date
    #:transparent)
  second : (integer-in 0 60)
  minute : (integer-in 0 59)
  hour : (integer-in 0 23)
  day : (integer-in 1 31)
  month : (integer-in 1 12)
  year : exact-integer?
  week-day : (integer-in 0 6)
  year-day : (integer-in 0 365)
  dst? : boolean?
  time-zone-offset : exact-integer?
Represents a date. The second field reaches 60 only +for leap seconds. The week-day field is 0 for +Sunday, 1 for Monday, etc. The year-day field is +0 for January 1, 1 for January 2, etc.; the +year-day field reaches 365 only in leap years.

The dst? field is #t if the date reflects a +daylight-saving adjustment. The time-zone-offset field +reports the number of seconds east of UTC (GMT) for the current time zone +(e.g., Pacific Standard Time is -28800), including any +daylight-saving adjustment (e.g., Pacific Daylight Time is +-25200). When a date record is generated by +seconds->date with #f as the second argument, then +the dst? and time-zone-offset fields are +#f and 0, respectively.

The date constructor accepts any value for dst? +and converts any non-#f value to #t.

The value produced for the time-zone-offset field tends to be +sensitive to the value of the TZ environment variable, +especially on Unix platforms; consult the system documentation +(usually under tzset) for details.

See also the racket/date library.

struct

(struct date* date (nanosecond time-zone-name)
    #:extra-constructor-name make-date*)
  nanosecond : (integer-in 0 999999999)
  time-zone-name : (and/c string? immutable?)
Extends date with nanoseconds and a time zone name, such as +"MDT", "Mountain Daylight Time", or "UTC".

When a date* record is generated by seconds->date +with #f as the second argument, then the +time-zone-name field is "UTC".

The date* constructor accepts a mutable string for +time-zone-name and converts it to an immutable one.

Like current-inexact-milliseconds, but coerced to a +fixnum (possibly negative). Since the result is a +fixnum, the value increases only over a limited (though +reasonably long) time on a 32-bit platform.

procedure

(current-process-milliseconds [scope])  exact-integer?

  scope : (or/c #f thread? 'subprocesses) = #f
Returns an amount of processor time in fixnum milliseconds that +has been consumed by on the underlying operating system, including +both user and system time.

  • If scope is #f, the reported time is for all +Racket threads and places.

  • If scope is a thread, the result is specific to the +time while the thread ran, but it may include time for other +places. The more a thread synchronizes with other +threads, the less precisely per-thread processor time is +recorded.

  • If scope is 'subprocesses, the result is the +sum of process times for known-completed subprocesses (see +Processes)—and known-completed children of the +subprocesses, etc., on Unix and Mac OS—across all places.

The precision of the result is platform-specific, and +since the result is a fixnum, the value increases only over a +limited (though reasonably long) time on a 32-bit platform.

Changed in version 6.1.1.4 of package base: Added 'subprocesses mode.

Returns the amount of processor time in fixnum milliseconds +that has been consumed by Racket’s garbage collection so far. This +time is a portion of the time reported by +(current-process-milliseconds), and is similarly limited.

procedure

(time-apply proc lst)  
list?
exact-integer?
exact-integer?
exact-integer?
  proc : procedure?
  lst : list?
Collects timing information for a procedure application.

Four values are returned: a list containing the result(s) of applying +proc to the arguments in lst, the number of milliseconds of +CPU time required to obtain this result, the number of “real” milliseconds +required for the result, and the number of milliseconds of CPU time (included +in the first result) spent on garbage collection.

The reliability of the timing numbers depends on the platform. If +multiple Racket threads are running, then the reported time may +include work performed by other threads.

syntax

(time body ...+)

Reports time-apply-style timing information for the +evaluation of expr directly to the current output port. The +result is the result of the last body.

15.6.1 Date Utilities

For more date & time operations, see +the Gregor: Date and Time documentation +or srfi/19

 (require racket/date) package: base
The bindings documented in this section are provided by the racket/date library, not racket/base or racket.

procedure

(current-date)  date*?

An abbreviation for (seconds->date (* 0.001 (current-inexact-milliseconds))).

procedure

(date->string date [time?])  string?

  date : date?
  time? : any/c = #f
Converts a date to a string. The returned string contains the time of +day only if time?. See also date-display-format.

parameter

(date-display-format)  
(or/c 'american
      'chinese
      'german
      'indian
      'irish
      'iso-8601
      'rfc2822
      'julian)
(date-display-format format)  void?
  format : 
(or/c 'american
      'chinese
      'german
      'indian
      'irish
      'iso-8601
      'rfc2822
      'julian)
Parameter that determines the date string format. The initial format +is 'american.

procedure

(date->seconds date [local-time?])  exact-integer?

  date : date?
  local-time? : any/c = #t
Finds the representation of a date in platform-specific seconds. +If the platform cannot represent the specified date, +exn:fail exception is raised.

The week-day, year-day fields of date are +ignored. The dst? and time-zone-offset fields of +date are also ignored; the date is assumed to be in local +time by default or in UTC if local-time? is #f.

procedure

(date*->seconds date [local-time?])  real?

  date : date?
  local-time? : any/c = #t
Like date->seconds, but returns an exact number that can +include a fraction of a second based on (date*-nanosecond date) if date is a date* instance.

procedure

(find-seconds second    
  minute    
  hour    
  day    
  month    
  year    
  [local-time?])  exact-integer?
  second : (integer-in 0 61)
  minute : (integer-in 0 59)
  hour : (integer-in 0 23)
  day : (integer-in 1 31)
  month : (integer-in 1 12)
  year : exact-nonnegative-integer?
  local-time? : any/c = #t
Finds the representation of a date in platform-specific seconds. The +arguments correspond to the fields of the date structure—in +local time by default or UTC if local-time? is +#f. If the platform cannot represent the specified date, an +error is signaled, otherwise an integer is returned.

procedure

(date->julian/scaliger date)  exact-integer?

  date : date?
Converts a date structure (up to 2099 BCE Gregorian) into a Julian +date number. The returned value is not a strict Julian number, but +rather Scaliger’s version, which is off by one for easier +calculations.

procedure

(julian/scaliger->string date-number)  string?

  date-number : exact-integer?
Converts a Julian number (Scaliger’s off-by-one version) into a +string.

procedure

(date->julian/scalinger date)  exact-integer?

  date : date?

procedure

(julian/scalinger->string date-number)  string?

  date-number : exact-integer?
The same as date->julian/scaliger and +julian/scaliger->string, but misspelled.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/trait.html b/clones/docs.racket-lang.org/reference/trait.html new file mode 100644 index 00000000..db8b0e56 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/trait.html @@ -0,0 +1,76 @@ + +6.6 Traits

6.6 Traits

 (require racket/trait) package: base
The bindings documented in this section are provided by the racket/trait library, not racket/base or racket.

A trait is a collection of methods that can be converted to +a mixin and then applied to a class. Before a trait is +converted to a mixin, the methods of a trait can be individually +renamed, and multiple traits can be merged to form a new trait.

syntax

(trait trait-clause ...)

 
trait-clause = (public maybe-renamed ...)
  | (pubment maybe-renamed ...)
  | (public-final maybe-renamed ...)
  | (override maybe-renamed ...)
  | (overment maybe-renamed ...)
  | (override-final maybe-renamed ...)
  | (augment maybe-renamed ...)
  | (augride maybe-renamed ...)
  | (augment-final maybe-renamed ...)
  | (inherit maybe-renamed ...)
  | (inherit/super maybe-renamed ...)
  | (inherit/inner maybe-renamed ...)
  | method-definition
  | (field field-declaration ...)
  | (inherit-field maybe-renamed ...)
Creates a trait. The body of a trait form is similar to the +body of a class* form, but restricted to non-private method +definitions. In particular, the grammar of +maybe-renamed, method-definition, and +field-declaration are the same as for class*, and +every method-definition must have a corresponding declaration +(one of public, override, etc.). As in +class, uses of method names in direct calls, super +calls, and inner calls depend on bringing method names into +scope via inherit, inherit/super, +inherit/inner, and other method declarations in the same +trait; an exception, compared to class is that +overment binds a method name only in the corresponding +method, and not in other methods of the same trait. Finally, macros +such as public* and define/public work in +trait as in class.

External identifiers in trait, trait-exclude, +trait-exclude-field, trait-alias, +trait-rename, and trait-rename-field forms are +subject to binding via define-member-name and +define-local-member-name. Although private methods +or fields are not allowed in a trait form, they can be +simulated by using a public or field declaration and +a name whose scope is limited to the trait form.

procedure

(trait? v)  boolean?

  v : any/c
Returns #t if v is a trait, #f otherwise.

procedure

(trait->mixin tr)  (class? . -> . class?)

  tr : trait?
Converts a trait to a mixin, which can be applied to a +class to produce a new class. An expression of the form

(trait->mixin
 (trait
   trait-clause ...))

is equivalent to

(lambda (%)
  (class %
    trait-clause ...
    (super-new)))

Normally, however, a trait’s methods are changed and combined with +other traits before converting to a mixin.

procedure

(trait-sum tr ...+)  trait?

  tr : trait?
Produces a trait that combines all of the methods of the given +trs. For example,

(define t1
  (trait
    (define/public (m1) 1)))
(define t2
  (trait
    (define/public (m2) 2)))
(define t3 (trait-sum t1 t2))

creates a trait t3 that is equivalent to

(trait
  (define/public (m1) 1)
  (define/public (m2) 2))

but t1 and t2 can still be used individually or +combined with other traits.

When traits are combined with trait-sum, the combination +drops inherit, inherit/super, +inherit/inner, and inherit-field declarations when a +definition is supplied for the same method or field name by another +trait. The trait-sum operation fails (the +exn:fail:contract exception is raised) if any of the traits to combine define a +method or field with the same name, or if an inherit/super or +inherit/inner declaration to be dropped is inconsistent with +the supplied definition. In other words, declaring a method with +inherit, inherit/super, or inherit/inner, +does not count as defining the method; at the same time, for example, +a trait that contains an inherit/super declaration for a +method m cannot be combined with a trait that defines +m as augment, since no class could satisfy the +requirements of both augment and inherit/super when +the trait is later converted to a mixin and applied to a class.

syntax

(trait-exclude trait-expr id)

Produces a new trait that is like the trait result of +trait-expr, but with the definition of a method named by +id removed; as the method definition is removed, either an +inherit, inherit/super, or inherit/inner +declaration is added:

If the trait produced by trait-expr has no method definition for +id, the exn:fail:contract exception is raised.

syntax

(trait-exclude-field trait-expr id)

Produces a new trait that is like the trait result of +trait-expr, but with the definition of a field named by +id removed; as the field definition is removed, an +inherit-field declaration is added.

syntax

(trait-alias trait-expr id new-id)

Produces a new trait that is like the trait result of +trait-expr, but the definition and declaration of the method +named by id is duplicated with the name new-id. The +consistency requirements for the resulting trait are the same as for +trait-sum, otherwise the exn:fail:contract exception is raised. This +operation does not rename any other use of id, such as in +method calls (even method calls to identifier in the cloned +definition for new-id).

syntax

(trait-rename trait-expr id new-id)

Produces a new trait that is like the trait result of +trait-expr, but all definitions and references to methods +named id are replaced by definitions and references to +methods named by new-id. The consistency requirements for the +resulting trait are the same as for trait-sum, otherwise the +exn:fail:contract exception is raised.

syntax

(trait-rename-field trait-expr id new-id)

Produces a new trait that is like the trait result of +trait-expr, but all definitions and references to fields +named id are replaced by definitions and references to fields +named by new-id. The consistency requirements for the +resulting trait are the same as for trait-sum, otherwise the +exn:fail:contract exception is raised.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/udp.html b/clones/docs.racket-lang.org/reference/udp.html new file mode 100644 index 00000000..73571e4a --- /dev/null +++ b/clones/docs.racket-lang.org/reference/udp.html @@ -0,0 +1,147 @@ + +15.3.2 UDP
15.3.2 UDP

 (require racket/udp) package: base
The bindings documented in this section are provided by the racket/udp and racket libraries, but not racket/base.

For information about UDP in general, see TCP/IP Illustrated, +Volume 1 by W. Richard Stevens.

procedure

(udp-open-socket [family-hostname    
  family-port-no])  udp?
  family-hostname : (or/c string? #f) = #f
  family-port-no : (or/c port-number? #f) = #f
Creates and returns a UDP socket to send and receive +datagrams (broadcasting is allowed). Initially, the socket is not +bound or connected to any address or port.

If family-hostname or family-port-no is not +#f, then the socket’s protocol family is determined from +these arguments. The socket is not bound to the hostname +or port number. For example, the arguments might be the hostname +and port to which messages will be sent through the socket, which +ensures that the socket’s protocol family is consistent with the +destination. Alternately, the arguments might be the same as for +a future call to udp-bind!, which ensures that the +socket’s protocol family is consistent with the binding. If +neither family-hostname nor family-port-no is +non-#f, then the socket’s protocol family is IPv4.

procedure

(udp-bind! udp-socket    
  hostname-string    
  port-no    
  [reuse?])  void?
  udp-socket : udp?
  hostname-string : (or/c string? #f)
  port-no : listen-port-number?
  reuse? : any/c = #f
Binds an unbound udp-socket to the local port number +port-no. If port-no is 0 the udp-socket is +bound to an ephemeral port, which can be determined by calling +udp-addresses.

If hostname-string is #f, then the socket +accepts connections to all of the listening machine’s IP +addresses at port-no. Otherwise, the socket accepts +connections only at the IP address associated with the given +name. For example, providing "127.0.0.1" as +hostname-string typically creates a listener that +accepts only connections to "127.0.0.1" from the local +machine.

A socket cannot receive datagrams until it is bound to a local address +and port. If a socket is not bound before it is used with a sending +procedure udp-send, udp-send-to, etc., the sending +procedure binds the socket to a random local port. Similarly, if an +event from udp-send-evt or udp-send-to-evt is chosen +for a synchronization (see Events), the socket is bound; if +the event is not chosen, the socket may or may not become bound.

The binding of a bound socket cannot be changed, with one exception: +on some systems, if the socket is bound automatically when sending, if +the socket is disconnected via udp-connect!, and if the +socket is later used again in a send, then the later send may change +the socket’s automatic binding.

If udp-socket is already bound or closed, the +exn:fail:network exception is raised.

If the reuse? argument is true, then udp-bind! will +set the SO_REUSEADDR socket option before binding, permitting the +sharing of access to a UDP port between many processes on a single +machine when using UDP multicast.

procedure

(udp-connect! udp-socket    
  hostname-string    
  port-no)  void?
  udp-socket : udp?
  hostname-string : (or/c string? #f)
  port-no : (or/c port-number? #f)
Connects the socket to the indicated remote address and port if +hostname-string is a string and port-no is an exact +integer.

If hostname-string is #f, then port-no also +must be #f, and the port is disconnected (if connected). If +one of hostname-string or port-no is #f and +the other is not, the exn:fail:contract exception is raised.

A connected socket can be used with udp-send (not +udp-send-to), and it accepts datagrams only from the +connected address and port. A socket need not be connected to receive +datagrams. A socket can be connected, re-connected, and disconnected +any number of times.

If udp-socket is closed, the exn:fail:network exception is raised.

procedure

(udp-send-to udp-socket    
  hostname    
  port-no    
  bstr    
  [start-pos    
  end-pos])  void?
  udp-socket : udp?
  hostname : string?
  port-no : port-number?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Sends (subbytes bytes start-pos end-pos) as a datagram from +the unconnected udp-socket to the socket at the remote +machine hostname-address on the port port-no. The +udp-socket need not be bound or connected; if it is not +bound, udp-send-to binds it to a random local port. If the +socket’s outgoing datagram queue is too full to support the send, +udp-send-to blocks until the datagram can be queued.

If start-pos is greater than the length of bstr, or +if end-pos is less than start-pos or greater than +the length of bstr, the exn:fail:contract exception is raised.

If udp-socket is closed or connected, the +exn:fail:network exception is raised.

procedure

(udp-send udp-socket bstr [start-pos end-pos])  void?

  udp-socket : udp?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like udp-send-to, except that udp-socket must be +connected, and the datagram goes to the connection target. If +udp-socket is closed or unconnected, the +exn:fail:network exception is raised.

procedure

(udp-send-to* udp-socket    
  hostname    
  port-no    
  bstr    
  [start-pos    
  end-pos])  boolean?
  udp-socket : udp?
  hostname : string?
  port-no : port-number?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like udp-send-to, but never blocks; if the socket’s outgoing +queue is too full to support the send, #f is returned, +otherwise the datagram is queued and the result is #t.

procedure

(udp-send* udp-socket bstr [start-pos end-pos])  boolean?

  udp-socket : udp?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like udp-send, except that (like udp-send-to) it +never blocks and returns #f or #t.

procedure

(udp-send-to/enable-break udp-socket    
  hostname    
  port-no    
  bstr    
  [start-pos    
  end-pos])  void?
  udp-socket : udp?
  hostname : string?
  port-no : port-number?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like udp-send-to, but breaking is enabled (see +Breaks) while trying to send the datagram. If +breaking is disabled when udp-send-to/enable-break is called, +then either the datagram is sent or the exn:break exception +is raised, but not both.

procedure

(udp-send/enable-break udp-socket    
  bstr    
  [start-pos    
  end-pos])  void?
  udp-socket : udp?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like udp-send, except that breaks are enabled like +udp-send-to/enable-break.

procedure

(udp-receive! udp-socket    
  bstr    
  [start-pos    
  end-pos])  
exact-nonnegative-integer?
string?
port-number?
  udp-socket : udp?
  bstr : (and/c bytes? (not immutable?))
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Accepts up to end-pos-start-pos bytes of +udp-socket’s next incoming datagram into bstr, +writing the datagram bytes starting at position start-pos +within bstr. The udp-socket must be bound to a local +address and port (but need not be connected). If no incoming datagram +is immediately available, udp-receive! blocks until one is +available.

Three values are returned: the number of received bytes (between +0 and end-pos-start-pos, a hostname +string indicating the source address of the datagram, and an integer +indicating the source port of the datagram. If the received datagram +is longer than end-pos-start-pos bytes, the +remainder is discarded.

If start-pos is greater than the length of bstr, or +if end-pos is less than start-pos or greater than +the length of bstr, the exn:fail:contract exception is raised.

procedure

(udp-receive!* udp-socket 
  bstr 
  [start-pos 
  end-pos]) 
  
(or/c exact-nonnegative-integer? #f)
(or/c string? #f)
(or/c port-number? #f)
  udp-socket : udp?
  bstr : (and/c bytes? (not immutable?))
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like udp-receive!, except that it never blocks. If no +datagram is available, the three result values are all #f.

procedure

(udp-receive!/enable-break udp-socket 
  bstr 
  [start-pos 
  end-pos]) 
  
exact-nonnegative-integer?
string?
port-number?
  udp-socket : udp?
  bstr : (and/c bytes? (not immutable?))
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Like udp-receive!, but breaking is enabled (see +Breaks) while trying to receive the datagram. If +breaking is disabled when udp-receive!/enable-break is +called, then either a datagram is received or the exn:break +exception is raised, but not both.

procedure

(udp-set-receive-buffer-size! udp-socket    
  size)  void?
  udp-socket : udp?
  size : exact-positive-integer?
Set the receive buffer size (SO_RCVBUF) for udp-socket. +Using a larger buffer can minimize packet loss that can occur due to +slow polling of a connection, including during a major garbage +collection.

If size is greater than the maximum allowed by the system, +the exn:fail:network exception is raised.

Added in version 7.1.0.11 of package base.

procedure

(udp-close udp-socket)  void?

  udp-socket : udp?
Closes udp-socket, discarding unreceived datagrams. If the +socket is already closed, the exn:fail:network exception is raised.

procedure

(udp? v)  boolean?

  v : any/c
Returns #t if v is a socket created by +udp-open-socket, #f otherwise.

procedure

(udp-bound? udp-socket)  boolean?

  udp-socket : udp?
Returns #t if udp-socket is bound to a local address +and port, #f otherwise.

procedure

(udp-connected? udp-socket)  boolean?

  udp-socket : udp?
Returns #t if udp-socket is connected to a remote +address and port, #f otherwise.

procedure

(udp-send-ready-evt udp-socket)  evt?

  udp-socket : udp?
Returns a synchronizable event (see Events) that is +in a blocking state when udp-send-to on udp-socket +would block. The synchronization result is the event itself.

procedure

(udp-receive-ready-evt udp-socket)  evt?

  udp-socket : udp?
Returns a synchronizable event (see Events) that is +in a blocking state when udp-receive! on udp-socket +would block. The synchronization result is the event itself.

procedure

(udp-send-to-evt udp-socket    
  hostname    
  port-no    
  bstr    
  [start-pos    
  end-pos])  evt?
  udp-socket : udp?
  hostname : string?
  port-no : port-number?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Returns a synchronizable event. The event is in a blocking +state when udp-send-to on udp-socket would +block. Otherwise, if the event is chosen in a synchronization, data is +sent as for (udp-send-to udp-socket hostname-address port-no bstr start-pos end-pos), and the synchronization result is +#<void>. (No bytes are sent if the event is not chosen.)

procedure

(udp-send-evt udp-socket    
  bstr    
  [start-pos    
  end-pos])  evt?
  udp-socket : udp?
  bstr : bytes?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Returns a synchronizable event. The event is ready for synchronization +when udp-send on udp-socket would +not block. Otherwise, if the event is chosen in a synchronization, data is +sent as for (udp-send-to udp-socket bstr start-pos end-pos), +and the synchronization result is #<void>. (No bytes are sent if +the event is not chosen.) If udp-socket is closed or +unconnected, the exn:fail:network exception is raised during a synchronization +attempt.

procedure

(udp-receive!-evt udp-socket    
  bstr    
  [start-pos    
  end-pos])  evt?
  udp-socket : udp?
  bstr : (and/c bytes? (not immutable?))
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (bytes-length bstr)
Returns a synchronizable event. The event is ready for synchronization +when udp-receive on udp-socket would not +block. Otherwise, if the event is chosen in a synchronization, data is +received into bstr as for (udp-receive! udp-socket bytes start-pos end-pos), and the synchronization result is a list of +three values, corresponding to the three results from +udp-receive!. (No bytes are received and the bstr +content is not modified if the event is not chosen.)

procedure

(udp-addresses udp-port [port-numbers?])

  
(or/c (values string? string?)
      (values string? listen-port-number?
              string? listen-port-number?))
  udp-port : udp?
  port-numbers? : any/c = #f
Returns two strings when port-numbers? is #f (the +default). The first string is the Internet address for the local +machine a viewed by the given UDP socket’s connection. (For most +machines, the answer corresponds to the current machine’s only +Internet address, but when a machine serves multiple addresses, the +result is connection-specific.) The second string is the Internet +address for the other end of the connection.

If port-numbers? is true, then four results are returned: a +string for the local machine’s address, an exact integer between +1 and 65535 for the local machine’s port number +or 0 if the socket is unbound, a +string for the remote machine’s address, and an exact integer between +1 and 65535 for the remote machine’s port number +or 0 if the socket is unconnected.

If the given port has been closed, the exn:fail:network exception is raised.

procedure

(udp-set-ttl! udp-socket ttl)  void?

  udp-socket : udp?
  ttl : byte?

procedure

(udp-ttl udp-socket)  byte?

  udp-socket : udp?

Time-to-live settings correspond to the +IP_TTL setting of the socket.

Sets or retrieves the current time-to-live setting of +udp-socket.

Added in version 7.5.0.5 of package base.

procedure

(udp-multicast-join-group! udp-socket    
  multicast-addr    
  hostname)  void?
  udp-socket : udp?
  multicast-addr : string?
  hostname : (or/c string? #f)

procedure

(udp-multicast-leave-group! udp-socket    
  multicast-addr    
  hostname)  void?
  udp-socket : udp?
  multicast-addr : string?
  hostname : (or/c string? #f)
Adds or removes udp-socket to a named multicast group.

The multicast-addr argument must be a valid IPv4 multicast +IP address; for example, "224.0.0.251" is the appropriate +address for the mDNS protocol. The hostname argument selects the +interface that the socket uses to receive (not send) multicast datagrams; +if hostname is #f or "0.0.0.0", the kernel +selects an interface automatically.

Leaving a group requires the same multicast-addr and +hostname arguments that were used to join the group.

procedure

(udp-multicast-interface udp-socket)  string?

  udp-socket : udp?

procedure

(udp-multicast-set-interface! udp-socket    
  hostname)  void?
  udp-socket : udp?
  hostname : (or/c string? #f)
Retrieves or sets the interface that udp-socket uses to +send (not receive) multicast datagrams. If the result or hostname is either +#f or "0.0.0.0", the kernel automatically selects an +interface when a multicast datagram is sent.

procedure

(udp-multicast-set-loopback! udp-socket    
  loopback?)  void?
  udp-socket : udp?
  loopback? : any/c

procedure

(udp-multicast-loopback? udp-socket)  boolean?

  udp-socket : udp?

Loopback settings correspond to the +IP_MULTICAST_LOOP setting of the socket.

Sets or checks whether udp-socket receives its own multicast +datagrams: a #t result or a true value for loopback? +indicates that self-receipt is enabled, and #f indicates that +self-receipt is disabled.

procedure

(udp-multicast-set-ttl! udp-socket ttl)  void?

  udp-socket : udp?
  ttl : byte?

procedure

(udp-multicast-ttl udp-socket)  byte?

  udp-socket : udp?

Time-to-live settings correspond to the +IP_MULTICAST_TTL setting of the socket.

Sets or retrieves the current time-to-live setting of +udp-socket.

The time-to-live setting should almost always be 1, and it is +important that this number is as low as possible. In fact, these +functions seldom should be used at all. See the documentation for your +platform’s IP stack.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/undefined.html b/clones/docs.racket-lang.org/reference/undefined.html new file mode 100644 index 00000000..a9a789dc --- /dev/null +++ b/clones/docs.racket-lang.org/reference/undefined.html @@ -0,0 +1,5 @@ + +4.21 Undefined

4.21 Undefined

The bindings documented in this section are provided by the racket/undefined library, not racket/base or racket.

The constant undefined can be used as a placeholder value for +a value to be installed later, especially for cases where premature +access of the value is either difficult or impossible to detect or +prevent.

The undefined value is always eq? to itself.

Added in version 6.0.0.6 of package base.

value

undefined : any/c

The “undefined” constant.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/unitcontracts.html b/clones/docs.racket-lang.org/reference/unitcontracts.html new file mode 100644 index 00000000..7c872b58 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/unitcontracts.html @@ -0,0 +1,16 @@ + +7.9 Unit Contracts

7.9 Unit Contracts

syntax

(unit/c
  (import sig-block ...)
  (export sig-block ...)
  init-depends-decl
  optional-body-ctc)
 
sig-block = (tagged-sig-id [id contract] ...)
  | tagged-sig-id
     
init-depends-decl = 
  | (init-depend tagged-sig-id ...)
     
optional-body-ctc = 
  | contract
  | (values contract ...)
A unit contract wraps a unit and checks both its imported and +exported identifiers to ensure that they match the appropriate contracts. +This allows the programmer to add contract checks to a single unit value +without adding contracts to the imported and exported signatures.

The unit value must import a subset of the import signatures and export a +superset of the export signatures listed in the unit contract. Additionally, +the unit value must declare initialization dependencies that are a subset of +those specified in the unit contract. Any identifier which is not listed +for a given signature is left alone. Variables used in a given +contract expression first refer to other variables in the same +signature, and then to the context of the unit/c expression. +If a body contract is specified then the result of invoking the unit value +is wrapped with the given contract, if no body contract is supplied then +no wrapping occurs when the unit value is invoked.

syntax

(define-unit/contract unit-id
  (import sig-spec-block ...)
  (export sig-spec-block ...)
  init-depends-decl
  optional-body-ctc
  unit-body-expr-or-defn
  ...)
 
sig-spec-block = (tagged-sig-spec [id contract] ...)
  | tagged-sig-spec
     
optional-body-ctc = 
  | #:invoke/contract contract
  | #:invoke/contract (values contract ...)
The define-unit/contract form defines a unit compatible with +link inference whose imports and exports are contracted with a unit +contract. The unit name is used for the positive blame of the contract.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/unixpaths.html b/clones/docs.racket-lang.org/reference/unixpaths.html new file mode 100644 index 00000000..31f2a792 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/unixpaths.html @@ -0,0 +1,27 @@ + +15.1.3 Unix and Mac OS Paths
15.1.3 Unix and Mac OS Paths

In a path on Unix and Mac OS, a / separates elements of the path, +. as a path element always means the directory indicated by +preceding path, and .. as a path element always means the +parent of the directory indicated by the preceding path. A leading +~ in a path is not treated specially, but +expand-user-path can be used to convert a leading ~ +element to a user-specific directory. No other character or byte has a +special meaning within a path. Multiple adjacent / are +equivalent to a single / (i.e., they act as a single path +separator).

A path root is always /. A path starting with / is +an absolute, complete path, and a path starting with any other +character is a relative path.

Any pathname that ends with a / syntactically refers to a +directory, as does any path whose last element is . or +...

A Unix and Mac OS path is cleansed by replacing multiple adjacent +/s with a single /.

For (bytes->path-element bstr), bstr must not +contain any /, otherwise the exn:fail:contract exception is raised. +The result of (path-element->bytes path) or +(path-element->string path) is always the same as the result +of (path->bytes path) and (path->string path). Since that is not the case for other platforms, however, +path-element->bytes and path-element->string should +be used when converting individual path elements.

On Mac OS, Finder aliases are zero-length files.

15.1.3.1 Unix Path Representation

A path on Unix and Mac OS is natively a byte string. For presentation to +users and for other string-based operations, a path is converted +to/from a string using the current locale’s encoding with ? +(encoding) or #\uFFFD (decoding) in place of errors. Beware +that the encoding may not accommodate all possible paths as +distinct strings.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/unreachable.html b/clones/docs.racket-lang.org/reference/unreachable.html new file mode 100644 index 00000000..d6c33a57 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/unreachable.html @@ -0,0 +1,10 @@ + +10.8 Unreachable Expressions

10.8 Unreachable Expressions

procedure

(assert-unreachable)  none/c

Reports an assertion failure by raising exn:fail:contract, +which is useful as a safe counterpart to +unsafe-assert-unreachable.

Added in version 8.0.0.11 of package base.

10.8.1 Customized Unreachable Reporting

The bindings documented in this section are provided by the racket/unreachable library, not racket/base or racket.

Added in version 8.0.0.11 of package base.

syntax

(with-assert-unreachable
  body ...+)
Similar to (assert-unreachable), asserts that the +body forms should not be reached.

Unless the expression is part of a module that includes +(#%declare #:unsafe), then it is equivalent to +(let-values () body ...+). The intent is that the +body forms will raise exn:fail:contract.

When a with-assert-unreachable expression is part of a module +with (#%declare #:unsafe), then it is equivalent to +(unsafe-assert-unreachable).

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/unsafe.html b/clones/docs.racket-lang.org/reference/unsafe.html new file mode 100644 index 00000000..9145ec45 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/unsafe.html @@ -0,0 +1,211 @@ + +17 Unsafe Operations
On this page:
17.1 Unsafe Numeric Operations
unsafe-fx+
unsafe-fx-
unsafe-fx*
unsafe-fxquotient
unsafe-fxremainder
unsafe-fxmodulo
unsafe-fxabs
unsafe-fxand
unsafe-fxior
unsafe-fxxor
unsafe-fxnot
unsafe-fxlshift
unsafe-fxrshift
unsafe-fxpopcount
unsafe-fxpopcount32
unsafe-fxpopcount16
unsafe-fx+  /  wraparound
unsafe-fx-/  wraparound
unsafe-fx*/  wraparound
unsafe-fxlshift/  wraparound
unsafe-fx=
unsafe-fx<
unsafe-fx>
unsafe-fx<=
unsafe-fx>=
unsafe-fxmin
unsafe-fxmax
unsafe-fl+
unsafe-fl-
unsafe-fl*
unsafe-fl/
unsafe-flabs
unsafe-fl=
unsafe-fl<
unsafe-fl>
unsafe-fl<=
unsafe-fl>=
unsafe-flmin
unsafe-flmax
unsafe-flround
unsafe-flfloor
unsafe-flceiling
unsafe-fltruncate
unsafe-flsingle
unsafe-flsin
unsafe-flcos
unsafe-fltan
unsafe-flasin
unsafe-flacos
unsafe-flatan
unsafe-fllog
unsafe-flexp
unsafe-flsqrt
unsafe-flexpt
unsafe-make-flrectangular
unsafe-flreal-part
unsafe-flimag-part
unsafe-fx->fl
unsafe-fl->fx
unsafe-flrandom
17.2 Unsafe Character Operations
unsafe-char=?
unsafe-char<?
unsafe-char>?
unsafe-char<=?
unsafe-char>=?
unsafe-char->integer
17.3 Unsafe Compound-Data Operations
unsafe-car
unsafe-cdr
unsafe-mcar
unsafe-mcdr
unsafe-set-mcar!
unsafe-set-mcdr!
unsafe-cons-list
unsafe-list-ref
unsafe-list-tail
unsafe-set-immutable-car!
unsafe-set-immutable-cdr!
unsafe-unbox
unsafe-set-box!
unsafe-unbox*
unsafe-set-box*!
unsafe-box*-cas!
unsafe-vector-length
unsafe-vector-ref
unsafe-vector-set!
unsafe-vector*-length
unsafe-vector*-ref
unsafe-vector*-set!
unsafe-vector*-cas!
unsafe-vector*->immutable-vector!
unsafe-string-length
unsafe-string-ref
unsafe-string-set!
unsafe-string->immutable-string!
unsafe-bytes-length
unsafe-bytes-ref
unsafe-bytes-set!
unsafe-bytes-copy!
unsafe-bytes->immutable-bytes!
unsafe-fxvector-length
unsafe-fxvector-ref
unsafe-fxvector-set!
unsafe-flvector-length
unsafe-flvector-ref
unsafe-flvector-set!
unsafe-f64vector-ref
unsafe-f64vector-set!
unsafe-s16vector-ref
unsafe-s16vector-set!
unsafe-u16vector-ref
unsafe-u16vector-set!
unsafe-stencil-vector
unsafe-stencil-vector-mask
unsafe-stencil-vector-length
unsafe-stencil-vector-ref
unsafe-stencil-vector-set!
unsafe-stencil-vector-update
unsafe-struct-ref
unsafe-struct-set!
unsafe-struct*-ref
unsafe-struct*-set!
unsafe-struct*-cas!
unsafe-mutable-hash-iterate-first
unsafe-mutable-hash-iterate-next
unsafe-mutable-hash-iterate-key
unsafe-mutable-hash-iterate-value
unsafe-mutable-hash-iterate-key+  value
unsafe-mutable-hash-iterate-pair
unsafe-immutable-hash-iterate-first
unsafe-immutable-hash-iterate-next
unsafe-immutable-hash-iterate-key
unsafe-immutable-hash-iterate-value
unsafe-immutable-hash-iterate-key+  value
unsafe-immutable-hash-iterate-pair
unsafe-weak-hash-iterate-first
unsafe-weak-hash-iterate-next
unsafe-weak-hash-iterate-key
unsafe-weak-hash-iterate-value
unsafe-weak-hash-iterate-key+  value
unsafe-weak-hash-iterate-pair
unsafe-ephemeron-hash-iterate-first
unsafe-ephemeron-hash-iterate-next
unsafe-ephemeron-hash-iterate-key
unsafe-ephemeron-hash-iterate-value
unsafe-ephemeron-hash-iterate-key+  value
unsafe-ephemeron-hash-iterate-pair
unsafe-make-srcloc
17.4 Unsafe Extflonum Operations
unsafe-extfl+
unsafe-extfl-
unsafe-extfl*
unsafe-extfl/
unsafe-extflabs
unsafe-extfl=
unsafe-extfl<
unsafe-extfl>
unsafe-extfl<=
unsafe-extfl>=
unsafe-extflmin
unsafe-extflmax
unsafe-extflround
unsafe-extflfloor
unsafe-extflceiling
unsafe-extfltruncate
unsafe-extflsin
unsafe-extflcos
unsafe-extfltan
unsafe-extflasin
unsafe-extflacos
unsafe-extflatan
unsafe-extfllog
unsafe-extflexp
unsafe-extflsqrt
unsafe-extflexpt
unsafe-fx->extfl
unsafe-extfl->fx
unsafe-extflvector-length
unsafe-extflvector-ref
unsafe-extflvector-set!
17.5 Unsafe Impersonators and Chaperones
unsafe-impersonate-procedure
unsafe-chaperone-procedure
unsafe-impersonate-vector
unsafe-chaperone-vector
17.6 Unsafe Assertions
unsafe-assert-unreachable
17.7 Unsafe Undefined
unsafe-undefined
check-not-unsafe-undefined
check-not-unsafe-undefined/  assign
chaperone-struct-unsafe-undefined
prop:  chaperone-unsafe-undefined

17 Unsafe Operations

 (require racket/unsafe/ops) package: base

All functions and forms provided by racket/base and +racket check their arguments to ensure that the +arguments conform to contracts and other constraints. For example, +vector-ref checks its arguments to ensure that the first +argument is a vector, that the second argument is an exact integer, +and that the second argument is between 0 and one less than +the vector’s length, inclusive.

Functions provided by racket/unsafe/ops are +unsafe. They have certain constraints, but the constraints +are not checked, which allows the system to generate and execute +faster code. If arguments violate an unsafe function’s constraints, +the function’s behavior and result is unpredictable, and the entire +system can crash or become corrupted.

All of the exported bindings of racket/unsafe/ops are +protected in the sense of protect-out, so access to unsafe +operations can be prevented by adjusting the code inspector (see +Code Inspectors).

17.1 Unsafe Numeric Operations

procedure

(unsafe-fx+ a ...)  fixnum?

  a : fixnum?

procedure

(unsafe-fx- a b ...)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fx* a ...)  fixnum?

  a : fixnum?

procedure

(unsafe-fxquotient a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fxremainder a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fxmodulo a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fxabs a)  fixnum?

  a : fixnum?
For fixnums: Unchecked versions of fx+, fx-, +fx*, fxquotient, +fxremainder, fxmodulo, and +fxabs.

Changed in version 7.0.0.13 of package base: Allow zero or more arguments for unsafe-fx+ and unsafe-fx* +and allow one or more arguments for unsafe-fx-.

procedure

(unsafe-fxand a ...)  fixnum?

  a : fixnum?

procedure

(unsafe-fxior a ...)  fixnum?

  a : fixnum?

procedure

(unsafe-fxxor a ...)  fixnum?

  a : fixnum?

procedure

(unsafe-fxnot a)  fixnum?

  a : fixnum?

procedure

(unsafe-fxlshift a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fxrshift a b)  fixnum?

  a : fixnum?
  b : fixnum?
For fixnums: Unchecked versions of fxand, fxior, fxxor, +fxnot, fxlshift, and fxrshift.

Changed in version 7.0.0.13 of package base: Allow zero or more arguments for +unsafe-fxand, unsafe-fxior, +and unsafe-fxxor.

procedure

(unsafe-fxpopcount a)  fixnum?

  a : (and/c fixnum? (not/c negative?))

procedure

(unsafe-fxpopcount32 a)  fixnum?

  a : (and/c fixnum? (integer-in 0 #xFFFFFFFF))

procedure

(unsafe-fxpopcount16 a)  fixnum?

  a : (and/c fixnum? (integer-in 0 #xFFFF))
For fixnums: Unchecked versions of fxpopcount, +fxpopcount32, and fxpopcount16.

Added in version 8.5.0.6 of package base.

procedure

(unsafe-fx+/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fx-/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fx*/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fxlshift/wraparound a b)  fixnum?

  a : fixnum?
  b : fixnum?

Added in version 7.9.0.6 of package base.

procedure

(unsafe-fx= a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fx< a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fx> a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fx<= a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fx>= a b ...)  boolean?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fxmin a b ...)  fixnum?

  a : fixnum?
  b : fixnum?

procedure

(unsafe-fxmax a b ...)  fixnum?

  a : fixnum?
  b : fixnum?
For fixnums: Unchecked versions of fx=, fx<, + fx>, fx<=, fx>=, + fxmin, and fxmax.

Changed in version 7.0.0.13 of package base: Allow one or more argument, +instead of allowing just two.

procedure

(unsafe-fl+ a ...)  flonum?

  a : flonum?

procedure

(unsafe-fl- a b ...)  flonum?

  a : flonum?
  b : flonum?

procedure

(unsafe-fl* a ...)  flonum?

  a : flonum?

procedure

(unsafe-fl/ a b ...)  flonum?

  a : flonum?
  b : flonum?

procedure

(unsafe-flabs a)  flonum?

  a : flonum?
For flonums: Unchecked versions of fl+, fl-, +fl*, fl/, and flabs.

Changed in version 7.0.0.13 of package base: Allow zero or more arguments for unsafe-fl+ and unsafe-fl* +and one or more arguments for unsafe-fl- and unsafe-fl/.

procedure

(unsafe-fl= a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(unsafe-fl< a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(unsafe-fl> a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(unsafe-fl<= a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(unsafe-fl>= a b ...)  boolean?

  a : flonum?
  b : flonum?

procedure

(unsafe-flmin a b ...)  flonum?

  a : flonum?
  b : flonum?

procedure

(unsafe-flmax a b ...)  flonum?

  a : flonum?
  b : flonum?
For flonums: Unchecked versions of fl=, fl<, +fl>, fl<=, fl>=, flmin, and +flmax.

Changed in version 7.0.0.13 of package base: Allow one or more argument, +instead of allowing just two.

procedure

(unsafe-flround a)  flonum?

  a : flonum?

procedure

(unsafe-flfloor a)  flonum?

  a : flonum?

procedure

(unsafe-flceiling a)  flonum?

  a : flonum?

procedure

(unsafe-fltruncate a)  flonum?

  a : flonum?
For flonums: Unchecked (potentially) versions of +flround, flfloor, flceiling, and +fltruncate. Currently, these bindings are simply aliases for +the corresponding safe bindings.

procedure

(unsafe-flsingle a)  flonum?

  a : flonum?
For flonums: Unchecked (potentially) version of +flsingle.

Added in version 7.8.0.7 of package base.

procedure

(unsafe-flsin a)  flonum?

  a : flonum?

procedure

(unsafe-flcos a)  flonum?

  a : flonum?

procedure

(unsafe-fltan a)  flonum?

  a : flonum?

procedure

(unsafe-flasin a)  flonum?

  a : flonum?

procedure

(unsafe-flacos a)  flonum?

  a : flonum?

procedure

(unsafe-flatan a)  flonum?

  a : flonum?

procedure

(unsafe-fllog a)  flonum?

  a : flonum?

procedure

(unsafe-flexp a)  flonum?

  a : flonum?

procedure

(unsafe-flsqrt a)  flonum?

  a : flonum?

procedure

(unsafe-flexpt a b)  flonum?

  a : flonum?
  b : flonum?
For flonums: Unchecked (potentially) versions of +flsin, flcos, fltan, flasin, +flacos, flatan, fllog, flexp, +flsqrt, and flexpt. Currently, some of these +bindings are simply aliases for the corresponding safe bindings.

procedure

(unsafe-make-flrectangular a b)

  
(and/c complex?
       (lambda (c) (flonum? (real-part c)))
       (lambda (c) (flonum? (imag-part c))))
  a : flonum?
  b : flonum?

procedure

(unsafe-flreal-part a)  flonum?

  a : 
(and/c complex?
       (lambda (c) (flonum? (real-part c)))
       (lambda (c) (flonum? (imag-part c))))

procedure

(unsafe-flimag-part a)  flonum?

  a : 
(and/c complex?
       (lambda (c) (flonum? (real-part c)))
       (lambda (c) (flonum? (imag-part c))))
For flonums: Unchecked versions of make-flrectangular, +flreal-part, and flimag-part.

procedure

(unsafe-fx->fl a)  flonum?

  a : fixnum?

procedure

(unsafe-fl->fx a)  fixnum?

  a : flonum?
Unchecked versions of fx->fl and fl->fx.

Changed in version 7.7.0.8 of package base: Changed unsafe-fl->fx to truncate.

procedure

(unsafe-flrandom rand-gen)  (and flonum? (>/c 0) (</c 1))

  rand-gen : pseudo-random-generator?
Unchecked version of flrandom.

17.2 Unsafe Character Operations

procedure

(unsafe-char=? a b ...)  boolean?

  a : char?
  b : char?

procedure

(unsafe-char<? a b ...)  boolean?

  a : char?
  b : char?

procedure

(unsafe-char>? a b ...)  boolean?

  a : char?
  b : char?

procedure

(unsafe-char<=? a b ...)  boolean?

  a : char?
  b : char?

procedure

(unsafe-char>=? a b ...)  boolean?

  a : char?
  b : char?

procedure

(unsafe-char->integer a)  fixnum?

  a : char?
Unchecked versions of char=?, char<?, char>?, +char<=?, char>=?, and char->integer.

Added in version 7.0.0.14 of package base.

17.3 Unsafe Compound-Data Operations

procedure

(unsafe-car p)  any/c

  p : pair?

procedure

(unsafe-cdr p)  any/c

  p : pair?

procedure

(unsafe-mcar p)  any/c

  p : mpair?

procedure

(unsafe-mcdr p)  any/c

  p : mpair?

procedure

(unsafe-set-mcar! p v)  void?

  p : mpair?
  v : any/c

procedure

(unsafe-set-mcdr! p v)  void?

  p : mpair?
  v : any/c
Unsafe variants of car, cdr, mcar, +mcdr, set-mcar!, and set-mcdr!.

procedure

(unsafe-cons-list v rest)  (and/c pair? list?)

  v : any/c
  rest : list?
Unsafe variant of cons that produces a pair that claims to be +a list—without checking whether rest is a list.

procedure

(unsafe-list-ref lst pos)  any/c

  lst : pair?
  pos : (and/c exact-nonnegative-integer? fixnum?)

procedure

(unsafe-list-tail lst pos)  any/c

  lst : any/c
  pos : (and/c exact-nonnegative-integer? fixnum?)
Unsafe variants of list-ref and list-tail, where +pos must be a fixnum, and lst must start with +at least (add1 pos) (for unsafe-list-ref) or +pos (for unsafe-list-tail) pairs.

procedure

(unsafe-set-immutable-car! p v)  void?

  p : pair?
  v : any/c

procedure

(unsafe-set-immutable-cdr! p v)  void?

  p : pair?
  v : any/c
As their oxymoronic names should suggest, there is no generally +correct way to use these functions. They may be useful nevertheless, +as a last resort, in settings where pairs are used in a constrained +way and when making correct assumptions about Racket’s implementation +(including limits on the compiler’s optimizations).

Some pitfalls of using unsafe-set-immutable-car! and +unsafe-set-immutable-cdr!:

  • Functions that consume a pair may take advantage of +immutability, such as computing a list’s length once and +expecting the list to retain that length, or checking a list +against a contract and expecting the contract to hold +thereafter.

  • The result of list? for a pair may be cached +internally, so that changing the cdr of a pair from a +list to a non-list or vice versa may cause list? to +produce the wrong value—for the mutated pair or for another +pair that reaches the mutated pair.

  • The compiler may reorder or even optimize away a call to +car or cdr on the grounds that pairs are +immutable, in which case a unsafe-set-immutable-car! +or unsafe-set-immutable-cdr! may not have an effect on +the use of car or cdr.

Added in version 7.9.0.18 of package base.

procedure

(unsafe-unbox b)  fixnum?

  b : box?

procedure

(unsafe-set-box! b k)  void?

  b : box?
  k : fixnum?

procedure

(unsafe-unbox* v)  any/c

  v : (and/c box? (not/c impersonator?))

procedure

(unsafe-set-box*! v val)  void?

  v : (and/c box? (not/c impersonator?))
  val : any/c
Unsafe versions of unbox and set-box!, where the +box* variants can be faster but do not work on +impersonators.

procedure

(unsafe-box*-cas! loc old new)  boolean?

  loc : box?
  old : any/c
  new : any/c
Unsafe version of box-cas!. Like unsafe-set-box*!, it does +not work on impersonators.

procedure

(unsafe-vector-length v)  fixnum?

  v : vector?

procedure

(unsafe-vector-ref v k)  any/c

  v : vector?
  k : fixnum?

procedure

(unsafe-vector-set! v k val)  void?

  v : vector?
  k : fixnum?
  val : any/c

procedure

(unsafe-vector*-length v)  fixnum?

  v : (and/c vector? (not/c impersonator?))

procedure

(unsafe-vector*-ref v k)  any/c

  v : (and/c vector? (not/c impersonator?))
  k : fixnum?

procedure

(unsafe-vector*-set! v k val)  void?

  v : (and/c vector? (not/c impersonator?))
  k : fixnum?
  val : any/c

procedure

(unsafe-vector*-cas! v k old-val new-val)  boolean?

  v : (and/c vector? (not/c impersonator?))
  k : fixnum?
  old-val : any/c
  new-val : any/c
Unsafe versions of vector-length, vector-ref, +vector-set!, and vector-cas!, where the vector* variants can be +faster but do not work on impersonators.

A vector’s size can never be larger than a fixnum, so even +vector-length always returns a fixnum.

Changed in version 6.11.0.2 of package base: Added unsafe-vector*-cas!.

Similar to vector->immutable-vector, but potentially destroys +v and reuses it space, so v must not be used after +calling unsafe-vector*->immutable-vector!.

Added in version 7.7.0.6 of package base.

procedure

(unsafe-string-length str)  fixnum?

  str : string?

procedure

(unsafe-string-ref str k)

  (and/c char? (lambda (ch) (<= 0 (char->integer ch) 255)))
  str : string?
  k : fixnum?

procedure

(unsafe-string-set! str k ch)  void?

  str : (and/c string? (not/c immutable?))
  k : fixnum?
  ch : char?
Unsafe versions of string-length, string-ref, and +string-set!. The unsafe-string-ref procedure can be used +only when the result will be a Latin-1 character. A string’s size can +never be larger than a fixnum (so even string-length +always returns a fixnum).

procedure

(unsafe-string->immutable-string! str)

  (and/c string? immutable?)
  str : string?
Similar to string->immutable-string, but potentially destroys +str and reuses it space, so str must not be used +after calling unsafe-string->immutable-string!.

Added in version 7.7.0.6 of package base.

procedure

(unsafe-bytes-length bstr)  fixnum?

  bstr : bytes?

procedure

(unsafe-bytes-ref bstr k)  byte?

  bstr : bytes?
  k : fixnum?

procedure

(unsafe-bytes-set! bstr k b)  void?

  bstr : (and/c bytes? (not/c immutable?))
  k : fixnum?
  b : byte?

procedure

(unsafe-bytes-copy! dest    
  dest-start    
  src    
  [src-start    
  src-end])  void?
  dest : (and/c bytes? (not/c immutable?))
  dest-start : fixnum?
  src : bytes?
  src-start : fixnum? = 0
  src-end : fixnum? = (bytes-length src)
Unsafe versions of bytes-length, bytes-ref, +bytes-set!, and bytes-copy!. +A bytes’s size can never be larger than a +fixnum (so even bytes-length always returns a +fixnum).

Changed in version 7.5.0.15 of package base: Added unsafe-bytes-copy!.

procedure

(unsafe-bytes->immutable-bytes! bstr)

  (and/c bytes? immutable?)
  bstr : bytes?
Similar to bytes->immutable-bytes, but potentially destroys +bstr and reuses it space, so bstr must not be used +after calling unsafe-bytes->immutable-bytes!.

Added in version 7.7.0.6 of package base.

procedure

(unsafe-fxvector-length v)  fixnum?

  v : fxvector?

procedure

(unsafe-fxvector-ref v k)  fixnum?

  v : fxvector?
  k : fixnum?

procedure

(unsafe-fxvector-set! v k x)  void?

  v : fxvector?
  k : fixnum?
  x : fixnum?
Unsafe versions of fxvector-length, fxvector-ref, and +fxvector-set!. A fxvector’s size can never be larger than a +fixnum (so even fxvector-length always returns a +fixnum).

procedure

(unsafe-flvector-length v)  fixnum?

  v : flvector?

procedure

(unsafe-flvector-ref v k)  flonum?

  v : flvector?
  k : fixnum?

procedure

(unsafe-flvector-set! v k x)  void?

  v : flvector?
  k : fixnum?
  x : flonum?
Unsafe versions of flvector-length, flvector-ref, and +flvector-set!. A flvector’s size can never be larger than a +fixnum (so even flvector-length always returns a +fixnum).

procedure

(unsafe-f64vector-ref vec k)  flonum?

  vec : f64vector?
  k : fixnum?

procedure

(unsafe-f64vector-set! vec k n)  void?

  vec : f64vector?
  k : fixnum?
  n : flonum?
Unsafe versions of f64vector-ref and +f64vector-set!.

procedure

(unsafe-s16vector-ref vec k)  (integer-in -32768 32767)

  vec : s16vector?
  k : fixnum?

procedure

(unsafe-s16vector-set! vec k n)  void?

  vec : s16vector?
  k : fixnum?
  n : (integer-in -32768 32767)
Unsafe versions of s16vector-ref and +s16vector-set!.

procedure

(unsafe-u16vector-ref vec k)  (integer-in 0 65535)

  vec : u16vector?
  k : fixnum?

procedure

(unsafe-u16vector-set! vec k n)  void?

  vec : u16vector?
  k : fixnum?
  n : (integer-in 0 65535)
Unsafe versions of u16vector-ref and +u16vector-set!.

procedure

(unsafe-stencil-vector mask v ...)  stencil-vector?

  mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  v : any/c

procedure

(unsafe-stencil-vector-mask vec)

  (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  vec : stencil-vector?

procedure

(unsafe-stencil-vector-length vec)

  (integer-in 0 (sub1 (stencil-vector-mask-width)))
  vec : stencil-vector?

procedure

(unsafe-stencil-vector-ref vec pos)  any/c

  vec : stencil-vector?
  pos : exact-nonnegative-integer?

procedure

(unsafe-stencil-vector-set! vec pos v)  avoid?

  vec : stencil-vector?
  pos : exact-nonnegative-integer?
  v : any/c

procedure

(unsafe-stencil-vector-update vec    
  remove-mask    
  add-mask    
  v ...)  stencil-vector?
  vec : stencil-vector?
  remove-mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  add-mask : (integer-in 0 (sub1 (expt 2 (stencil-vector-mask-width))))
  v : any/c

Added in version 8.5.0.7 of package base.

procedure

(unsafe-struct-ref v k)  any/c

  v : any/c
  k : fixnum?

procedure

(unsafe-struct-set! v k val)  void?

  v : any/c
  k : fixnum?
  val : any/c

procedure

(unsafe-struct*-ref v k)  any/c

  v : (not/c impersonator?)
  k : fixnum?

procedure

(unsafe-struct*-set! v k val)  void?

  v : (not/c impersonator?)
  k : fixnum?
  val : any/c

procedure

(unsafe-struct*-cas! v k old-val new-val)  boolean?

  v : (not/c impersonator?)
  k : fixnum?
  old-val : any/c
  new-val : any/c
Unsafe field access and update for an instance of a structure +type, where the struct* variants can be +faster but do not work on impersonators. +The index k must be between 0 (inclusive) and +the number of fields in the structure (exclusive). In the case of +unsafe-struct-set!, unsafe-struct*-set!, and unsafe-struct*-cas!, the +field must be mutable. The unsafe-struct*-cas! operation +is analogous to box-cas! to perform an atomic compare-and-set.

Changed in version 6.11.0.2 of package base: Added unsafe-struct*-cas!.

procedure

(unsafe-mutable-hash-iterate-first hash)  (or/c #f any/c)

  hash : (and/c hash? (not/c immutable?) hash-strong?)

procedure

(unsafe-mutable-hash-iterate-next hash pos)  (or/c #f any/c)

  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c

procedure

(unsafe-mutable-hash-iterate-key hash pos)  any/c

  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c

procedure

(unsafe-mutable-hash-iterate-key hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-mutable-hash-iterate-value hash    
  pos)  any/c
  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c

procedure

(unsafe-mutable-hash-iterate-value hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-mutable-hash-iterate-key+value hash    
  pos)  
any/c any/c
  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c

procedure

(unsafe-mutable-hash-iterate-key+value hash 
  pos 
  bad-index-v) 
  
any/c any/c
  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-mutable-hash-iterate-pair hash pos)  pair?

  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c

procedure

(unsafe-mutable-hash-iterate-pair hash    
  pos    
  bad-index-v)  pair?
  hash : (and/c hash? (not/c immutable?) hash-strong?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-immutable-hash-iterate-first hash)  (or/c #f any/c)

  hash : (and/c hash? immutable?)

procedure

(unsafe-immutable-hash-iterate-next hash    
  pos)  (or/c #f any/c)
  hash : (and/c hash? immutable?)
  pos : any/c

procedure

(unsafe-immutable-hash-iterate-key hash    
  pos)  any/c
  hash : (and/c hash? immutable?)
  pos : any/c

procedure

(unsafe-immutable-hash-iterate-key hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? immutable?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-immutable-hash-iterate-value hash    
  pos)  any/c
  hash : (and/c hash? immutable?)
  pos : any/c

procedure

(unsafe-immutable-hash-iterate-value hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? immutable?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-immutable-hash-iterate-key+value hash    
  pos)  
any/c any/c
  hash : (and/c hash? immutable?)
  pos : any/c

procedure

(unsafe-immutable-hash-iterate-key+value hash 
  pos 
  bad-index-v) 
  
any/c any/c
  hash : (and/c hash? immutable?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-immutable-hash-iterate-pair hash    
  pos)  pair?
  hash : (and/c hash? immutable?)
  pos : any/c

procedure

(unsafe-immutable-hash-iterate-pair hash    
  pos    
  bad-index-v)  pair?
  hash : (and/c hash? immutable?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-weak-hash-iterate-first hash)  (or/c #f any/c)

  hash : (and/c hash? hash-weak?)

procedure

(unsafe-weak-hash-iterate-next hash pos)  (or/c #f any/c)

  hash : (and/c hash? hash-weak?)
  pos : any/c

procedure

(unsafe-weak-hash-iterate-key hash pos)  any/c

  hash : (and/c hash? hash-weak?)
  pos : any/c

procedure

(unsafe-weak-hash-iterate-key hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? hash-weak?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-weak-hash-iterate-value hash pos)  any/c

  hash : (and/c hash? hash-weak?)
  pos : any/c

procedure

(unsafe-weak-hash-iterate-value hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? hash-weak?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-weak-hash-iterate-key+value hash    
  pos)  
any/c any/c
  hash : (and/c hash? hash-weak?)
  pos : any/c

procedure

(unsafe-weak-hash-iterate-key+value hash    
  pos    
  bad-index-v)  
any/c any/c
  hash : (and/c hash? hash-weak?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-weak-hash-iterate-pair hash pos)  pair?

  hash : (and/c hash? hash-weak?)
  pos : any/c

procedure

(unsafe-weak-hash-iterate-pair hash    
  pos    
  bad-index-v)  pair?
  hash : (and/c hash? hash-weak?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-ephemeron-hash-iterate-first hash)  (or/c #f any/c)

  hash : (and/c hash? hash-ephemeron?)

procedure

(unsafe-ephemeron-hash-iterate-next hash    
  pos)  (or/c #f any/c)
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c

procedure

(unsafe-ephemeron-hash-iterate-key hash    
  pos)  any/c
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c

procedure

(unsafe-ephemeron-hash-iterate-key hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-ephemeron-hash-iterate-value hash    
  pos)  any/c
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c

procedure

(unsafe-ephemeron-hash-iterate-value hash    
  pos    
  bad-index-v)  any/c
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-ephemeron-hash-iterate-key+value hash    
  pos)  
any/c any/c
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c

procedure

(unsafe-ephemeron-hash-iterate-key+value hash 
  pos 
  bad-index-v) 
  
any/c any/c
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c
  bad-index-v : any/c

procedure

(unsafe-ephemeron-hash-iterate-pair hash    
  pos)  pair?
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c

procedure

(unsafe-ephemeron-hash-iterate-pair hash    
  pos    
  bad-index-v)  pair?
  hash : (and/c hash? hash-ephemeron?)
  pos : any/c
  bad-index-v : any/c
Unsafe versions of hash-iterate-key and similar procedures. +These operations support chaperones and impersonators.

Each unsafe ...-first and ...-next procedure may return, +instead of a number index, an internal representation of a view into +the hash structure, enabling faster iteration. The result of these +...-first and ...-next functions should be given as +pos to the corresponding unsafe accessor functions.

If the pos provided to an accessor function for a mutable +hash was formerly a valid hash index but is no longer +a valid hash index for hash, and if +bad-index-v is not provided, then the +exn:fail:contract exception is raised. No behavior is specified for a +pos that was never a valid hash index for +hash. Note that bad-index-v argument is technically +not useful for the unsafe-immutable-hash-iterate- functions, +since an index cannot become invalid for an immutable hash.

Added in version 6.4.0.6 of package base.
Changed in version 7.0.0.10: Added the optional bad-index-v argument.
Changed in version 8.0.0.10: Added ephemeron variants.

procedure

(unsafe-make-srcloc source    
  line    
  column    
  position    
  span)  srcloc?
  source : any/c
  line : (or/c exact-positive-integer? #f)
  column : (or/c exact-nonnegative-integer? #f)
  position : (or/c exact-positive-integer? #f)
  span : (or/c exact-nonnegative-integer? #f)
Unsafe version of srcloc.

Added in version 7.2.0.10 of package base.

17.4 Unsafe Extflonum Operations

procedure

(unsafe-extfl+ a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extfl- a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extfl* a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extfl/ a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extflabs a)  extflonum?

  a : extflonum?
Unchecked versions of extfl+, extfl-, +extfl*, extfl/, and extflabs.

procedure

(unsafe-extfl= a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extfl< a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extfl> a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extfl<= a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extfl>= a b)  boolean?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extflmin a b)  extflonum?

  a : extflonum?
  b : extflonum?

procedure

(unsafe-extflmax a b)  extflonum?

  a : extflonum?
  b : extflonum?
Unchecked versions of extfl=, extfl<, +extfl>, extfl<=, extfl>=, extflmin, and +extflmax.

procedure

(unsafe-extflround a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflfloor a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflceiling a)  extflonum?

  a : extflonum?

procedure

(unsafe-extfltruncate a)  extflonum?

  a : extflonum?
Unchecked (potentially) versions of extflround, +extflfloor, extflceiling, and +extfltruncate. Currently, these bindings are simply aliases +for the corresponding safe bindings.

procedure

(unsafe-extflsin a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflcos a)  extflonum?

  a : extflonum?

procedure

(unsafe-extfltan a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflasin a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflacos a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflatan a)  extflonum?

  a : extflonum?

procedure

(unsafe-extfllog a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflexp a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflsqrt a)  extflonum?

  a : extflonum?

procedure

(unsafe-extflexpt a b)  extflonum?

  a : extflonum?
  b : extflonum?
Unchecked (potentially) versions of extflsin, +extflcos, extfltan, extflasin, +extflacos, extflatan, extfllog, +extflexp, extflsqrt, and +extflexpt. Currently, some of these bindings are simply +aliases for the corresponding safe bindings.

procedure

(unsafe-fx->extfl a)  extflonum?

  a : fixnum?

procedure

(unsafe-extfl->fx a)  fixnum?

  a : extflonum?
Unchecked (potentially) versions of fx->extfl and extfl->fx.

Changed in version 7.7.0.8 of package base: Changed unsafe-fl->fx to truncate.

procedure

(unsafe-extflvector-length v)  fixnum?

  v : extflvector?

procedure

(unsafe-extflvector-ref v k)  extflonum?

  v : extflvector?
  k : fixnum?

procedure

(unsafe-extflvector-set! v k x)  void?

  v : extflvector?
  k : fixnum?
  x : extflonum?
Unchecked versions of extflvector-length, extflvector-ref, and +extflvector-set!. A extflvector’s size can never be larger than a +fixnum (so even extflvector-length always returns a +fixnum).

17.5 Unsafe Impersonators and Chaperones

procedure

(unsafe-impersonate-procedure proc 
  replacement-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c procedure? impersonator?)
  proc : procedure?
  replacement-proc : procedure?
  prop : impersonator-property?
  prop-val : any
Like impersonate-procedure, but assumes that +replacement-proc calls proc itself. When the result +of unsafe-impersonate-procedure is applied to arguments, the +arguments are passed on to replacement-proc directly, +ignoring proc. At the same time, impersonator-of? +reports #t when given the result of +unsafe-impersonate-procedure and proc.

If proc is itself an impersonator that is derived from +impersonate-procedure* or chaperone-procedure*, +beware that replacement-proc will not be able to call it +correctly. Specifically, the impersonator produced by +unsafe-impersonate-procedure will not get passed to a +wrapper procedure that was supplied to +impersonate-procedure* or chaperone-procedure* to +generate proc.

Finally, unlike impersonate-procedure, +unsafe-impersonate-procedure does not specially handle +impersonator-prop:application-mark as a prop.

The unsafety of unsafe-impersonate-procedure is limited to +the above differences from impersonate-procedure. The +contracts on the arguments of unsafe-impersonate-procedure are +checked when the arguments are supplied.

As an example, assuming that f accepts a single argument and +is not derived from impersonate-procedure* or +chaperone-procedure*, then +
(λ (f)
  (unsafe-impersonate-procedure
   f
   (λ (x)
     (if (number? x)
         (error 'no-numbers!)
         (f x)))))
is equivalent to +
(λ (f)
  (impersonate-procedure
   f
   (λ (x)
     (if (number? x)
         (error 'no-numbers!)
         x))))

Similarly, with the same assumptions about f, the following +two procedures wrap-f1 and +wrap-f2 are almost equivalent; they differ only +in the error message produced when their arguments are +functions that return multiple values (and that they update +different global variables). The version using unsafe-impersonate-procedure +will signal an error in the let expression about multiple +return values, whereas the one using impersonate-procedure signals +an error from impersonate-procedure about multiple return values. +
(define log1-args '())
(define log1-results '())
(define wrap-f1
  (λ (f)
    (impersonate-procedure
     f
     (λ (arg)
       (set! log1-args (cons arg log1-args))
       (values (λ (res)
                 (set! log1-results (cons res log1-results))
                 res)
               arg)))))
 
(define log2-args '())
(define log2-results '())
(define wrap-f2
  (λ (f)
    (unsafe-impersonate-procedure
     f
     (λ (arg)
       (set! log2-args (cons arg log2-args))
       (let ([res (f arg)])
         (set! log2-results (cons res log2-results))
         res)))))

Added in version 6.4.0.4 of package base.

procedure

(unsafe-chaperone-procedure proc 
  wrapper-proc 
  prop 
  prop-val ... 
  ...) 
  (and/c procedure? chaperone?)
  proc : procedure?
  wrapper-proc : procedure?
  prop : impersonator-property?
  prop-val : any
Like unsafe-impersonate-procedure, but creates a chaperone. +Since wrapper-proc will be called in lieu of proc, +wrapper-proc is assumed to return a chaperone of the value that +proc would return.

Added in version 6.4.0.4 of package base.

procedure

(unsafe-impersonate-vector vec 
  replacement-vec 
  prop 
  prop-val ... 
  ...) 
  (and/c vector? impersonator?)
  vec : vector?
  replacement-vec : (and/c vector? (not/c impersonator?))
  prop : impersonator-property?
  prop-val : any/c
Like impersonate-vector, but instead of going through interposition procedures, all +accesses to the impersonator are dispatched to replacement-vec.

The result of unsafe-impersonate-vector is an impersonator of vec.

Added in version 6.9.0.2 of package base.

procedure

(unsafe-chaperone-vector vec 
  replacement-vec 
  prop 
  prop-val ... 
  ...) 
  (and/c vector? chaperone?)
  vec : vector?
  replacement-vec : (and/c vector? (not/c impersonator?))
  prop : impersonator-property?
  prop-val : any/c
Like unsafe-impersonate-vector, but the result of unsafe-chaperone-vector is a +chaperone of vec.

Added in version 6.9.0.2 of package base.

17.6 Unsafe Assertions

Like assert-unreachable, but the contract of +unsafe-assert-unreachable is never satisfied, and the +“unsafe” implication is that anything at all can happen if a call to +unsafe-assert-unreachable is reached.

The compiler may take advantage of its liberty to pick convenient or +efficient behavior in place of a call to +unsafe-assert-unreachable. For example, the expression

(lambda (x)
  (if (pair? x)
      (car x)
      (unsafe-assert-unreachable)))

may be compiled to code equivalent to

(lambda (x) (unsafe-car x))

because choosing to make (unsafe-assert-unreachable) behave +the same as (unsafe-car x) makes both branches of the +if the same, and then pair? test can be eliminated.

Added in version 8.0.0.11 of package base.

17.7 Unsafe Undefined

The bindings documented in this section are provided by the racket/unsafe/undefined library, not racket/base or racket.

The constant unsafe-undefined is used internally as a +placeholder value. For example, it is used by letrec as a +value for a variable that has not yet been assigned a value. Unlike +the undefined value exported by racket/undefined, +however, the unsafe-undefined value should not leak as the +result of a safe expression, and it should not be passed as an optional +argument to a procedure (because it may count as “no value provided”). +Expression results that potentially +produce unsafe-undefined can be guarded by +check-not-unsafe-undefined, so that an exception can be +raised instead of producing an undefined value.

The unsafe-undefined value is always eq? to itself.

Added in version 6.0.1.2 of package base.
Changed in version 6.90.0.29: Procedures with optional arguments +sometimes use the unsafe-undefined +value internally to mean “no argument supplied.”

The unsafe “undefined” constant.

See above for important constraints on the use of unsafe-undefined.

procedure

(check-not-unsafe-undefined v sym)

  (and/c any/c (not/c (one-of/c unsafe-undefined)))
  v : any/c
  sym : symbol?
Checks whether v is unsafe-undefined, and raises +exn:fail:contract:variable in that case with an error message +along the lines of “sym: undefined; use before +initialization.” If v is not unsafe-undefined, +then v is returned.

procedure

(check-not-unsafe-undefined/assign v sym)

  (and/c any/c (not/c (one-of/c unsafe-undefined)))
  v : any/c
  sym : symbol?
The same as check-not-unsafe-undefined, except that the error +message (if any) is along the lines of “sym: undefined; +assignment before initialization.”

procedure

(chaperone-struct-unsafe-undefined v)  any/c

  v : any/c
Chaperones v if it is a structure (as viewed through some +inspector). Every access of a field in the structure is checked +to prevent returning unsafe-undefined. Similarly, every +assignment to a field in the structure is checked (unless the check +disabled as described below) to prevent assignment of a field whose +current value is unsafe-undefined.

When a field access would otherwise produce unsafe-undefined +or when a field assignment would replace unsafe-undefined, the +exn:fail:contract exception is raised.

The chaperone’s field-assignment check is disabled whenever +(continuation-mark-set-first #f prop:chaperone-unsafe-undefined) returns unsafe-undefined. +Thus, a field-initializing assignment—one that is intended to replace the +unsafe-undefined value of a field—should be wrapped with +(with-continuation-mark prop:chaperone-unsafe-undefined unsafe-undefined ....).

A structure type property that causes a structure type’s +constructor to produce a chaperone of an instance +in the same way as chaperone-struct-unsafe-undefined.

The property value should be a list of symbols used as field names, +but the list should be in reverse order of the structure’s fields. +When a field access or assignment would produce or replace +unsafe-undefined, the exn:fail:contract:variable +exception is raised if a field name is provided by the structure +property’s value, otherwise the exn:fail:contract exception +is raised.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/values.html b/clones/docs.racket-lang.org/reference/values.html new file mode 100644 index 00000000..2751887e --- /dev/null +++ b/clones/docs.racket-lang.org/reference/values.html @@ -0,0 +1,12 @@ + +10.1 Multiple Values

10.1 Multiple Values

See Multiple Return Values for general information about multiple +result values. In addition to call-with-values (described in +this section), the let-values, let*-values, +letrec-values, and define-values forms (among +others) create continuations that receive multiple values.

procedure

(values v ...)  any

  v : any/c
Returns the given vs. That is, values returns its +provided arguments.

Examples:
> (values 1)

1

> (values 1 2 3)

1

2

3

> (values)

procedure

(call-with-values generator receiver)  any

  generator : (-> any)
  receiver : procedure?
Calls generator, and passes the values that +generator produces as arguments to receiver. Thus, +call-with-values creates a continuation that accepts any +number of values that receiver can accept. The +receiver procedure is called in tail position with respect to +the call-with-values call.

Examples:
> (call-with-values (lambda () (values 1 2)) +)

3

> (call-with-values (lambda () 1) (lambda (x y) (+ x y)))

arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 2

  given: 1

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/vectors.html b/clones/docs.racket-lang.org/reference/vectors.html new file mode 100644 index 00000000..d27e7465 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/vectors.html @@ -0,0 +1,84 @@ + +4.12 Vectors

4.12 Vectors

+Vectors in The Racket Guide introduces vectors.

A vector is a fixed-length array with constant-time access +and update of the vector slots, which are numbered from 0 to +one less than the number of slots in the vector.

Two vectors are equal? if they have the same length, and if +the values in corresponding slots of the vectors are +equal?.

A vector can be mutable or immutable. When an +immutable vector is provided to a procedure like vector-set!, +the exn:fail:contract exception is raised. Vectors generated by the default +reader (see Reading Strings) are immutable. Use +immutable? to check whether a vector is immutable.

A vector can be used as a single-valued sequence (see +Sequences). The elements of the vector serve as elements +of the sequence. See also in-vector.

A literal or printed vector starts with #(, optionally with +a number between the # and +(. See Reading Vectors + for information on reading + vectors and Printing Vectors + for information on printing vectors.

procedure

(vector? v)  boolean?

  v : any/c
Returns #t if v is a vector, #f otherwise.

procedure

(make-vector size [v])  vector?

  size : exact-nonnegative-integer?
  v : any/c = 0
Returns a mutable vector with size slots, where all slots are +initialized to contain v.

This function takes time proportional to size.

procedure

(vector v ...)  vector?

  v : any/c
Returns a newly allocated mutable vector with as many slots as provided vs, +where the slots are initialized to contain the given vs in +order.

procedure

(vector-immutable v ...)  
(and/c vector?
       immutable?)
  v : any/c
Returns a newly allocated immutable vector with as many slots as provided +vs, where the slots contain the given vs in +order.

procedure

(vector-length vec)  exact-nonnegative-integer?

  vec : vector?
Returns the length of vec (i.e., the number of slots in the +vector).

This function takes constant time.

procedure

(vector-ref vec pos)  any/c

  vec : vector?
  pos : exact-nonnegative-integer?
Returns the element in slot pos of vec. The first +slot is position 0, and the last slot is one less than +(vector-length vec).

This function takes constant time.

procedure

(vector-set! vec pos v)  void?

  vec : (and/c vector? (not/c immutable?))
  pos : exact-nonnegative-integer?
  v : any/c
Updates the slot pos of vec to contain v.

This function takes constant time.

procedure

(vector*-length vec)  exact-nonnegative-integer?

  vec : (and/c vector? (not/c impersonator?))

procedure

(vector*-ref vec pos)  any/c

  vec : (and/c vector? (not/c impersonator?))
  pos : exact-nonnegative-integer?

procedure

(vector*-set! vec pos v)  void?

  vec : (and/c vector? (not/c immutable?)  (not/c impersonator?))
  pos : exact-nonnegative-integer?
  v : any/c
Like vector-length, vector-ref, and +vector-set!, but constrained to work on vectors that are not +impersonators.

Added in version 6.90.0.15 of package base.

procedure

(vector-cas! vec pos old-v new-v)  boolean?

  vec : (and/c vector? (not/c immutable?) (not/c impersonator?))
  pos : exact-nonnegative-integer?
  old-v : any/c
  new-v : any/c
Compare and set operation for vectors. See box-cas!.

Added in version 6.11.0.2 of package base.

procedure

(vector->list vec)  list?

  vec : vector?
Returns a list with the same length and elements as vec.

This function takes time proportional to the size of vec.

procedure

(list->vector lst)  vector?

  lst : list?
Returns a mutable vector with the same length and elements as +lst.

This function takes time proportional to the length of lst.

procedure

(vector->immutable-vector vec)  (and/c vector? immutable?)

  vec : vector?
Returns an immutable vector with the same length and elements as vec. +If vec is itself immutable, then it is returned as the result.

This function takes time proportional to the size of vec when +vec is mutable.

procedure

(vector-fill! vec v)  void?

  vec : (and/c vector? (not/c immutable?))
  v : any/c
Changes all slots of vec to contain v.

This function takes time proportional to the size of vec.

procedure

(vector-copy! dest    
  dest-start    
  src    
  [src-start    
  src-end])  void?
  dest : (and/c vector? (not/c immutable?))
  dest-start : exact-nonnegative-integer?
  src : vector?
  src-start : exact-nonnegative-integer? = 0
  src-end : exact-nonnegative-integer? = (vector-length src)
Changes the elements of dest starting at position + dest-start to match the elements in src from + src-start (inclusive) to src-end (exclusive). The + vectors dest and src can be the same vector, and in + that case the destination region can overlap with the source region; + the destination elements after the copy match the source elements + from before the copy. If any of dest-start, + src-start, or src-end are out of range (taking into + account the sizes of the vectors and the source and destination + regions), the exn:fail:contract exception is raised.

This function takes time proportional to (- src-end src-start).

Examples:
> (define v (vector 'A 'p 'p 'l 'e))
> (vector-copy! v 4 #(y))
> (vector-copy! v 0 v 3 4)
> v

'#(l p p l y)

procedure

(vector->values vec [start-pos end-pos])  any

  vec : vector?
  start-pos : exact-nonnegative-integer? = 0
  end-pos : exact-nonnegative-integer? = (vector-length vec)
Returns end-pos - start-pos values, which are +the elements of vec from start-pos (inclusive) to +end-pos (exclusive). If start-pos or +end-pos are greater than (vector-length vec), or if +end-pos is less than start-pos, the +exn:fail:contract exception is raised.

This function takes time proportional to the size of vec.

procedure

(build-vector n proc)  vector?

  n : exact-nonnegative-integer?
  proc : (exact-nonnegative-integer? . -> . any/c)
Creates a vector of n elements by applying proc to +the integers from 0 to (sub1 n) in order. If +vec is the resulting vector, then (vector-ref vec i) is the value produced by (proc i).

Example:
> (build-vector 5 add1)

'#(1 2 3 4 5)

4.12.1 Additional Vector Functions

 (require racket/vector) package: base
The bindings documented in this section are provided by the racket/vector and racket libraries, but not racket/base.

procedure

(vector-empty? v)  boolean?

  v : vector?
Returns #t if v is empty (i.e. its length is 0), #f otherwise.

Added in version 7.4.0.4 of package base.

procedure

(vector-set*! vec pos v ... ...)  void?

  vec : (and/c vector? (not/c immutable?))
  pos : exact-nonnegative-integer?
  v : any/c
Updates each slot pos of vec to contain each v. +The update takes place from the left so later updates overwrite earlier updates.

procedure

(vector-map proc vec ...+)  vector?

  proc : procedure?
  vec : vector?
Applies proc to the elements of the vecs from the + first elements to the last. The proc argument must accept + the same number of arguments as the number of supplied vecs, + and all vecs must have the same number of elements. The + result is a fresh vector containing each result of proc in + order.

Example:
> (vector-map + #(1 2) #(3 4))

'#(4 6)

procedure

(vector-map! proc vec ...+)  vector?

  proc : procedure?
  vec : (and/c vector? (not/c immutable?))
Like vector-map, but result of proc is inserted into + the first vec at the index that the arguments to + proc were taken from. The result is the first vec.

Examples:
> (define v (vector 1 2 3 4))
> (vector-map! add1 v)

'#(2 3 4 5)

> v

'#(2 3 4 5)

procedure

(vector-append vec ...)  vector?

  vec : vector?
Creates a fresh vector that contains all +of the elements of the given vectors in order.

Example:
> (vector-append #(1 2) #(3 4))

'#(1 2 3 4)

procedure

(vector-take vec pos)  vector?

  vec : vector?
  pos : exact-nonnegative-integer?
Returns a fresh vector whose elements are the first pos elements of +vec. If vec has fewer than +pos elements, then the exn:fail:contract exception is raised.

Example:
> (vector-take #(1 2 3 4) 2)

'#(1 2)

procedure

(vector-take-right vec pos)  vector?

  vec : vector?
  pos : exact-nonnegative-integer?
Returns a fresh vector whose elements are the last pos elements of +vec. If vec has fewer than +pos elements, then the exn:fail:contract exception is raised.

Example:
> (vector-take-right #(1 2 3 4) 2)

'#(3 4)

procedure

(vector-drop vec pos)  vector?

  vec : vector?
  pos : exact-nonnegative-integer?
Returns a fresh vector whose elements are the elements of vec + after the first pos elements. If vec has fewer + than pos elements, then the exn:fail:contract exception is raised.

Example:
> (vector-drop #(1 2 3 4) 2)

'#(3 4)

procedure

(vector-drop-right vec pos)  vector?

  vec : vector?
  pos : exact-nonnegative-integer?
Returns a fresh vector whose elements are the prefix of vec, +dropping its pos-length tail. If vec has fewer +than pos elements, then the exn:fail:contract exception is raised.

Examples:
> (vector-drop-right #(1 2 3 4) 1)

'#(1 2 3)

> (vector-drop-right #(1 2 3 4) 3)

'#(1)

procedure

(vector-split-at vec pos)  
vector? vector?
  vec : vector?
  pos : exact-nonnegative-integer?
Returns the same result as

(values (vector-take vec pos) (vector-drop vec pos))

except that it can be faster.

Example:
> (vector-split-at #(1 2 3 4 5) 2)

'#(1 2)

'#(3 4 5)

procedure

(vector-split-at-right vec pos)  
vector? vector?
  vec : vector?
  pos : exact-nonnegative-integer?
Returns the same result as

(values (vector-take-right vec pos) (vector-drop-right vec pos))

except that it can be faster.

Example:
> (vector-split-at-right #(1 2 3 4 5) 2)

'#(1 2 3)

'#(4 5)

procedure

(vector-copy vec [start end])  vector?

  vec : vector?
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (vector-length v)
Creates a fresh vector of size (- end start), with all of the +elements of vec from start (inclusive) to +end (exclusive).

Examples:
> (vector-copy #(1 2 3 4))

'#(1 2 3 4)

> (vector-copy #(1 2 3 4) 3)

'#(4)

> (vector-copy #(1 2 3 4) 2 3)

'#(3)

procedure

(vector-filter pred vec)  vector?

  pred : procedure?
  vec : vector?
Returns a fresh vector with the elements of vec for which + pred produces a true value. The pred procedure is + applied to each element from first to last.

Example:
> (vector-filter even? #(1 2 3 4 5 6))

'#(2 4 6)

procedure

(vector-filter-not pred vec)  vector?

  pred : procedure?
  vec : vector?
Like vector-filter, but the meaning of the pred predicate +is reversed: the result is a vector of all items for which pred +returns #f.

Example:
> (vector-filter-not even? #(1 2 3 4 5 6))

'#(1 3 5)

procedure

(vector-count proc vec ...+)  exact-nonnegative-integer?

  proc : procedure?
  vec : vector?
Returns the number of elements of the vec ... (taken in +parallel) on which proc does not evaluate to #f.

Examples:
> (vector-count even? #(1 2 3 4 5))

2

> (vector-count = #(1 2 3 4 5) #(5 4 3 2 1))

1

procedure

(vector-argmin proc vec)  any/c

  proc : (-> any/c real?)
  vec : vector?
This returns the first element in the non-empty vector vec that minimizes +the result of proc.

Examples:
> (vector-argmin car #((3 pears) (1 banana) (2 apples)))

'(1 banana)

> (vector-argmin car #((1 banana) (1 orange)))

'(1 banana)

procedure

(vector-argmax proc vec)  any/c

  proc : (-> any/c real?)
  vec : vector?
This returns the first element in the non-empty vector vec that maximizes +the result of proc.

Examples:
> (vector-argmax car #((3 pears) (1 banana) (2 apples)))

'(3 pears)

> (vector-argmax car #((3 pears) (3 oranges)))

'(3 pears)

procedure

(vector-member v vec)  (or/c natural-number/c #f)

  v : any/c
  vec : vector?
Locates the first element of vec that is equal? to + v. If such an element exists, the index of that element in + vec is returned. Otherwise, the result is #f.

Examples:
> (vector-member 2 (vector 1 2 3 4))

1

> (vector-member 9 (vector 1 2 3 4))

#f

procedure

(vector-memv v vec)  (or/c natural-number/c #f)

  v : any/c
  vec : vector?
Like vector-member, but finds an element using eqv?. +

Examples:
> (vector-memv 2 (vector 1 2 3 4))

1

> (vector-memv 9 (vector 1 2 3 4))

#f

procedure

(vector-memq v vec)  (or/c natural-number/c #f)

  v : any/c
  vec : vector?
Like vector-member, but finds an element using eq?.

Examples:
> (vector-memq 2 (vector 1 2 3 4))

1

> (vector-memq 9 (vector 1 2 3 4))

#f

procedure

(vector-sort vec    
  less-than?    
  [start    
  end    
  #:key key    
  #:cache-keys? cache-keys?])  vector?
  vec : vector?
  less-than? : (any/c any/c . -> . any/c)
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (vector-length vec)
  key : (any/c . -> . any/c) = (λ (x) x)
  cache-keys? : boolean? = #f
Like sort, but operates on vectors; a + fresh vector of length (- end start) is + returned containing the elements from indices + start (inclusive) through end (exclusive) + of vec, but in sorted order (i.e., vec is + not modified). This sort is stable (i.e., the order of “equal” + elements is preserved).

Examples:
> (define v1 (vector 4 3 2 1))
> (vector-sort v1 <)

'#(1 2 3 4)

> v1

'#(4 3 2 1)

> (define v2 (vector '(4) '(3) '(2) '(1)))
> (vector-sort v2 < 1 3 #:key car)

'#((2) (3))

> v2

'#((4) (3) (2) (1))

Added in version 6.6.0.5 of package base.

procedure

(vector-sort! vec    
  less-than?    
  [start    
  end    
  #:key key    
  #:cache-keys? cache-keys?])  void?
  vec : (and/c vector? (not/c immutable?))
  less-than? : (any/c any/c . -> . any/c)
  start : exact-nonnegative-integer? = 0
  end : exact-nonnegative-integer? = (vector-length vec)
  key : (any/c . -> . any/c) = (λ (x) x)
  cache-keys? : boolean? = #f
Like vector-sort, but updates indices + start (inclusive) through end (exclusive) + of vec by sorting them according to the less-than? + procedure.

Examples:
> (define v1 (vector 4 3 2 1))
> (vector-sort! v1 <)
> v1

'#(1 2 3 4)

> (define v2 (vector '(4) '(3) '(2) '(1)))
> (vector-sort! v2 < 1 3 #:key car)
> v2

'#((4) (2) (3) (1))

Added in version 6.6.0.5 of package base.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/void.html b/clones/docs.racket-lang.org/reference/void.html new file mode 100644 index 00000000..b25e6aeb --- /dev/null +++ b/clones/docs.racket-lang.org/reference/void.html @@ -0,0 +1,5 @@ + +4.20 Void

4.20 Void

The constant #<void> is returned by most forms and procedures +that have a side-effect and no useful result.

The #<void> value is always eq? to itself.

procedure

(void? v)  boolean?

  v : any/c
Returns #t if v is the +constant #<void>, #f otherwise.

procedure

(void v ...)  void?

  v : any/c
Returns the constant #<void>. Each +v argument is ignored.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/wcm.html b/clones/docs.racket-lang.org/reference/wcm.html new file mode 100644 index 00000000..df47390f --- /dev/null +++ b/clones/docs.racket-lang.org/reference/wcm.html @@ -0,0 +1,13 @@ + +3.19 Continuation Marks: with-continuation-mark

3.19 Continuation Marks: with-continuation-mark

syntax

(with-continuation-mark key-expr val-expr result-expr)

The key-expr, val-expr, and result-expr +expressions are evaluated in order. After key-expr is +evaluated to obtain a key and val-expr is evaluated to +obtain a value, the key is mapped to the value as a continuation mark in the current +continuation’s initial continuation frame. If the frame already has a mark for the +key, the mark is replaced. Finally, the result-expr is evaluated; +the continuation for evaluating result-expr is the +continuation of the with-continuation-mark expression (so the +result of the result-expr is the result of the +with-continuation-mark expression, and result-expr +is in tail position for the with-continuation-mark +expression).

+Continuation Marks provides more information on continuation marks.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/weakbox.html b/clones/docs.racket-lang.org/reference/weakbox.html new file mode 100644 index 00000000..3d6993bf --- /dev/null +++ b/clones/docs.racket-lang.org/reference/weakbox.html @@ -0,0 +1,14 @@ + +16.1 Weak Boxes

16.1 Weak Boxes

A weak box is similar to a normal box (see +Boxes), but when the garbage collector (see +Garbage Collection) can prove that the content value of a weak box is +only reachable via weak references, the content of the weak box is +replaced with #f. A weak reference is a +reference through a weak box, through a key reference in a weak hash +table (see Hash Tables), through a value in an ephemeron +where the value can be replaced by #f (see +Ephemerons), or through a custodian (see +Custodians).

procedure

(make-weak-box v)  weak-box?

  v : any/c
Returns a new weak box that initially contains v.

procedure

(weak-box-value weak-box [gced-v])  any/c

  weak-box : weak-box?
  gced-v : any/c = #f
Returns the value contained in weak-box. If the garbage +collector has proven that the previous content value of +weak-box was reachable only through a weak reference, then +gced-v (which defaults to #f) is returned.

procedure

(weak-box? v)  boolean?

  v : any/c
Returns #t if v is a weak box, #f otherwise.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/when_unless.html b/clones/docs.racket-lang.org/reference/when_unless.html new file mode 100644 index 00000000..9db72f93 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/when_unless.html @@ -0,0 +1,6 @@ + +3.16 Guarded Evaluation: when and unless
On this page:
when
unless

3.16 Guarded Evaluation: when and unless

+Effects If...: when and unless in The Racket Guide introduces when and unless.

syntax

(when test-expr body ...+)

Evaluates test-expr. If the result is #f, then +the result of the when expression is +#<void>. Otherwise, the bodys are evaluated, and the +last body is in tail position with respect to the +when form.

Examples:
> (when (positive? -5)
    (display "hi"))
> (when (positive? 5)
    (display "hi")
    (display " there"))

hi there

syntax

(unless test-expr body ...+)

Equivalent to (when (not test-expr) body ...+).

Examples:
> (unless (positive? 5)
    (display "hi"))
> (unless (positive? -5)
    (display "hi")
    (display " there"))

hi there

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/willexecutor.html b/clones/docs.racket-lang.org/reference/willexecutor.html new file mode 100644 index 00000000..fbe8cfe6 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/willexecutor.html @@ -0,0 +1,45 @@ + +16.3 Wills and Executors

16.3 Wills and Executors

A will executor manages a collection of values and +associated will procedures +(a.k.a. finalizers). The will procedure for each +value is ready to be executed when the value has been proven (by the +garbage collector) to be unreachable, except through weak references +(see Weak Boxes) or as the registrant for other will +executors. A will is useful for triggering clean-up actions on +data associated with an unreachable value, such as closing a port +embedded in an object when the object is no longer used.

Calling the will-execute or will-try-execute +procedure executes a will that is ready in the specified will +executor. A will executor is also a synchronizable event, so sync +or sync/timeout can be used to detect when a will executor has +ready wills. Wills are not executed automatically, because certain +programs need control to avoid race conditions. However, a program can +create a thread whose sole job is to execute wills for a particular +executor.

If a value is registered with multiple wills (in one or multiple +executors), the wills are readied in the reverse order of +registration. Since readying a will procedure makes the value +reachable again, the will must be executed and the value must be +proven again unreachable through only weak references before another +of the wills is readied or executed. However, wills for distinct +unreachable values are readied at the same time, regardless of whether +the values are reachable from each other.

A will executor’s registrant is held non-weakly until after the +corresponding will procedure is executed. Thus, if the content value +of a weak box (see Weak Boxes) is registered with a will +executor, the weak box’s content is not changed to #f until +all wills have been executed for the value and the value has been +proven again reachable through only weak references.

A will executor can be used as a synchronizable event (see Events). +A will executor is ready for synchronization when +will-execute would not block; the synchronization result of a will executor is the will executor itself.

These examples show how to run cleanup actions when +no synchronization is necessary. It simply runs the registered +executors as they become ready in another thread. +

Examples:
> (define an-executor (make-will-executor))
> (void
   (thread
    (λ ()
      (let loop ()
        (will-execute an-executor)
        (loop)))))
> (define (executor-proc v) (printf "a-box is now garbage\n"))
> (define a-box-to-track (box #f))
> (will-register an-executor a-box-to-track executor-proc)
> (collect-garbage)
> (set! a-box-to-track #f)
> (collect-garbage)

a-box is now garbage

Returns a new will executor with no managed values.

procedure

(will-executor? v)  boolean?

  v : any/c
Returns #t if v is a will executor, #f +otherwise.

procedure

(will-register executor v proc)  void?

  executor : will-executor?
  v : any/c
  proc : (any/c . -> . any)
Registers the value v with the will procedure proc +in the will executor executor. When v is proven +unreachable, then the procedure proc is ready to be called +with v as its argument via will-execute or +will-try-execute. The proc argument is strongly +referenced until the will procedure is executed.

procedure

(will-execute executor)  any

  executor : will-executor?
Invokes the will procedure for a single “unreachable” value +registered with the executor executor. The values returned +by the will procedure are the result of the will-execute +call. If no will is ready for immediate execution, +will-execute blocks until one is ready.

procedure

(will-try-execute executor [v])  any

  executor : any/c
  v : any/c = #f
Like will-execute if a will is ready for immediate +execution. Otherwise, v is returned.

Changed in version 6.90.0.4 of package base: Added the v argument.

 
\ No newline at end of file diff --git a/clones/docs.racket-lang.org/reference/windowspaths.html b/clones/docs.racket-lang.org/reference/windowspaths.html new file mode 100644 index 00000000..78ebbb27 --- /dev/null +++ b/clones/docs.racket-lang.org/reference/windowspaths.html @@ -0,0 +1,245 @@ + +15.1.4 Windows Paths
15.1.4 Windows Paths

In general, a Windows pathname consists of an optional drive specifier +and a drive-specific path. A Windows path can be absolute +but still relative to the current drive; such paths start with a +/ or \ separator and are not UNC paths or paths +that start with \\?\.

A path that starts with a drive specification is complete. +Roughly, a drive specification is either a Latin letter followed by a +colon, a UNC path of the form +\\machine\volume, or a +\\?\ form followed by something other than +REL\element, or +RED\element. (Variants of \\?\ +paths are described further below.)

Racket fails to implement the usual Windows path syntax in one +way. Outside of Racket, a pathname "C:rant.txt" can be a +drive-specific relative path. That is, it names a file "rant.txt" +on drive "C:", but the complete path to the file is determined by +the current working directory for drive "C:". Racket does not +support drive-specific working directories (only a working directory +across all drives, as reflected by the current-directory +parameter). Consequently, Racket implicitly converts a path like +"C:rant.txt" into "C:\rant.txt".

  • Racket-specific: Whenever a path starts with a drive specifier +letter: that is not followed by a +/ or \, a \ is inserted as +the path is cleansed.

Otherwise, Racket follows standard Windows path conventions, but also + adds \\?\REL and \\?\RED conventions to + deal with paths inexpressible in the standard convention, plus + conventions to deal with excessive \s in \\?\ + paths.

In the following, letter stands for a Latin letter (case +does not matter), machine stands for any sequence of +characters that does not include \ or / and is +not ?, volume stands for any sequence of +characters that does not include \ or / , and +element stands for any sequence of characters that does not +include \.

  • Trailing spaces and . in a path element are ignored +when the element is the last one in the path, unless the path +starts with \\?\ or the element consists of only +spaces and .s.

  • The following special “files”, which access devices, exist in +all directories, case-insensitively, and with all possible +endings after a period or colon, except in pathnames that start +with \\?\: "NUL", "CON", +"PRN", "AUX", "COM1", +"COM2", "COM3", "COM4", +"COM5", "COM6", "COM7", +"COM8", "COM9", "LPT1", +"LPT2", "LPT3", "LPT4", +"LPT5", "LPT6", "LPT7", +"LPT8", "LPT9".

  • Except for \\?\ paths, /s are +equivalent to \s. Except for \\?\ +paths and the start of UNC paths, multiple adjacent +/s and \s count as a single +\. In a path that starts \\?\ +paths, elements can be separated by either a single or double +\.

  • A directory can be accessed with or without a trailing +separator. In the case of a non-\\?\ path, the +trailing separator can be any number of /s and +\s; in the case of a \\?\ path, a +trailing separator must be a single \, except that +two \s can follow +\\?\letter:.

  • Except for \\?\ paths, a single . as a +path element means “the current directory,” and a +.. as a path element means “the parent directory.” +Up-directory path elements (i.e., ..) immediately +after a drive are ignored.

  • A pathname that starts +\\machine\volume +(where a / can replace any \) is a UNC +path, and the starting +\\machine\volume +counts as the drive specifier.

  • Normally, a path element cannot contain a character in the +range #\x 0 to #\x 1F nor any of the following +characters:

    < > : " +/ \ | ? *

    Except for \, path elements containing these +characters can be accessed using a \\?\ path +(assuming that the underlying filesystem allows the +characters).

  • In a pathname that starts +\\?\letter:\, the +\\?\letter:\ prefix +counts as the path’s drive, as long as the path does not both +contain non-drive elements and end with two consecutive +\s, and as long as the path contains no sequence +of three or more \s. Two \s can +appear in place of the \ before +letter. A / cannot be used in place of a +\ (but /s can be used in element names, +though the result typically does not name an actual directory +or file).

  • In a pathname that starts +\\?\UNC\machine\volume, +the +\\?\UNC\machine\volume +prefix counts as the path’s drive, as long as the path does +not end with two consecutive \s, and as long as +the path contains no sequence of three or more +\s. Two \s can appear in place of +the \ before UNC, the \s +after UNC, and/or the \s +aftermachine. The letters in the UNC part +can be uppercase or lowercase, and / cannot be used +in place of \s (but / can be used in +element names).

  • Racket-specific: A pathname that starts +\\?\REL\element or +\\?\REL\\element is a relative +path, as long as the path does not end with two consecutive +\s, and as long as the path contains no sequence of +three or more \s. This Racket-specific path form +supports relative paths with elements that are not normally +expressible in Windows paths (e.g., a final element that ends +in a space). The REL part must be exactly the three +uppercase letters, and /s cannot be used in place +of \s. If the path starts +\\?\REL\.. then for as long as the +path continues with repetitions of \.., +each element counts as an up-directory element; a single +\ must be used to separate the up-directory +elements. As soon as a second \ is used to separate +the elements, or as soon as a non-.. element is +encountered, the remaining elements are all literals (never +up-directory elements). When a \\?\REL path +value is converted to a string (or when the path value is +written or displayed), the string does not contain the +starting \\?\REL or the immediately following +\s; converting a path value to a byte string +preserves the \\?\REL prefix.

  • Racket-specific: A pathname that starts +\\?\RED\element or +\\?\RED\\element is a +drive-relative path, as long as the path does not end with two +consecutive \s, and as long as the path contains +no sequence of three or more \s. This +Racket-specific path form supports drive-relative paths (i.e., +absolute given a drive) with elements that are not normally +expressible in Windows paths. The RED part must be +exactly the three uppercase letters, and /s cannot +be used in place of \s. Unlike +\\?\REL paths, a .. element is always +a literal path element. When a \\?\RED path +value is converted to a string (or when the path value is +written or displayed), the string does not contain the +starting \\?\RED and it contains a single +starting \; converting a path value to a byte +string preserves the \\?\RED prefix.

Three additional Racket-specific rules provide meanings to character +sequences that are otherwise ill-formed as Windows paths:

  • Racket-specific: In a pathname of the form +\\?\any\\ where +any is any non-empty sequence of characters other +than letter: or +\letter:, the entire path +counts as the path’s (non-existent) drive.

  • Racket-specific: In a pathname of the form +\\?\any\\\elements, +where any is any non-empty sequence of characters +and elements is any sequence that does not start +with a \, does not end with two \s, +and does not contain a sequence of three \s, then +\\?\any\\ counts as the +path’s (non-existent) drive.

  • Racket-specific: In a pathname that starts \\?\ and +does not match any of the patterns from the preceding bullets, +\\?\ counts as the path’s (non-existent) +drive.

Outside of Racket, except for \\?\ paths, pathnames are + typically limited to 259 characters when used as a file path and 247 characters when + used as a directory path. Racket internally converts + pathnames longer than 247 characters to \\?\ form to avoid the + limits; in that case, the path is first simplified syntactically (in the + sense of simplify-path). The operating system cannot access files through + \\?\ paths that are longer than 32,000 characters or + so.

Where the above descriptions says “character,” substitute “byte” +for interpreting byte strings as paths. The encoding of Windows paths +into bytes preserves ASCII characters, and all special characters +mentioned above are ASCII, so all of the rules are the same.

Beware that the \ path separator is an escape character +in Racket strings. Thus, the path \\?\REL\..\\.. as +a string must be written "\\\\?\\REL\\..\\\\..".

A path that ends with a directory separator syntactically refers to a +directory. In addition, a path syntactically refers to a directory if +its last element is a same-directory or up-directory indicator (not +quoted by a \\?\ form), or if it refers to a root.

Even on variants of Windows that support symbolic links, up-directory +.. indicators in a path are resolved syntactically, not +sensitive to links. For example, if a path ends with d\..\f +and d refers to a symbolic link that references a directory +with a different parent than d, the path nevertheless refers +to f in the same directory as d. A relative-path +link is parsed as if prefixed with \\?\REL paths, except +that .. and . elements are allowed throughout the +path, and any number of redundant \ separators are allowed.

Windows paths are cleansed as follows: In paths that start +\\?\, redundant \s are removed, an extra +\ is added in a \\?\REL if an extra one is +not already present to separate up-directory indicators from literal +path elements, and an extra \ is similarly added after +\\?\RED if an extra one is not already present. +For other paths, multiple /s and \s are +converted to single /s or \ (except at the beginning of a shared +folder name), and a \ is inserted after the colon in a drive +specification if it is missing.

For (bytes->path-element bstr), /s, colons, +trailing dots, trailing whitespace, and special device names (e.g., +“aux”) in bstr are encoded as a literal part of the path +element by using a \\?\REL prefix. The bstr +argument must not contain a \, otherwise the +exn:fail:contract exception is raised.

For (path-element->bytes path) or +(path-element->string path), if the byte-string form of +path starts with a \\?\REL, the prefix is not +included in the result.

For (build-path base-path sub-path ...), trailing spaces +and periods are removed from the last element of base-path +and all but the last sub-path (unless the element consists of +only spaces and periods), except for those that start with +\\?\. If base-path starts \\?\, +then after each non-\\?\REL\ and +non-\\?\RED\ sub-path is added, all +/s in the addition are converted to \s, +multiple consecutive \s are converted to a single +\, added . elements are removed, and added +.. elements are removed along with the preceding element; +these conversions are not performed on the original base-path +part of the result or on any \\?\REL\ or +\\?\RED\ or sub-path. If a +\\?\REL\ or \\?\RED\ +sub-path is added to a non-\\?\ +base-path, the base-path (with any additions up +to the \\?\REL\ or \\?\RED\ +sub-path) is simplified and converted to a +\\?\ path. In other cases, a \ may be +added or removed before combining paths to avoid changing the root +meaning of the path (e.g., combining //x and y +produces /x/y, because //x/y would be a UNC path +instead of a drive-relative path).

For (simplify-path path use-filesystem?), path is +expanded, and if path does not start with +\\?\, trailing spaces and periods are removed, a +/ is inserted after the colon in a drive specification if it +is missing, and a \ is inserted after \\?\ +as a root if there are elements and no extra \ +already. Otherwise, if no indicators or redundant separators are in +path, then path is returned.

For (split-path path) producing base, +name, and must-be-dir?, splitting a path that does +not start with \\?\ can produce parts that start with +\\?\. For example, splitting C:/x /aux/ twice +produces \\?\REL\\x  and \\?\REL\\aux; +the \\?\ is needed in these cases to preserve a +trailing space after x and to avoid referring to the AUX +device instead of an "aux" file.

15.1.4.1 Windows Path Representation

A path on Windows is natively a sequence of UTF-16 code units, where +the sequence can include unpaired surrogates. This sequence is encoded +as a byte string through an extension of UTF-8, where unpaired +surrogates in the UTF-16 code-unit sequence are converted as if they +were non-surrogate values. The extended encodings are implemented on +Windows as the "platform-UTF-16" and +"platform-UTF-8" encodings for bytes-open-converter.

Racket’s internal representation of a Windows path is a byte string, +so that path->bytes and bytes->path are always +inverses. When converting a path to a native UTF-16 code-unit +sequence, #\tab is used in place of platform-UTF-8 decoding +errors (on the grounds that tab is normally disallowed as a character +in a Windows path, unlike #\uFFFD).

A Windows path is converted to a string by treating the platform-UTF-8 +encoding as a UTF-8 encoding with #\uFFFD in place of +decoding errors. Similarly, a string is converted to a path by UTF-8 +encoding (in which case no errors are possible).

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/doc-site.css b/clones/download.racket-lang.org/releases/8.6/doc/doc-site.css new file mode 100644 index 00000000..e69de29b diff --git a/clones/download.racket-lang.org/releases/8.6/doc/doc-site.js b/clones/download.racket-lang.org/releases/8.6/doc/doc-site.js new file mode 100644 index 00000000..e69de29b diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/An_Extended_Example.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/An_Extended_Example.html new file mode 100644 index 00000000..a65bfa6e --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/An_Extended_Example.html @@ -0,0 +1,22 @@ + +9.10 An Extended Example

9.10 An Extended Example

Here’s an extended example from Friedl’s Mastering Regular +Expressions, page 189, that covers many of the features described in +this chapter. The problem is to fashion a regexp that will match any +and only IP addresses or dotted quads: four numbers separated +by three dots, with each number between 0 and 255.

First, we define a subregexp n0-255 that matches 0 through +255:

> (define n0-255
    (string-append
     "(?:"
     "\\d|"        ;  0 through 9
     "\\d\\d|"     ;  00 through 99
     "[01]\\d\\d|" ; 000 through 199
     "2[0-4]\\d|"  ; 200 through 249
     "25[0-5]"     ; 250 through 255
     ")"))

Note that n0-255 lists prefixes as preferred +alternates, which is something we cautioned against in +Alternation. However, since we intend to anchor +this subregexp explicitly to force an overall match, the order of the +alternates does not matter.

The first two alternates simply get all single- and +double-digit numbers. Since 0-padding is allowed, we +need to match both 1 and 01. We need to be careful +when getting 3-digit numbers, since numbers above 255 +must be excluded. So we fashion alternates to get 000 +through 199, then 200 through 249, and finally 250 +through 255.

An IP-address is a string that consists of four n0-255s with +three dots separating them.

> (define ip-re1
    (string-append
     "^"        ; nothing before
     n0-255     ; the first n0-255,
     "(?:"      ; then the subpattern of
     "\\."      ; a dot followed by
     n0-255     ; an n0-255,
     ")"        ; which is
     "{3}"      ; repeated exactly 3 times
     "$"))
; with nothing following

Let’s try it out:

> (regexp-match (pregexp ip-re1) "1.2.3.4")

'("1.2.3.4")

> (regexp-match (pregexp ip-re1) "55.155.255.265")

#f

which is fine, except that we also have

> (regexp-match (pregexp ip-re1) "0.00.000.00")

'("0.00.000.00")

All-zero sequences are not valid IP addresses! Lookahead to the +rescue. Before starting to match ip-re1, we look ahead to +ensure we don’t have all zeros. We could use positive lookahead to +ensure there is a digit other than zero.

> (define ip-re
    (pregexp
     (string-append
       "(?=.*[1-9])" ; ensure there's a non-0 digit
       ip-re1)))

Or we could use negative lookahead to ensure that what’s ahead isn’t +composed of only zeros and dots.

> (define ip-re
    (pregexp
     (string-append
       "(?![0.]*$)" ; not just zeros and dots
                    ; (note: . is not metachar inside [...])
       ip-re1)))

The regexp ip-re will match all and only valid IP addresses.

> (regexp-match ip-re "1.2.3.4")

'("1.2.3.4")

> (regexp-match ip-re "0.0.0.0")

#f

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Backtracking.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Backtracking.html new file mode 100644 index 00000000..0c222430 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Backtracking.html @@ -0,0 +1,28 @@ + +9.8 Backtracking

9.8 Backtracking

We’ve already seen that greedy quantifiers match the maximal number of +times, but the overriding priority is that the overall match succeed. +Consider

> (regexp-match #rx"a*a" "aaaa")

'("aaaa")

The regexp consists of two subregexps: a* followed by +a. The subregexp a* cannot be allowed to match +all four a’s in the text string aaaa, even though +* is a greedy quantifier. It may match only the first +three, leaving the last one for the second subregexp. This ensures +that the full regexp matches successfully.

The regexp matcher accomplishes this via a process called +backtracking. The matcher tentatively allows the greedy +quantifier to match all four a’s, but then when it becomes +clear that the overall match is in jeopardy, it backtracks to a +less greedy match of three a’s. If even this fails, as in +the call

> (regexp-match #rx"a*aa" "aaaa")

'("aaaa")

the matcher backtracks even further. Overall failure is conceded +only when all possible backtracking has been tried with no success.

Backtracking is not restricted to greedy quantifiers. +Nongreedy quantifiers match as few instances as +possible, and progressively backtrack to more and more +instances in order to attain an overall match. There +is backtracking in alternation too, as the more +rightward alternates are tried when locally successful +leftward ones fail to yield an overall match.

Sometimes it is efficient to disable backtracking. For example, we +may wish to commit to a choice, or we know that trying alternatives is +fruitless. A nonbacktracking regexp is enclosed in +(?>...).

> (regexp-match #rx"(?>a+)." "aaaa")

#f

In this call, the subregexp ?>a+ greedily matches all four +a’s, and is denied the opportunity to backtrack. So, the +overall match is denied. The effect of the regexp is therefore to +match one or more a’s followed by something that is +definitely non-a.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Building_New_Contracts.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Building_New_Contracts.html new file mode 100644 index 00000000..1203f7e1 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Building_New_Contracts.html @@ -0,0 +1,185 @@ + +7.8 Building New Contracts

7.8 Building New Contracts

Contracts are represented internally as functions that +accept information about the contract (who is to blame, +source locations, etc.) and produce projections (in the +spirit of Dana Scott) that enforce the contract.

In a general sense, a +projection is a function that accepts an arbitrary value, +and returns a value that satisfies the corresponding +contract. For example, a projection that accepts only +integers corresponds to the contract (flat-contract integer?), and can be written like this:

(define int-proj
  (λ (x)
    (if (integer? x)
        x
        (signal-contract-violation))))

As a second example, a projection that accepts unary functions +on integers looks like this:

(define int->int-proj
  (λ (f)
    (if (and (procedure? f)
             (procedure-arity-includes? f 1))
        (λ (x) (int-proj (f (int-proj x))))
        (signal-contract-violation))))

Although these projections have the right error behavior, +they are not quite ready for use as contracts, because they +do not accommodate blame and do not provide good error +messages. In order to accommodate these, contracts do not +just use simple projections, but use functions that accept a +blame object encapsulating +the names of two parties that are the candidates for blame, +as well as a record of the source location where the +contract was established and the name of the contract. They +can then, in turn, pass that information +to raise-blame-error to signal a good error +message.

Here is the first of those two projections, rewritten for +use in the contract system: +
(define (int-proj blame)
  (λ (x)
    (if (integer? x)
        x
        (raise-blame-error
         blame
         x
         '(expected: "<integer>" given: "~e")
         x))))
The new argument specifies who is to be blamed for +positive and negative contract violations.

Contracts, in this system, are always +established between two parties. One party, called the server, provides some +value according to the contract, and the other, the client, consumes the +value, also according to the contract. The server is called +the positive position and the client the negative position. So, +in the case of just the integer contract, the only thing +that can go wrong is that the value provided is not an +integer. Thus, only the positive party (the server) can ever accrue +blame. The raise-blame-error function always blames +the positive party.

Compare that to the projection for our function contract:

(define (int->int-proj blame)
  (define dom (int-proj (blame-swap blame)))
  (define rng (int-proj blame))
  (λ (f)
    (if (and (procedure? f)
             (procedure-arity-includes? f 1))
        (λ (x) (rng (f (dom x))))
        (raise-blame-error
         blame
         f
         '(expected "a procedure of one argument" given: "~e")
         f))))

In this case, the only explicit blame covers the situation +where either a non-procedure is supplied to the contract or +the procedure does not accept one argument. As with +the integer projection, the blame here also lies with the +producer of the value, which is +why raise-blame-error is passed blame unchanged.

The checking for the domain and range are delegated to +the int-proj function, which is supplied its +arguments in the first two lines of +the int->int-proj function. The trick here is that, +even though the int->int-proj function always +blames what it sees as positive, we can swap the blame parties by +calling blame-swap on the given +blame object, replacing +the positive party with the negative party and vice versa.

This technique is not merely a cheap trick to get the example to work, +however. The reversal of the positive and the negative is a +natural consequence of the way functions behave. That is, +imagine the flow of values in a program between two +modules. First, one module (the server) defines a function, and then that +module is required by another (the client). So far, the function itself +has to go from the original, providing module to the +requiring module. Now, imagine that the requiring module +invokes the function, supplying it an argument. At this +point, the flow of values reverses. The argument is +traveling back from the requiring module to the providing +module! The client is “serving” the argument to the server, +and the server is receiving that value as a client. +And finally, when the function produces a result, +that result flows back in the original +direction from server to client. +Accordingly, the contract on the domain reverses +the positive and the negative blame parties, just like the flow +of values reverses.

We can use this insight to generalize the function contracts +and build a function that accepts any two contracts and +returns a contract for functions between them.

This projection also goes further and uses +blame-add-context to improve the error messages +when a contract violation is detected.

(define (make-simple-function-contract dom-proj range-proj)
  (λ (blame)
    (define dom (dom-proj (blame-add-context blame
                                             "the argument of"
                                             #:swap? #t)))
    (define rng (range-proj (blame-add-context blame
                                               "the range of")))
    (λ (f)
      (if (and (procedure? f)
               (procedure-arity-includes? f 1))
          (λ (x) (rng (f (dom x))))
          (raise-blame-error
           blame
           f
           '(expected "a procedure of one argument" given: "~e")
           f)))))

While these projections are supported by the contract library +and can be used to build new contracts, the contract library +also supports a different API for projections that can be more +efficient. Specifically, a +late neg projection accepts +a blame object without the negative blame information and then +returns a function that accepts both the value to be contracted and +the name of the negative party, in that order. +The returned function then in turn +returns the value with the contract. Rewriting int->int-proj +to use this API looks like this: +
(define (int->int-proj blame)
  (define dom-blame (blame-add-context blame
                                       "the argument of"
                                       #:swap? #t))
  (define rng-blame (blame-add-context blame "the range of"))
  (define (check-int v to-blame neg-party)
    (unless (integer? v)
      (raise-blame-error
       to-blame #:missing-party neg-party
       v
       '(expected "an integer" given: "~e")
       v)))
  (λ (f neg-party)
    (if (and (procedure? f)
             (procedure-arity-includes? f 1))
        (λ (x)
          (check-int x dom-blame neg-party)
          (define ans (f x))
          (check-int ans rng-blame neg-party)
          ans)
        (raise-blame-error
         blame #:missing-party neg-party
         f
         '(expected "a procedure of one argument" given: "~e")
         f))))
The advantage of this style of contract is that the blame +argument can be supplied on the server side of the +contract boundary and the result can be used for each different +client. With the simpler situation, a new blame object has to be +created for each client.

One final problem remains before this contract can be used with the +rest of the contract system. In the function above, +the contract is implemented by creating a wrapper function for +f, but this wrapper function does not cooperate with +equal?, nor does it let the runtime system know that there +is a relationship between the result function and f, the input +function.

To remedy these two problems, we should use +chaperones instead +of just using λ to create the wrapper function. Here is the +int->int-proj function rewritten to use a +chaperone:

(define (int->int-proj blame)
  (define dom-blame (blame-add-context blame
                                       "the argument of"
                                       #:swap? #t))
  (define rng-blame (blame-add-context blame "the range of"))
  (define (check-int v to-blame neg-party)
    (unless (integer? v)
      (raise-blame-error
       to-blame #:missing-party neg-party
       v
       '(expected "an integer" given: "~e")
       v)))
  (λ (f neg-party)
    (if (and (procedure? f)
             (procedure-arity-includes? f 1))
        (chaperone-procedure
         f
         (λ (x)
           (check-int x dom-blame neg-party)
           (values (λ (ans)
                     (check-int ans rng-blame neg-party)
                     ans)
                   x)))
        (raise-blame-error
         blame #:missing-party neg-party
         f
         '(expected "a procedure of one argument" given: "~e")
         f))))

Projections like the ones described above, but suited to +other, new kinds of value you might make, can be used with +the contract library primitives. Specifically, we can use +make-chaperone-contract to build it: +
(define int->int-contract
  (make-contract
   #:name 'int->int
   #:late-neg-projection int->int-proj))
and then combine it with a value and get some contract +checking. +
(define/contract (f x)
  int->int-contract
  "not an int")

 

> (f #f)

f: contract violation;

 expected an integer

  given: #f

  in: the argument of

      int->int

  contract from: (function f)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:5:0

> (f 1)

f: broke its own contract;

 promised an integer

  produced: "not an int"

  in: the range of

      int->int

  contract from: (function f)

  blaming: (function f)

   (assuming the contract is correct)

  at: eval:5:0

7.8.1 Contract Struct Properties

The make-chaperone-contract function is okay for one-off contracts, +but often you want to make many different contracts that differ only +in some pieces. The best way to do that is to use a struct +with either prop:contract, prop:chaperone-contract, or +prop:flat-contract.

For example, lets say we wanted to make a simple form of the -> +contract that accepts one contract for the range and one for the domain. +We should define a struct with two fields and use +build-chaperone-contract-property to construct the chaperone contract +property we need. +
(struct simple-arrow (dom rng)
  #:property prop:chaperone-contract
  (build-chaperone-contract-property
   #:name
   (λ (arr) (simple-arrow-name arr))
   #:late-neg-projection
   (λ (arr) (simple-arrow-late-neg-proj arr))))

To do the automatic coercion of values like integer? and #f +into contracts, we need to call coerce-chaperone-contract +(note that this rejects impersonator contracts and does not insist +on flat contracts; to do either of those things, call coerce-contract +or coerce-flat-contract instead). +
(define (simple-arrow-contract dom rng)
  (simple-arrow (coerce-contract 'simple-arrow-contract dom)
                (coerce-contract 'simple-arrow-contract rng)))

To define simple-arrow-name is straight-forward; it needs to return +an s-expression representing the contract: +
(define (simple-arrow-name arr)
  `(-> ,(contract-name (simple-arrow-dom arr))
       ,(contract-name (simple-arrow-rng arr))))
And we can define the projection using a generalization of the +projection we defined earlier, this time using +chaperones: +
(define (simple-arrow-late-neg-proj arr)
  (define dom-ctc (get/build-late-neg-projection (simple-arrow-dom arr)))
  (define rng-ctc (get/build-late-neg-projection (simple-arrow-rng arr)))
  (λ (blame)
    (define dom+blame (dom-ctc (blame-add-context blame
                                                  "the argument of"
                                                  #:swap? #t)))
    (define rng+blame (rng-ctc (blame-add-context blame "the range of")))
    (λ (f neg-party)
      (if (and (procedure? f)
               (procedure-arity-includes? f 1))
          (chaperone-procedure
           f
           (λ (arg)
             (values
              (λ (result) (rng+blame result neg-party))
              (dom+blame arg neg-party))))
          (raise-blame-error
           blame #:missing-party neg-party
           f
           '(expected "a procedure of one argument" given: "~e")
           f)))))

(define/contract (f x)
  (simple-arrow-contract integer? boolean?)
  "not a boolean")

 

> (f #f)

f: contract violation

  expected: integer?

  given: #f

  in: the argument of

      (-> integer? boolean?)

  contract from: (function f)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:12:0

> (f 1)

f: broke its own contract

  promised: boolean?

  produced: "not a boolean"

  in: the range of

      (-> integer? boolean?)

  contract from: (function f)

  blaming: (function f)

   (assuming the contract is correct)

  at: eval:12:0

7.8.2 With all the Bells and Whistles

There are a number of optional pieces to a contract that +simple-arrow-contract did not add. In this section, +we walk through all of them to show examples of how they can +be implemented.

The first is a first-order check. This is used by or/c +in order to determine which of the higher-order argument contracts +to use when it sees a value. Here’s the function for +our simple arrow contract. +
(define (simple-arrow-first-order ctc)
  (λ (v) (and (procedure? v)
              (procedure-arity-includes? v 1))))
It accepts a value and returns #f if the value is guaranteed not +to satisfy the contract, and #t if, as far as we can tell, +the value satisfies the contract, just be inspecting first-order +properties of the value.

The next is random generation. Random generation in the contract +library consists of two pieces: the ability to randomly generate +values satisfying the contract and the ability to exercise values +that match the contract that are given, in the hopes of finding bugs +in them (and also to try to get them to produce interesting values to +be used elsewhere during generation).

To exercise contracts, we need to implement a function that +is given a arrow-contract struct and some fuel. It should return +two values: a function that accepts values of the contract +and exercises them, plus a list of values that the exercising +process will always produce. In the case of our simple +contract, we know that we can always produce values of the range, +as long as we can generate values of the domain (since we can just +call the function). So, here’s a function that matches the +exercise argument of build-chaperone-contract-property’s +contract: +
(define (simple-arrow-contract-exercise arr)
  (define env (contract-random-generate-get-current-environment))
  (λ (fuel)
    (define dom-generate
      (contract-random-generate/choose (simple-arrow-dom arr) fuel))
    (cond
      [dom-generate
       (values
        (λ (f) (contract-random-generate-stash
                env
                (simple-arrow-rng arr)
                (f (dom-generate))))
        (list (simple-arrow-rng arr)))]
      [else
       (values void '())])))
If the domain contract can be generated, then we know we can do some good via exercising. +In that case, we return a procedure that calls f (the function matching +the contract) with something that we generated from the domain, and we stash the result +value in the environment too. We also return (simple-arrow-rng arr) +to indicate that exercising will always produce something of that contract.

If we cannot, then we simply return a function that +does no exercising (void) and the empty list (indicating that we won’t generate +any values).

Then, to generate values matching the contract, we define a function +that when given the contract and some fuel, makes up a random function. +To help make it a more effective testing function, we can exercise +any arguments it receives, and also stash them into the generation +environment, but only if we can generate values of the range contract. +
(define (simple-arrow-contract-generate arr)
  (λ (fuel)
    (define env (contract-random-generate-get-current-environment))
    (define rng-generate
      (contract-random-generate/choose (simple-arrow-rng arr) fuel))
    (cond
      [rng-generate
       (λ ()
         (λ (arg)
           (contract-random-generate-stash env (simple-arrow-dom arr) arg)
           (rng-generate)))]
      [else
       #f])))

When the random generation pulls something out of the environment, +it needs to be able to tell if a value that has been passed to +contract-random-generate-stash is a candidate for +the contract it is trying to generate. Of course, it the contract +passed to contract-random-generate-stash is an exact +match, then it can use it. But it can also use the value if the +contract is stronger (in the sense that it accepts fewer values).

To provide that functionality, we implement this function: +
(define (simple-arrow-first-stronger? this that)
  (and (simple-arrow? that)
       (contract-stronger? (simple-arrow-dom that)
                           (simple-arrow-dom this))
       (contract-stronger? (simple-arrow-rng this)
                           (simple-arrow-rng that))))
This function accepts this and that, two contracts. It is +guaranteed that this will be one of our simple arrow contracts, +since we’re supplying this function together with the simple arrow implementation. +But the that argument might be any contract. This function +checks to see if that is also a simple arrow contract and, if so +compares the domain and range. Of course, there are other contracts that we +could also check for (e.g., contracts built using -> or ->*), +but we do not need to. The stronger function is allowed to return #f +if it doesn’t know the answer but if it returns #t, then the contract +really must be stronger.

Now that we have all of the pieces implemented, we need to pass them +to build-chaperone-contract-property so the contract system +starts using them: +
(struct simple-arrow (dom rng)
  #:property prop:custom-write contract-custom-write-property-proc
  #:property prop:chaperone-contract
  (build-chaperone-contract-property
   #:name
   (λ (arr) (simple-arrow-name arr))
   #:late-neg-projection
   (λ (arr) (simple-arrow-late-neg-proj arr))
   #:first-order simple-arrow-first-order
   #:stronger simple-arrow-first-stronger?
   #:generate simple-arrow-contract-generate
   #:exercise simple-arrow-contract-exercise))
(define (simple-arrow-contract dom rng)
  (simple-arrow (coerce-contract 'simple-arrow-contract dom)
                (coerce-contract 'simple-arrow-contract rng)))
We also add a prop:custom-write property so +that the contracts print properly, e.g.: +
> (simple-arrow-contract integer? integer?)

(-> integer? integer?)

(We use prop:custom-write because the contract library +can not depend on
but yet still wants +to provide some help to make it easy to use the right printer.)

Now that that’s done, we can use the new functionality. Here’s a random function, +generated by the contract library, using our simple-arrow-contract-generate +function: +
(define a-random-function
  (contract-random-generate
   (simple-arrow-contract integer? integer?)))

 

> (a-random-function 0)

0

> (a-random-function 1)

1

Here’s how the contract system can now automatically find bugs in functions +that consume simple arrow contracts: +
(define/contract (misbehaved-f f)
  (-> (simple-arrow-contract integer? boolean?) any)
  (f "not an integer"))

 

> (contract-exercise misbehaved-f)

misbehaved-f: broke its own contract

  promised: integer?

  produced: "not an integer"

  in: the argument of

      the 1st argument of

      (-> (-> integer? boolean?) any)

  contract from: (function misbehaved-f)

  blaming: (function misbehaved-f)

   (assuming the contract is correct)

  at: eval:25:0

And if we hadn’t implemented simple-arrow-first-order, then +or/c would not be able to tell which branch of the or/c +to use in this program: +
(define/contract (maybe-accepts-a-function f)
  (or/c (simple-arrow-contract real? real?)
        (-> real? real? real?)
        real?)
  (if (procedure? f)
      (if (procedure-arity-includes f 1)
          (f 1132)
          (f 11 2))
      f))

 

> (maybe-accepts-a-function sqrt)

maybe-accepts-a-function: contract violation

  expected: real?

  given: #<procedure:sqrt>

  in: the argument of

      a part of the or/c of

      (or/c

       (-> real? real?)

       (-> real? real? real?)

       real?)

  contract from:

      (function maybe-accepts-a-function)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:27:0

> (maybe-accepts-a-function 123)

123

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Contracts_for_Units.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Contracts_for_Units.html new file mode 100644 index 00000000..40c39829 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Contracts_for_Units.html @@ -0,0 +1,16 @@ + +14.6 Contracts for Units

14.6 Contracts for Units

There are a couple of ways of protecting units with contracts. One way +is useful when writing new signatures, and the other handles the case +when a unit must conform to an already existing signature.

14.6.1 Adding Contracts to Signatures

When contracts are added to a signature, then all units which implement +that signature are protected by those contracts. The following version +of the toy-factory^ signature adds the contracts previously +written in comments:

"contracted-toy-factory-sig.rkt"

#lang racket
 
(define-signature contracted-toy-factory^
  ((contracted
    [build-toys (-> integer? (listof toy?))]
    [repaint    (-> toy? symbol? toy?)]
    [toy?       (-> any/c boolean?)]
    [toy-color  (-> toy? symbol?)])))
 
(provide contracted-toy-factory^)

Now we take the previous implementation of simple-factory@ and +implement this version of toy-factory^ instead:

"contracted-simple-factory-unit.rkt"

#lang racket
 
(require "contracted-toy-factory-sig.rkt")
 
(define-unit contracted-simple-factory@
  (import)
  (export contracted-toy-factory^)
 
  (printf "Factory started.\n")
 
  (struct toy (color) #:transparent)
 
  (define (build-toys n)
    (for/list ([i (in-range n)])
      (toy 'blue)))
 
  (define (repaint t col)
    (toy col)))
 
(provide contracted-simple-factory@)

As before, we can invoke our new unit and bind the exports so +that we can use them. This time, however, misusing the exports +causes the appropriate contract errors.

> (require "contracted-simple-factory-unit.rkt")
> (define-values/invoke-unit/infer contracted-simple-factory@)

Factory started.

> (build-toys 3)

(list (toy 'blue) (toy 'blue) (toy 'blue))

> (build-toys #f)

build-toys: contract violation

  expected: integer?

  given: #f

  in: the 1st argument of

      (-> integer? (listof toy?))

  contract from:

      (unit contracted-simple-factory@)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:34:0

> (repaint 3 'blue)

repaint: contract violation

  expected: toy?

  given: 3

  in: the 1st argument of

      (-> toy? symbol? toy?)

  contract from:

      (unit contracted-simple-factory@)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:34:0

14.6.2 Adding Contracts to Units

However, sometimes we may have a unit that must conform to an +already existing signature that is not contracted. In this case, +we can create a unit contract with unit/c or use +the define-unit/contract form, which defines a unit which +has been wrapped with a unit contract.

For example, here’s a version of toy-factory@ which still +implements the regular toy-factory^, but whose exports +have been protected with an appropriate unit contract.

"wrapped-simple-factory-unit.rkt"

#lang racket
 
(require "toy-factory-sig.rkt")
 
(define-unit/contract wrapped-simple-factory@
  (import)
  (export (toy-factory^
           [build-toys (-> integer? (listof toy?))]
           [repaint    (-> toy? symbol? toy?)]
           [toy?       (-> any/c boolean?)]
           [toy-color  (-> toy? symbol?)]))
 
  (printf "Factory started.\n")
 
  (struct toy (color) #:transparent)
 
  (define (build-toys n)
    (for/list ([i (in-range n)])
      (toy 'blue)))
 
  (define (repaint t col)
    (toy col)))
 
(provide wrapped-simple-factory@)
> (require "wrapped-simple-factory-unit.rkt")
> (define-values/invoke-unit/infer wrapped-simple-factory@)

Factory started.

> (build-toys 3)

(list (toy 'blue) (toy 'blue) (toy 'blue))

> (build-toys #f)

wrapped-simple-factory@: contract violation

  expected: integer?

  given: #f

  in: the 1st argument of

      (unit/c

       (import)

       (export (toy-factory^

                (build-toys

                 (-> integer? (listof toy?)))

                (repaint (-> toy? symbol? toy?))

                (toy? (-> any/c boolean?))

                (toy-color (-> toy? symbol?))))

       (init-depend))

  contract from:

      (unit wrapped-simple-factory@)

  blaming: top-level

   (assuming the contract is correct)

  at: <collects>/racket/unit.rkt

> (repaint 3 'blue)

wrapped-simple-factory@: contract violation

  expected: toy?

  given: 3

  in: the 1st argument of

      (unit/c

       (import)

       (export (toy-factory^

                (build-toys

                 (-> integer? (listof toy?)))

                (repaint (-> toy? symbol? toy?))

                (toy? (-> any/c boolean?))

                (toy-color (-> toy? symbol?))))

       (init-depend))

  contract from:

      (unit wrapped-simple-factory@)

  blaming: top-level

   (assuming the contract is correct)

  at: <collects>/racket/unit.rkt

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Emacs.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Emacs.html new file mode 100644 index 00000000..e814ef72 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Emacs.html @@ -0,0 +1,56 @@ + +24.2 Emacs

24.2 Emacs

Emacs has long been a favorite among Lispers and Schemers, and is +popular among Racketeers as well.

24.2.1 Major Modes
  • Racket mode +provides thorough syntax highlighting and DrRacket-style REPL +and buffer execution support for Emacs.

    Racket mode can be installed via MELPA +or manually from the Github repository.

  • Quack is an +extension of Emacs’s scheme-mode that provides enhanced +support for Racket, including highlighting and indentation of +Racket-specific forms, and documentation integration.

    Quack is included in the Debian and Ubuntu repositories as part +of the emacs-goodies-el package. A Gentoo port is also +available (under the name app-emacs/quack).

  • Geiser provides a +programming environment where the editor is tightly integrated +with the Racket REPL. Programmers accustomed to environments +such as Slime or Squeak should feel at home using +Geiser. Geiser requires GNU Emacs 23.2 or better.

    Quack and Geiser can be used together, and complement each +other nicely. More information is available in the +Geiser manual.

    Debian and Ubuntu packages for Geiser are available under the +name geiser.

  • Emacs ships with a major mode for Scheme, scheme-mode, +that while not as featureful as the above options, works +reasonably well for editing Racket code. However, this mode +does not provide support for Racket-specific forms.

  • No Racket program is complete without documentation. Scribble +support for Emacs is available with Neil Van Dyke’s +Scribble +Mode.

    In addition, texinfo-mode (included with GNU Emacs) and + plain text modes work well when editing Scribble + documents. The Racket major modes above are not really suited + to this task, given how different Scribble’s syntax is from + Racket’s.

24.2.2 Minor Modes
  • Paredit +is a minor mode for pseudo-structurally editing programs in +Lisp-like languages. In addition to providing high-level +S-expression editing commands, it prevents you from +accidentally unbalancing parentheses.

    Debian and Ubuntu packages for Paredit are available under the +name paredit-el.

  • Smartparens +is a minor mode for editing s-expressions, keeping parentheses +balanced, etc. Similar to Paredit.

  • Alex Shinn’s +scheme-complete +provides intelligent, context-sensitive code completion. It +also integrates with Emacs’s eldoc mode to provide live +documentation in the minibuffer.

    While this mode was designed for R5RS, it +can still be useful for Racket development. The tool is +unaware of large portions of the Racket standard library, and +there may be some discrepancies in the live documentation in +cases where Scheme and Racket have diverged.

  • The +RainbowDelimiters +mode colors parentheses and other delimiters according to their +nesting depth. Coloring by nesting depth makes it easier to +know, at a glance, which parentheses match.

  • ParenFace +lets you choose in which face (font, color, etc.) parentheses +should be displayed. Choosing an alternate face makes it +possible to make “tone down” parentheses.

24.2.3 Packages specific to Evil Mode
  • on-parens +is a wrapper for smartparens motions to work better with +evil-mode’s normal state.

  • evil-surround +provides commands to add, remove, and change parentheses and +other delimiters.

  • evil-textobj-anyblock +adds a text-object that matches the closest of any +parenthesis or other delimiter pair.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Invoking_Units.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Invoking_Units.html new file mode 100644 index 00000000..4f9564fa --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Invoking_Units.html @@ -0,0 +1,18 @@ + +14.2 Invoking Units

14.2 Invoking Units

The simple-factory@ unit has no imports, so it can be +invoked directly using invoke-unit:

> (require "simple-factory-unit.rkt")
> (invoke-unit simple-factory@)

Factory started.

The invoke-unit form does not make the body definitions +available, however, so we cannot build any toys with this factory. The +define-values/invoke-unit form binds the identifiers of a +signature to the values supplied by a unit (to be invoked) that +implements the signature:

> (define-values/invoke-unit/infer simple-factory@)

Factory started.

> (build-toys 3)

(list (toy 'blue) (toy 'blue) (toy 'blue))

Since simple-factory@ exports the toy-factory^ +signature, each identifier in toy-factory^ is defined by the +define-values/invoke-unit/infer form. The +/infer part of the form name indicates that the +identifiers bound by the declaration are inferred from +simple-factory@.

Now that the identifiers in toy-factory^ are defined, we can +also invoke toy-store@, which imports toy-factory^ +to produce toy-store^:

> (require "toy-store-unit.rkt")
> (define-values/invoke-unit/infer toy-store@)
> (get-inventory)

'()

> (stock! 2)
> (get-inventory)

(list (toy 'green) (toy 'green))

Again, the /infer part +define-values/invoke-unit/infer determines that +toy-store@ imports toy-factory^, and so it supplies +the top-level bindings that match the names in toy-factory^ +as imports to toy-store@.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Linking_Units.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Linking_Units.html new file mode 100644 index 00000000..43c4f591 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Linking_Units.html @@ -0,0 +1,17 @@ + +14.3 Linking Units

14.3 Linking Units

We can make our toy economy more efficient by having toy factories +that cooperate with stores, creating toys that do not have to be +repainted. Instead, the toys are always created using the store’s +color, which the factory gets by importing toy-store^:

"store-specific-factory-unit.rkt"

#lang racket
 
(require "toy-store-sig.rkt"
         "toy-factory-sig.rkt")
 
(define-unit store-specific-factory@
  (import toy-store^)
  (export toy-factory^)
 
  (struct toy () #:transparent)
 
  (define (toy-color t) (store-color))
 
  (define (build-toys n)
    (for/list ([i (in-range n)])
      (toy)))
 
  (define (repaint t col)
    (error "cannot repaint")))
 
(provide store-specific-factory@)

To invoke store-specific-factory@, we need +toy-store^ bindings to supply to the unit. But to get +toy-store^ bindings by invoking toy-store@, we will +need a toy factory! The unit implementations are mutually dependent, +and we cannot invoke either before the other.

The solution is to link the units together, and then we can +invoke the combined units. The define-compound-unit/infer form +links any number of units to form a combined unit. It can propagate +imports and exports from the linked units, and it can satisfy each +unit’s imports using the exports of other linked units.

> (require "toy-factory-sig.rkt")
> (require "toy-store-sig.rkt")
> (require "store-specific-factory-unit.rkt")
> (define-compound-unit/infer toy-store+factory@
    (import)
    (export toy-factory^ toy-store^)
    (link store-specific-factory@
          toy-store@))

The overall result above is a unit toy-store+factory@ that +exports both toy-factory^ and toy-store^. The +connection between store-specific-factory@ and +toy-store@ is inferred from the signatures that each imports +and exports.

This unit has no imports, so we can always invoke it:

> (define-values/invoke-unit/infer toy-store+factory@)
> (stock! 2)
> (get-inventory)

(list (toy) (toy))

> (map toy-color (get-inventory))

'(green green)

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Lists__Iteration__and_Recursion.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Lists__Iteration__and_Recursion.html new file mode 100644 index 00000000..8fa2afe4 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Lists__Iteration__and_Recursion.html @@ -0,0 +1,96 @@ + +2.3 Lists, Iteration, and Recursion

2.3 Lists, Iteration, and Recursion

Racket is a dialect of the language Lisp, whose name originally stood +for “LISt Processor.” The built-in list datatype remains a prominent +feature of the language.

The list function takes any number of values and returns +a list containing the values:

> (list "red" "green" "blue")

'("red" "green" "blue")

> (list 1 2 3 4 5)

'(1 2 3 4 5)

A list usually prints with ', but the printed +form of a list depends on its content. See +Pairs and Lists for more information.

As you can see, a list result prints in the REPL as a quote +' and then a pair of parentheses wrapped around the printed +form of the list elements. There’s an opportunity for confusion here, +because parentheses are used for both expressions, such as +(list "red" "green" "blue"), and printed results, such as +'("red" "green" "blue"). In addition to the quote, +parentheses for results are printed in blue in the documentation and +in DrRacket, whereas parentheses for expressions are brown.

Many predefined functions operate on lists. Here are a few examples:

> (length (list "hop" "skip" "jump"))        ; count the elements

3

> (list-ref (list "hop" "skip" "jump") 0)    ; extract by position

"hop"

> (list-ref (list "hop" "skip" "jump") 1)

"skip"

> (append (list "hop" "skip") (list "jump")) ; combine lists

'("hop" "skip" "jump")

> (reverse (list "hop" "skip" "jump"))       ; reverse order

'("jump" "skip" "hop")

> (member "fall" (list "hop" "skip" "jump")) ; check for an element

#f

2.3.1 Predefined List Loops

In addition to simple operations like append, Racket includes +functions that iterate over the elements of a list. These iteration +functions play a role similar to for in Java, Racket, and other +languages. The body of a Racket iteration is packaged into a function +to be applied to each element, so the lambda form becomes +particularly handy in combination with iteration functions.

Different list-iteration functions combine iteration results in +different ways. The map function uses the per-element +results to create a new list:

> (map sqrt (list 1 4 9 16))

'(1 2 3 4)

> (map (lambda (i)
         (string-append i "!"))
       (list "peanuts" "popcorn" "crackerjack"))

'("peanuts!" "popcorn!" "crackerjack!")

The andmap and ormap functions combine the results +by anding or oring:

> (andmap string? (list "a" "b" "c"))

#t

> (andmap string? (list "a" "b" 6))

#f

> (ormap number? (list "a" "b" 6))

#t

The map, andmap, and ormap +functions can all handle multiple lists, instead of just a single +list. The lists must all have the same length, and the given function +must accept one argument for each list:

> (map (lambda (s n) (substring s 0 n))
       (list "peanuts" "popcorn" "crackerjack")
       (list 6 3 7))

'("peanut" "pop" "cracker")

The filter function keeps elements for which the body result +is true, and discards elements for which it is #f:

> (filter string? (list "a" "b" 6))

'("a" "b")

> (filter positive? (list 1 -2 6 7 0))

'(1 6 7)

The foldl function generalizes some iteration functions. It +uses the per-element function to both process an element and combine +it with the “current” value, so the per-element function takes an +extra first argument. Also, a starting “current” value must be +provided before the lists:

> (foldl (lambda (elem v)
           (+ v (* elem elem)))
         0
         '(1 2 3))

14

Despite its generality, foldl is not as popular as the other +functions. One reason is that map, ormap, +andmap, and filter cover the most common kinds of +list loops.

Racket provides a general list comprehension form +for/list, which builds a list by iterating through +sequences. List comprehensions and related iteration forms +are described in Iterations and Comprehensions.

2.3.2 List Iteration from Scratch

Although map and other iteration functions are predefined, they +are not primitive in any interesting sense. You can write equivalent +iterations using a handful of list primitives.

Since a Racket list is a linked list, the two core operations on a +non-empty list are

  • first: get the first thing in the list; and

  • rest: get the rest of the list.

Examples:
> (first (list 1 2 3))

1

> (rest (list 1 2 3))

'(2 3)

To create a new node for a linked list—that is, to add to the front +of the list—use the cons function, which is short for +“construct.” To get an empty list to start with, use the +empty constant:

> empty

'()

> (cons "head" empty)

'("head")

> (cons "dead" (cons "head" empty))

'("dead" "head")

To process a list, you need to be able to distinguish empty lists from +non-empty lists, because first and rest work only on +non-empty lists. The empty? function detects empty lists, +and cons? detects non-empty lists:

> (empty? empty)

#t

> (empty? (cons "head" empty))

#f

> (cons? empty)

#f

> (cons? (cons "head" empty))

#t

With these pieces, you can write your own versions of the +length function, map function, and more.

Examples:
(define (my-length lst)
  (cond
   [(empty? lst) 0]
   [else (+ 1 (my-length (rest lst)))]))
> (my-length empty)

0

> (my-length (list "a" "b" "c"))

3

(define (my-map f lst)
  (cond
   [(empty? lst) empty]
   [else (cons (f (first lst))
               (my-map f (rest lst)))]))

 

> (my-map string-upcase (list "ready" "set" "go"))

'("READY" "SET" "GO")

If the derivation of the above definitions is mysterious to you, +consider reading How to Design Programs. If you are merely suspicious of the use +of recursive calls instead of a looping construct, then read on.

2.3.3 Tail Recursion

Both the my-length and my-map functions run in +O(n) space for a list of length n. This is easy to see by +imagining how (my-length (list "a" "b" "c")) must evaluate:

(my-length (list "a" "b" "c"))
= (+ 1 (my-length (list "b" "c")))
= (+ 1 (+ 1 (my-length (list "c"))))
= (+ 1 (+ 1 (+ 1 (my-length (list)))))
= (+ 1 (+ 1 (+ 1 0)))
= (+ 1 (+ 1 1))
= (+ 1 2)
= 3

For a list with n elements, evaluation will stack up n +(+ 1 ...) additions, and then finally add them up when the +list is exhausted.

You can avoid piling up additions by adding along the way. To +accumulate a length this way, we need a function that takes both a +list and the length of the list seen so far; the code below uses a +local function iter that accumulates the length in an +argument len:

(define (my-length lst)
  ; local function iter:
  (define (iter lst len)
    (cond
     [(empty? lst) len]
     [else (iter (rest lst) (+ len 1))]))
  ; body of my-length calls iter:
  (iter lst 0))

Now evaluation looks like this:

(my-length (list "a" "b" "c"))
= (iter (list "a" "b" "c") 0)
= (iter (list "b" "c") 1)
= (iter (list "c") 2)
= (iter (list) 3)
3

The revised my-length runs in constant space, just as the +evaluation steps above suggest. That is, when the result of a +function call, like (iter (list "b" "c") 1), is exactly the +result of some other function call, like (iter (list "c") 2), then the first one doesn’t have to wait around for the second +one, because that takes up space for no good reason.

This evaluation behavior is sometimes called tail-call +optimization, but it’s not merely an “optimization” in Racket; it’s +a guarantee about the way the code will run. More precisely, an +expression in tail position with respect to another +expression does not take extra computation space over the other +expression.

In the case of my-map, O(n) space complexity is +reasonable, since it has to generate a result of size +O(n). Nevertheless, you can reduce the constant factor by +accumulating the result list. The only catch is that the accumulated +list will be backwards, so you’ll have to reverse it at the very end:

Attempting to reduce a constant factor like this is +usually not worthwhile, as discussed below.

(define (my-map f lst)
  (define (iter lst backward-result)
    (cond
     [(empty? lst) (reverse backward-result)]
     [else (iter (rest lst)
                 (cons (f (first lst))
                       backward-result))]))
  (iter lst empty))

It turns out that if you write

(define (my-map f lst)
  (for/list ([i lst])
    (f i)))

then the for/list form in the function is expanded to +essentially the same code as the iter local definition and +use. The difference is merely syntactic convenience.

2.3.4 Recursion versus Iteration

The my-length and my-map examples demonstrate that +iteration is just a special case of recursion. In many languages, it’s +important to try to fit as many computations as possible into +iteration form. Otherwise, performance will be bad, and moderately +large inputs can lead to stack overflow. Similarly, in Racket, it is +sometimes important to make sure that tail recursion is used to avoid +O(n) space consumption when the computation is easily performed +in constant space.

At the same time, recursion does not lead to particularly bad +performance in Racket, and there is no such thing as stack overflow; +you can run out of memory if a computation involves too much context, +but exhausting memory typically requires orders of magnitude deeper +recursion than would trigger a stack overflow in other +languages. These considerations, combined with the fact that +tail-recursive programs automatically run the same as a loop, lead +Racket programmers to embrace recursive forms rather than avoid them.

Suppose, for example, that you want to remove consecutive duplicates +from a list. While such a function can be written as a loop that +remembers the previous element for each iteration, a Racket programmer +would more likely just write the following:

(define (remove-dups l)
  (cond
   [(empty? l) empty]
   [(empty? (rest l)) l]
   [else
    (let ([i (first l)])
      (if (equal? i (first (rest l)))
          (remove-dups (rest l))
          (cons i (remove-dups (rest l)))))]))

 

> (remove-dups (list "a" "b" "b" "b" "c" "c"))

'("a" "b" "c")

In general, this function consumes O(n) space for an input +list of length n, but that’s fine, since it produces an +O(n) result. If the input list happens to be mostly consecutive +duplicates, then the resulting list can be much smaller than +O(n)and remove-dups will also use much less than +O(n) space! The reason is that when the function discards +duplicates, it returns the result of a remove-dups call +directly, so the tail-call “optimization” kicks in:

(remove-dups (list "a" "b" "b" "b" "b" "b"))
= (cons "a" (remove-dups (list "b" "b" "b" "b" "b")))
= (cons "a" (remove-dups (list "b" "b" "b" "b")))
= (cons "a" (remove-dups (list "b" "b" "b")))
= (cons "a" (remove-dups (list "b" "b")))
= (cons "a" (remove-dups (list "b")))
= (cons "a" (list "b"))
= (list "a" "b")
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Looking_Ahead_and_Behind.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Looking_Ahead_and_Behind.html new file mode 100644 index 00000000..2879ae6c --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Looking_Ahead_and_Behind.html @@ -0,0 +1,22 @@ + +9.9 Looking Ahead and Behind

9.9 Looking Ahead and Behind

You can have assertions in your pattern that look ahead or +behind to ensure that a subpattern does or does not occur. +These “look around” assertions are specified by putting the +subpattern checked for in a cluster whose leading characters are: +?= (for positive lookahead), ?! (negative +lookahead), ?<= (positive lookbehind), ?<! +(negative lookbehind). Note that the subpattern in the assertion does +not generate a match in the final result; it merely allows or +disallows the rest of the match.

9.9.1 Lookahead

Positive lookahead with ?= peeks ahead to ensure that +its subpattern could match.

> (regexp-match-positions #rx"grey(?=hound)"
    "i left my grey socks at the greyhound")

'((28 . 32))

The regexp #rx"grey(?=hound)" matches grey, but +only if it is followed by hound. Thus, the first +grey in the text string is not matched.

Negative lookahead with ?! peeks ahead to ensure that its +subpattern could not possibly match.

> (regexp-match-positions #rx"grey(?!hound)"
    "the gray greyhound ate the grey socks")

'((27 . 31))

The regexp #rx"grey(?!hound)" matches grey, but +only if it is not followed by hound. Thus the +grey just before socks is matched.

9.9.2 Lookbehind

Positive lookbehind with ?<= checks that its subpattern +could match immediately to the left of the current position in +the text string.

> (regexp-match-positions #rx"(?<=grey)hound"
    "the hound in the picture is not a greyhound")

'((38 . 43))

The regexp #rx"(?<=grey)hound" matches hound, but +only if it is preceded by grey.

Negative lookbehind with ?<! checks that its subpattern +could not possibly match immediately to the left.

> (regexp-match-positions #rx"(?<!grey)hound"
    "the greyhound in the picture is not a hound")

'((38 . 43))

The regexp #rx"(?<!grey)hound" matches hound, but +only if it is not preceded by grey.

Lookaheads and lookbehinds can be convenient when they +are not confusing.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Module_Syntax.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Module_Syntax.html new file mode 100644 index 00000000..1ecd61b8 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Module_Syntax.html @@ -0,0 +1,107 @@ + +6.2 Module Syntax

6.2 Module Syntax

The #lang at the start of a module file begins a shorthand +for a module form, much like ' is a shorthand for a +quote form. Unlike ', the #lang +shorthand does not work well in a REPL, in part because it must be +terminated by an end-of-file, but also because the longhand expansion +of #lang depends on the name of the enclosing file.

6.2.1 The module Form

The longhand form of a module declaration, which works in a +REPL as well as a file, is

(module name-id initial-module-path
  decl ...)

where the name-id is a name for the module, +initial-module-path is an initial import, and each +decl is an import, export, definition, or expression. In +the case of a file, name-id normally matches the name of the +containing file, minus its directory path or file extension, but +name-id is ignored when the module is required +through its file’s path.

The initial-module-path is needed because even the +require form must be imported for further use in the module +body. In other words, the initial-module-path import +bootstraps the syntax that is available in the body. The most commonly used +initial-module-path is racket, which supplies most +of the bindings described in this guide, including require, +define, and provide. Another commonly used +initial-module-path is racket/base, which provides +less functionality, but still much of the most commonly needed +functions and syntax.

For example, the "cake.rkt" example of the +previous section could be written as

(module cake racket
  (provide print-cake)
 
  (define (print-cake n)
    (show "   ~a   " n #\.)
    (show " .-~a-. " n #\|)
    (show " | ~a | " n #\space)
    (show "---~a---" n #\-))
 
  (define (show fmt n ch)
    (printf fmt (make-string n ch))
    (newline)))

Furthermore, this module form can be evaluated in a +REPL to declare a cake module that is not associated +with any file. To refer to such an unassociated module, quote the +module name:

Examples:
> (require 'cake)
> (print-cake 3)

   ...   

 .-|||-.

 |     |

---------

Declaring a module does not immediately evaluate the body definitions +and expressions of the module. The module must be explicitly +required at the top level to trigger evaluation. After +evaluation is triggered once, later requires do not +re-evaluate the module body.

Examples:
> (module hi racket
    (printf "Hello\n"))
> (require 'hi)

Hello

> (require 'hi)

6.2.2 The #lang Shorthand

The body of a #lang shorthand has no specific syntax, +because the syntax is determined by the language name that follows +#lang.

In the case of #lang racket, the syntax +is

#lang racket
decl ...

which reads the same as

(module name racket
  decl ...)

where name is derived from the name of the file that +contains the #lang form.

The #lang racket/base form has the same +syntax as #lang racket, except that +the longhand expansion uses racket/base instead of +racket. The #lang scribble/manual form, in +contrast, has a completely different syntax that doesn’t even look +like Racket, and which we do not attempt to describe in this guide.

Unless otherwise specified, a module that is documented as a +“language” using the #lang notation will expand to +module in the same way as #lang +racket. The documented language name can be used +directly with module or require, too.

6.2.3 Submodules

A module form can be nested within a module, in which case +the nested module form declares a +submodule. Submodules can be referenced directly by the +enclosing module using a quoted name. The following example prints +"Tony" by importing tiger from the zoo +submodule:

"park.rkt"

#lang racket
 
(module zoo racket
  (provide tiger)
  (define tiger "Tony"))
 
(require 'zoo)
 
tiger

Running a module does not necessarily run its submodules. In the above +example, running "park.rkt" runs its submodule zoo +only because the "park.rkt" module requires the +zoo submodule. Otherwise, a module and each of its submodules can be run +independently. Furthermore, if "park.rkt" is compiled to a +bytecode file (via raco make), then the code for +"park.rkt" or the code for zoo can be loaded independently.

Submodules can be nested within submodules, and a submodule can be +referenced directly by a module other than its enclosing module by +using a submodule path.

A module* form is similar to a nested module form:

(module* name-id initial-module-path-or-#f
  decl ...)

The module* form differs from module in that it +inverts the possibilities for reference between the submodule and +enclosing module:

  • A submodule declared with module can be +required by its enclosing module, but the submodule +cannot require the enclosing module or lexically +reference the enclosing module’s bindings.

  • A submodule declared with module* can require +its enclosing module, but the enclosing module cannot +require the submodule.

In addition, a module* form can specify #f in place of an +initial-module-path, in which case the submodule sees all of +the enclosing module’s bindings—including bindings that are not +exported via provide.

One use of submodules declared with module* and #f is +to export additional bindings through a submodule that are not +normally exported from the module:

"cake.rkt"

#lang racket
 
(provide print-cake)
 
(define (print-cake n)
  (show "   ~a   " n #\.)
  (show " .-~a-. " n #\|)
  (show " | ~a | " n #\space)
  (show "---~a---" n #\-))
 
(define (show fmt n ch)
  (printf fmt (make-string n ch))
  (newline))
 
(module* extras #f
  (provide show))

In this revised "cake.rkt" module, show is not +imported by a module that uses (require "cake.rkt"), since +most clients of "cake.rkt" will not want the extra function. A +module can require the extra submodule using +(require (submod "cake.rkt" extras)) to access the otherwise +hidden show function.See submodule paths +for more information on submod.

6.2.4 Main and Test Submodules

The following variant of "cake.rkt" includes a main +submodule that calls print-cake:

"cake.rkt"

#lang racket
 
(define (print-cake n)
  (show "   ~a   " n #\.)
  (show " .-~a-. " n #\|)
  (show " | ~a | " n #\space)
  (show "---~a---" n #\-))
 
(define (show fmt n ch)
  (printf fmt (make-string n ch))
  (newline))
 
(module* main #f
  (print-cake 10))

Running a module does not run its module*-defined +submodules. Nevertheless, running the above module via racket +or DrRacket prints a cake with 10 candles, because the main +submodule is a special case.

When a module is provided as a program name to the racket +executable or run directly within DrRacket, if the module has a +main submodule, the main submodule is run +after its enclosing module. Declaring a main submodule +thus specifies extra actions to be performed when a module is run directly, +instead of required as a library within a larger program.

A main submodule does not have to be declared with +module*. If the main module does not need to use +bindings from its enclosing module, it can be declared with +module. More commonly, main is declared using +module+:

(module+ name-id
  decl ...)

A submodule declared with module+ is like one declared with +module* using #f as its +initial-module-path. In addition, +multiple module+ forms can specify the same submodule name, +in which case the bodies of the module+ forms are combined to +create a single submodule.

The combining behavior of module+ is particularly useful for +defining a test submodule, which can be conveniently run +using raco test in much the same way that main is +conveniently run with racket. For example, the following +"physics.rkt" module exports drop and +to-energy functions, and it defines a test module to +hold unit tests:

"physics.rkt"

#lang racket
(module+ test
  (require rackunit)
  (define ε 1e-10))
 
(provide drop
         to-energy)
 
(define (drop t)
  (* 1/2 9.8 t t))
 
(module+ test
  (check-= (drop 0) 0 ε)
  (check-= (drop 10) 490 ε))
 
(define (to-energy m)
  (* m (expt 299792458.0 2)))
 
(module+ test
  (check-= (to-energy 0) 0 ε)
  (check-= (to-energy 1) 9e+16 1e+15))

Importing "physics.rkt" into a larger program does not run +the drop and to-energy tests—or even trigger the +loading of the test code, if the module is compiled—but running +raco test physics.rkt at a command line runs the tests.

The above "physics.rkt" module is equivalent to using +module*:

"physics.rkt"

#lang racket
 
(provide drop
         to-energy)
 
(define (drop t)
  (* 1/2 49/5 t t))
 
(define (to-energy m)
  (* m (expt 299792458 2)))
 
(module* test #f
  (require rackunit)
  (define ε 1e-10)
  (check-= (drop 0) 0 ε)
  (check-= (drop 10) 490 ε)
  (check-= (to-energy 0) 0 ε)
  (check-= (to-energy 1) 9e+16 1e+15))

Using module+ instead of module* allows tests to be +interleaved with function definitions.

The combining behavior of module+ is also sometimes helpful +for a main module. Even when combining is not needed, +(module+ main ....) is preferred as it is more readable than +(module* main #f ....).

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/More_Libraries.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/More_Libraries.html new file mode 100644 index 00000000..a09b2f54 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/More_Libraries.html @@ -0,0 +1,40 @@ + +22 More Libraries

22 More Libraries

This guide covers only the Racket language and libraries that are +documented in The Racket Reference. The Racket distribution includes many +additional libraries.

22.1 Graphics and GUIs

Racket provides many libraries for graphics and graphical user +interfaces (GUIs):

  • The racket/draw library provides basic drawing +tools, including drawing contexts such as bitmaps and +PostScript files.

    See The Racket Drawing Toolkit +for more information.

  • The racket/gui library provides GUI widgets +such as windows, buttons, checkboxes, and text fields. The +library also includes a sophisticated and extensible text +editor.

    See The Racket Graphical Interface Toolkit +for more information.

  • The pict library provides a more +functional abstraction layer over racket/draw. +This layer is especially useful for creating slide +presentations with Slideshow, but +it is also useful for creating images for Scribble +documents or other drawing tasks. Pictures created with the +pict library can be rendered to any +drawing context.

    See Slideshow: Figure and Presentation Tools +for more information.

  • The 2htdp/image library is similar to +pict. It is more streamlined for +pedagogical use, but also slightly more specific to screen and +bitmap drawing.

    See 2htdp/image for more information.

  • The sgl library provides OpenGL for 3-D +graphics. The context for rendering OpenGL can be a window or +bitmap created with racket/gui.

    See the SGL documentation for more +information.

22.2 The Web Server

Web Applications in Racket +describes the Racket web server, which supports servlets implemented +in Racket.

22.3 Using Foreign Libraries

The Racket Foreign Interface describes +tools for using Racket to access libraries that are normally used by C +programs.

22.4 And More

Racket Documentation lists documentation for +other libraries, including libraries that are installed as packages. +Run raco docs to find documentation for libraries that are +installed on your system and specific to your user account.

PLT Package Catalog at +https://pkgs.racket-lang.org offers even more downloadable +packages contributed by Racketeers. The +online Racket documentation +includes documentation for packages in that catalog, updated daily. +For more information about packages, see see Package Management in Racket.

PLaneT serves packages that +were developed using an older package system. Racket packages should +use the newer system, instead.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Pairs__Lists__and_Racket_Syntax.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Pairs__Lists__and_Racket_Syntax.html new file mode 100644 index 00000000..cbd89e8d --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Pairs__Lists__and_Racket_Syntax.html @@ -0,0 +1,87 @@ + +2.4 Pairs, Lists, and Racket Syntax

2.4 Pairs, Lists, and Racket Syntax

The cons function actually accepts any two values, not just +a list for the second argument. When the second argument is not +empty and not itself produced by cons, the result prints +in a special way. The two values joined with cons are printed +between parentheses, but with a dot (i.e., a period surrounded by +whitespace) in between:

> (cons 1 2)

'(1 . 2)

> (cons "banana" "split")

'("banana" . "split")

Thus, a value produced by cons is not always a list. In +general, the result of cons is a pair. The more +traditional name for the cons? function is pair?, +and we’ll use the traditional name from now on.

The name rest also makes less sense for non-list pairs; the +more traditional names for first and rest are +car and cdr, respectively. (Granted, the traditional +names are also nonsense. Just remember that “a” comes before “d,” +and cdr is pronounced “could-er.”)

Examples:
> (car (cons 1 2))

1

> (cdr (cons 1 2))

2

> (pair? empty)

#f

> (pair? (cons 1 2))

#t

> (pair? (list 1 2 3))

#t

Racket’s pair datatype and its relation to lists is essentially a +historical curiosity, along with the dot notation for printing and the +funny names car and cdr. Pairs are deeply wired into +the culture, specification, and implementation of Racket, however, +so they survive in the language.

You are perhaps most likely to encounter a non-list pair when making a +mistake, such as accidentally reversing the arguments to +cons:

> (cons (list 2 3) 1)

'((2 3) . 1)

> (cons 1 (list 2 3))

'(1 2 3)

Non-list pairs are used intentionally, sometimes. For example, the +make-hash function takes a list of pairs, where the +car of each pair is a key and the cdr is an +arbitrary value.

The only thing more confusing to new Racketeers than non-list pairs is +the printing convention for pairs where the second element is +a pair, but is not a list:

> (cons 0 (cons 1 2))

'(0 1 . 2)

In general, the rule for printing a pair is as follows: use the dot +notation unless the dot is immediately followed by an open +parenthesis. In that case, remove the dot, the open parenthesis, and the +matching close parenthesis. Thus, '(0 . (1 . 2)) +becomes '(0 1 . 2), and +'(1 . (2 . (3 . ()))) becomes '(1 2 3).

2.4.1 Quoting Pairs and Symbols with quote

A list prints with a quote mark before it, but if an element of a list +is itself a list, then no quote mark is printed for the inner list:

> (list (list 1) (list 2 3) (list 4))

'((1) (2 3) (4))

For nested lists, especially, the quote form lets you write a +list as an expression in essentially the same way that the list +prints:

> (quote ("red" "green" "blue"))

'("red" "green" "blue")

> (quote ((1) (2 3) (4)))

'((1) (2 3) (4))

> (quote ())

'()

The quote form works with the dot notation, too, whether the +quoted form is normalized by the dot-parenthesis elimination rule or +not:

> (quote (1 . 2))

'(1 . 2)

> (quote (0 . (1 . 2)))

'(0 1 . 2)

Naturally, lists of any kind can be nested:

> (list (list 1 2 3) 5 (list "a" "b" "c"))

'((1 2 3) 5 ("a" "b" "c"))

> (quote ((1 2 3) 5 ("a" "b" "c")))

'((1 2 3) 5 ("a" "b" "c"))

If you wrap an identifier with quote, then you get output +that looks like an identifier, but with a ' prefix:

> (quote jane-doe)

'jane-doe

A value that prints like a quoted identifier is a symbol. In the +same way that parenthesized output should not be confused with +expressions, a printed symbol should not be confused with an +identifier. In particular, the symbol (quote map) has nothing to do with the map +identifier or the predefined function that is bound to +map, except that the symbol and the identifier happen +to be made up of the same letters.

Indeed, the intrinsic value of a symbol is nothing more than its +character content. In this sense, symbols and strings are almost the +same thing, and the main difference is how they print. The functions +symbol->string and string->symbol convert between +them.

Examples:
> map

#<procedure:map>

> (quote map)

'map

> (symbol? (quote map))

#t

> (symbol? map)

#f

> (procedure? map)

#t

> (string->symbol "map")

'map

> (symbol->string (quote map))

"map"

In the same way that quote for a list automatically applies +itself to nested lists, quote on a parenthesized sequence of +identifiers automatically applies itself to the identifiers to create +a list of symbols:

> (car (quote (road map)))

'road

> (symbol? (car (quote (road map))))

#t

When a symbol is inside a list that is printed with +', the ' on the symbol is omitted, since +' is doing the job already:

> (quote (road map))

'(road map)

The quote form has no effect on a literal expression such as +a number or string:

> (quote 42)

42

> (quote "on the record")

"on the record"

2.4.2 Abbreviating quote with '

As you may have guessed, you can abbreviate a use of +quote by just putting ' in front of a form to +quote:

> '(1 2 3)

'(1 2 3)

> 'road

'road

> '((1 2 3) road ("a" "b" "c"))

'((1 2 3) road ("a" "b" "c"))

In the documentation, ' within an expression is printed in green along with the +form after it, since the combination is an expression that is a +constant. In DrRacket, only the ' is colored green. DrRacket +is more precisely correct, because the meaning of quote can +vary depending on the context of an expression. In the documentation, +however, we routinely assume that standard bindings are in scope, and +so we paint quoted forms in green for extra clarity.

A ' expands to a quote form in quite a literal +way. You can see this if you put a ' in front of a form that has a +':

> (car ''road)

'quote

> (car '(quote road))

'quote

The ' abbreviation works in output as well as input. The +REPL’s printer recognizes the symbol 'quote as the +first element of a two-element list when printing output, in which +case it uses to print the output:

> (quote (quote road))

''road

> '(quote road)

''road

> ''road

''road

2.4.3 Lists and Racket Syntax

Now that you know the truth about pairs and lists, and now that you’ve +seen quote, you’re ready to understand the main way in which +we have been simplifying Racket’s true syntax.

The syntax of Racket is not defined directly in terms of character +streams. Instead, the syntax is determined by two layers:

  • a reader layer, which turns a sequence of characters +into lists, symbols, and other constants; and

  • an expander layer, which processes the lists, symbols, +and other constants to parse them as an expression.

The rules for printing and reading go together. For example, a list is +printed with parentheses, and reading a pair of parentheses produces a +list. Similarly, a non-list pair is printed with the dot notation, and +a dot on input effectively runs the dot-notation rules in reverse to +obtain a pair.

One consequence of the read layer for expressions is that you can use +the dot notation in expressions that are not quoted forms:

> (+ 1 . (2))

3

This works because (+ 1 . (2)) is just another +way of writing (+ 1 2). It is practically never a good idea +to write application expressions using this dot notation; it’s just a +consequence of the way Racket’s syntax is defined.

Normally, . is allowed by the reader only with a +parenthesized sequence, and only before the last element of the +sequence. However, a pair of .s can also appear around a +single element in a parenthesized sequence, as long as the element is +not first or last. Such a pair triggers a reader conversion that moves +the element between .s to the front of the list. The +conversion enables a kind of general infix notation:

> (1 . < . 2)

#t

> '(1 . < . 2)

'(< 1 2)

This two-dot convention is non-traditional, and it has essentially +nothing to do with the dot notation for non-list pairs. Racket +programmers use the infix convention sparingly—mostly for asymmetric +binary operators such as < and is-a?.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Signatures_and_Units.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Signatures_and_Units.html new file mode 100644 index 00000000..1d197fc6 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Signatures_and_Units.html @@ -0,0 +1,17 @@ + +14.1 Signatures and Units

14.1 Signatures and Units

The interface of a unit is described in terms of +signatures. Each signature is defined (normally within a +module) using define-signature. For example, the +following signature, placed in a "toy-factory-sig.rkt" file, +describes the exports of a component that implements a toy factory:

By convention, signature names end with ^.

"toy-factory-sig.rkt"

#lang racket
 
(define-signature toy-factory^
  (build-toys  ; (integer? -> (listof toy?))
   repaint     ; (toy? symbol? -> toy?)
   toy?        ; (any/c -> boolean?)
   toy-color)) ; (toy? -> symbol?)
 
(provide toy-factory^)

An implementation of the toy-factory^ signature is written +using define-unit with an export clause that names +toy-factory^:

By convention, unit names end with @.

"simple-factory-unit.rkt"

#lang racket
 
(require "toy-factory-sig.rkt")
 
(define-unit simple-factory@
  (import)
  (export toy-factory^)
 
  (printf "Factory started.\n")
 
  (struct toy (color) #:transparent)
 
  (define (build-toys n)
    (for/list ([i (in-range n)])
      (toy 'blue)))
 
  (define (repaint t col)
    (toy col)))
 
(provide simple-factory@)

The toy-factory^ signature also could be referenced by a unit +that needs a toy factory to implement something else. In that case, +toy-factory^ would be named in an import clause. +For example, a toy store would get toys from a toy factory. (Suppose, +for the sake of an example with interesting features, that the store +is willing to sell only toys in a particular color.)

"toy-store-sig.rkt"

#lang racket
 
(define-signature toy-store^
  (store-color     ; (-> symbol?)
   stock!          ; (integer? -> void?)
   get-inventory)) ; (-> (listof toy?))
 
(provide toy-store^)

"toy-store-unit.rkt"

#lang racket
 
(require "toy-store-sig.rkt"
         "toy-factory-sig.rkt")
 
(define-unit toy-store@
  (import toy-factory^)
  (export toy-store^)
 
  (define inventory null)
 
  (define (store-color) 'green)
 
  (define (maybe-repaint t)
    (if (eq? (toy-color t) (store-color))
        t
        (repaint t (store-color))))
 
  (define (stock! n)
    (set! inventory
          (append inventory
                  (map maybe-repaint
                       (build-toys n)))))
 
  (define (get-inventory) inventory))
 
(provide toy-store@)

Note that "toy-store-unit.rkt" imports +"toy-factory-sig.rkt", but not +"simple-factory-unit.rkt". Consequently, the +toy-store@ unit relies only on the specification of a toy +factory, not on a specific implementation.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Simple_Values.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Simple_Values.html new file mode 100644 index 00000000..f781ff95 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Simple_Values.html @@ -0,0 +1,15 @@ + +2.1 Simple Values

2.1 Simple Values

Racket values include numbers, booleans, strings, and byte strings. In +DrRacket and documentation examples (when you read the documentation +in color), value expressions are shown in green.

Numbers are written in the usual way, including fractions +and imaginary numbers:

+Numbers (later in this guide) explains more about numbers.

1       3.14
1/2     6.02e+23
1+2i    9999999999999999999999

Booleans are #t for true and #f for +false. In conditionals, however, all non-#f values are +treated as true.

+Booleans (later in this guide) explains more about booleans.

Strings are written between doublequotes. Within a string, +backslash is an escaping character; for example, a backslash followed +by a doublequote includes a literal doublequote in the string. Except +for an unescaped doublequote or backslash, any Unicode character can +appear in a string constant.

+Strings (Unicode) (later in this guide) explains more about strings.

"Hello, world!"
"Benjamin \"Bugsy\" Siegel"
"λx:(μα.α→α).xx"

When a constant is evaluated in the REPL, it typically prints the same +as its input syntax. In some cases, the printed form is a normalized +version of the input syntax. In documentation and in DrRacket’s REPL, +results are printed in blue instead of green to highlight the +difference between an input expression and a printed result.

Examples:
> 1.0000

1.0

> "Bugs \u0022Figaro\u0022 Bunny"

"Bugs \"Figaro\" Bunny"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Sublime_Text.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Sublime_Text.html new file mode 100644 index 00000000..3f36bf30 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Sublime_Text.html @@ -0,0 +1,3 @@ + +24.4 Sublime Text

24.4 Sublime Text

The Racket package +provides support for syntax highlighting and building for Sublime Text.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Vim.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Vim.html new file mode 100644 index 00000000..a900a8fd --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Vim.html @@ -0,0 +1,55 @@ + +24.3 Vim

24.3 Vim

Many distributions of Vim ship with support for Scheme, which will mostly work +for Racket. As of version 7.3.518, +Vim detects files with the extension .rkt as having the +scheme filetype. Version 8.2.3368 +added support for .rktd and .rktl.

In older versions, you can enable filetype detection of Racket +files as Scheme with the following:

  if has("autocmd")

    autocmd filetypedetect BufReadPost *.rkt,*.rktl,*.rktd set filetype=scheme

  endif

If your Vim supports the ftdetect system, in which case it’s likely new enough +to support Racket already, you can nevertheless put the following in +"~/.vim/ftdetect/racket.vim" +("$HOME/vimfiles/ftdetect/racket.vim" on MS-Windows; see :help runtimepath).

  " :help ftdetect

  " If you want to change the filetype only if one has not been set

  autocmd BufRead,BufNewFile *.rkt,*.rktl,*.rktd setfiletype scheme

  " If you always want to set this filetype

  autocmd BufRead,BufNewFile *.rkt,*.rktl,*.rktd set filetype=scheme

24.3.1 Plugins

Alternatively, you can use a plugin such as

The major difference between the two is that the +benknoble/vim-racket fork supports more features out of the box and is +updated more frequently.

to enable auto-detection, indentation, and syntax highlighting specifically for +Racket files.

These plugins work by setting the filetype option based on the #lang +line. For example:
Depending on which plugin you have, modifiers like at-exp may also be +ignored, so that #lang at-exp racket is still a filetype of +racket.

This approach is more flexible but may lead to more work. Since each +#lang has its own filetype, options, syntax highlighting, and other +features need to be configured for each filetype. This can be done via the +standard ftplugin mechanism. See for example :help ftplugin-overrule +and :help ftplugin: place your options for <lang> in +"~/.vim/after/ftplugin/<lang>.vim" +("$HOME/vimfiles/after/ftplugin/<lang>.vim" on MS-Windows). Similarly, +syntax files follow the standard mechanism documented in :help syntax.

Both plugins come with configuration for Racket +(and possibly other #langs) as ftplugins. To enable them, use the +:filetype command as documented in :help :filetype. You likely want to +turn on filetype plugins (:help :filetype-plugin-on) and filetype indent +plugins (:help :filetype-indent-on).

24.3.2 Indentation

You can enable indentation for Racket by setting both the lisp and +autoindent options in Vim. You will want to customize the buffer-local +lispwords option to control how special forms are indented. See :help +lispwords. Both plugins mentioned in Plugins set this option for +you.

However, the indentation can be limited and may not be as complete as what you +can get in Emacs. You can also use Dorai Sitaram’s +scmindent for better +indentation of Racket code. The instructions on how to use the indenter are +available on the website.

24.3.3 Highlighting

The Rainbow +Parenthesis script for Vim can be useful for more visible parenthesis +matching. Syntax highlighting for Scheme is shipped with Vim on many platforms, +which will work for the most part with Racket. The vim-racket script +provides good default highlighting settings for you.

24.3.4 Structured Editing

The Slimv +plugin has a paredit mode that works like paredit in Emacs. However, the plugin +is not aware of Racket. You can either set Vim to treat Racket as Scheme files +or you can modify the paredit script to load on ".rkt" files.

For a more Vim-like set of key-mappings, pair either of

The benknoble/vim-sexp fork is slightly more modern vimscript.

with tpope/vim-sexp-mappings-for-regular-people. +The experience is on par with paredit, but more comfortable for the fingers.

24.3.5 REPLs

There are many general-purpose Vim + REPL plugins out there. Here are a few that +support Racket out of the box:

24.3.6 Scribble

Vim support for writing scribble documents is provided by

Again, benknoble/scribble.vim is updated more frequently and +is somewhat more modern.

24.3.7 Miscellaneous

If you are installing many Vim plugins (not necessary specific to Racket), we +recommend using a plugin that will make loading other plugins easier. There are +many plugin managers.

Pathogen is one plugin that +does this; using it, you can install new plugins by extracting them to +subdirectories in the "bundle" folder of your personal Vim files +("~/.vim" on Unix, "$HOME/vimfiles" on MS-Windows).

With newer Vim versions, you can use the package system (:help packages).

One relatively up-to-date reference on the various managers is +What are the differences between the vim plugin managers?. +The same site, Vi & Vim is a great +place to get help from Vimmers.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Visual_Studio_Code.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Visual_Studio_Code.html new file mode 100644 index 00000000..0a4fe84a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Visual_Studio_Code.html @@ -0,0 +1,3 @@ + +24.5 Visual Studio Code

24.5 Visual Studio Code

The Magic Racket +extension provides Racket support including REPL integration and syntax highlighting in Visual Studio Code.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/Whole-module_Signatures_and_Units.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/Whole-module_Signatures_and_Units.html new file mode 100644 index 00000000..9618a2cd --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/Whole-module_Signatures_and_Units.html @@ -0,0 +1,10 @@ + +14.5 Whole-module Signatures and Units

14.5 Whole-module Signatures and Units

In programs that use units, modules like "toy-factory-sig.rkt" +and "simple-factory-unit.rkt" are common. The +racket/signature and racket/unit module names can be +used as languages to avoid much of the boilerplate module, signature, +and unit declaration text.

For example, "toy-factory-sig.rkt" can be written as

#lang racket/signature
 
build-toys  ; (integer? -> (listof toy?))
repaint     ; (toy? symbol? -> toy?)
toy?        ; (any/c -> boolean?)
toy-color   ; (toy? -> symbol?)

The signature toy-factory^ is automatically provided from the +module, inferred from the filename "toy-factory-sig.rkt" by +replacing the "-sig.rkt" suffix with ^.

Similarly, "simple-factory-unit.rkt" module can be written

#lang racket/unit
 
(require "toy-factory-sig.rkt")
 
(import)
(export toy-factory^)
 
(printf "Factory started.\n")
 
(struct toy (color) #:transparent)
 
(define (build-toys n)
  (for/list ([i (in-range n)])
    (toy 'blue)))
 
(define (repaint t col)
  (toy col))

The unit simple-factory@ is automatically provided from the +module, inferred from the filename "simple-factory-unit.rkt" by +replacing the "-unit.rkt" suffix with @.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/application.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/application.html new file mode 100644 index 00000000..e1aa9665 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/application.html @@ -0,0 +1,41 @@ + +4.3 Function Calls

4.3 Function Calls (Procedure Applications)

An expression of the form

(proc-expr arg-expr ...)

is a function call—also known as a procedure +applicationwhen proc-expr is not an identifier that is +bound as a syntax transformer (such as if or +define).

4.3.1 Evaluation Order and Arity

A function call is evaluated by first evaluating the +proc-expr and all arg-exprs in order (left to +right). Then, if proc-expr produces a function that accepts +as many arguments as supplied arg-exprs, the function is +called. Otherwise, an exception is raised.

Examples:
> (cons 1 null)

'(1)

> (+ 1 2 3)

6

> (cons 1 2 3)

cons: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 2

  given: 3

> (1 2 3)

application: not a procedure;

 expected a procedure that can be applied to arguments

  given: 1

Some functions, such as cons, accept a fixed number of +arguments. Some functions, such as + or list, accept +any number of arguments. Some functions accept a range of argument +counts; for example substring accepts either two or three +arguments. A function’s arity is the number of arguments +that it accepts.

4.3.2 Keyword Arguments

Some functions accept keyword arguments in addition to +by-position arguments. For that case, an arg can be an +arg-keyword arg-expr sequence instead of just a +arg-expr:

+Keywords introduces keywords.

(proc-expr arg ...)
 
arg = arg-expr
  | arg-keyword arg-expr

For example,

(go "super.rkt" #:mode 'fast)

calls the function bound to go with "super.rkt" as a +by-position argument, and with 'fast as an argument +associated with the #:mode keyword. A keyword is implicitly +paired with the expression that follows it.

Since a keyword by itself is not an expression, then

(go "super.rkt" #:mode #:fast)

is a syntax error. The #:mode keyword must be followed by an +expression to produce an argument value, and #:fast is not an +expression.

The order of keyword args determines the order in which +arg-exprs are evaluated, but a function accepts keyword +arguments independent of their position in the argument list. The +above call to go can be equivalently written

(go #:mode 'fast "super.rkt")

+Procedure Applications and #%app in The Racket Reference provides more on procedure applications.

4.3.3 The apply Function

The syntax for function calls supports any number of arguments, but a +specific call always specifies a fixed number of arguments. As a +result, a function that takes a list of arguments cannot directly +apply a function like + to all of the items in a list:

(define (avg lst) ; doesn’t work...
  (/ (+ lst) (length lst)))

 

> (avg '(1 2 3))

+: contract violation

  expected: number?

  given: '(1 2 3)

(define (avg lst) ; doesn’t always work...
  (/ (+ (list-ref lst 0) (list-ref lst 1) (list-ref lst 2))
     (length lst)))

 

> (avg '(1 2 3))

2

> (avg '(1 2))

list-ref: index too large for list

  index: 2

  in: '(1 2)

The apply function offers a way around this restriction. It +takes a function and a list argument, and it applies the +function to the values in the list:

(define (avg lst)
  (/ (apply + lst) (length lst)))

 

> (avg '(1 2 3))

2

> (avg '(1 2))

3/2

> (avg '(1 2 3 4))

5/2

As a convenience, the apply function accepts additional +arguments between the function and the list. The additional arguments +are effectively consed onto the argument list:

(define (anti-sum lst)
  (apply - 0 lst))

 

> (anti-sum '(1 2 3))

-6

The apply function accepts keyword arguments, too, and it +passes them along to the called function:

(apply go #:mode 'fast '("super.rkt"))
(apply go '("super.rkt") #:mode 'fast)

Keywords that are included in apply’s list argument do not +count as keyword arguments for the called function; instead, all arguments in +this list are treated as by-position arguments. To pass a list of +keyword arguments to a function, use +the keyword-apply function, which accepts a function to apply +and three lists. The first two lists are in parallel, where the first +list contains keywords (sorted by keyword<?), and the second +list contains a corresponding argument for each keyword. The third +list contains by-position function arguments, as for apply.

(keyword-apply go
               '(#:mode)
               '(fast)
               '("super.rkt"))
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/begin.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/begin.html new file mode 100644 index 00000000..dc82b1ec --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/begin.html @@ -0,0 +1,27 @@ + +4.8 Sequencing

4.8 Sequencing

Racket programmers prefer to write programs with as few side-effects +as possible, since purely functional code is more easily tested and +composed into larger programs. Interaction with the external +environment, however, requires sequencing, such as when writing to a +display, opening a graphical window, or manipulating a file on disk.

4.8.1 Effects Before: begin

+Sequencing: begin, begin0, and begin-for-syntax in The Racket Reference also documents begin.

A begin expression sequences expressions:

(begin expr ...+)

The exprs are evaluated in order, and the result of all but +the last expr is ignored. The result from the last +expr is the result of the begin form, and it is in +tail position with respect to the begin form.

Examples:
(define (print-triangle height)
  (if (zero? height)
      (void)
      (begin
        (display (make-string height #\*))
        (newline)
        (print-triangle (sub1 height)))))
> (print-triangle 4)

****

***

**

*

Many forms, such as lambda or cond support a +sequence of expressions even without a begin. Such positions are +sometimes said to have an implicit begin.

Examples:
(define (print-triangle height)
  (cond
    [(positive? height)
     (display (make-string height #\*))
     (newline)
     (print-triangle (sub1 height))]))
> (print-triangle 4)

****

***

**

*

The begin form is special at the top level, at module level, +or as a body after only internal definitions. In those +positions, instead of forming an expression, the content of +begin is spliced into the surrounding context.

Example:
> (let ([curly 0])
    (begin
      (define moe (+ 1 curly))
      (define larry (+ 1 moe)))
    (list larry curly moe))

'(2 0 1)

This splicing behavior is mainly useful for macros, as we discuss +later in Macros.

4.8.2 Effects After: begin0

+Sequencing: begin, begin0, and begin-for-syntax in The Racket Reference also documents begin0.

A begin0 expression has the same syntax as a begin +expression:

(begin0 expr ...+)

The difference is that begin0 returns the result of the first +expr, instead of the result of the last expr. The +begin0 form is useful for implementing side-effects that +happen after a computation, especially in the case where the +computation produces an unknown number of results.

Examples:
(define (log-times thunk)
  (printf "Start: ~s\n" (current-inexact-milliseconds))
  (begin0
    (thunk)
    (printf "End..: ~s\n" (current-inexact-milliseconds))))
> (log-times (lambda () (sleep 0.1) 0))

Start: 1659635523430.117

End..: 1659635523530.1548

0

> (log-times (lambda () (values 1 2)))

Start: 1659635523531.675

End..: 1659635523531.6907

1

2

4.8.3 Effects If...: when and unless

+Guarded Evaluation: when and unless in The Racket Reference also documents when and unless.

The when form combines an if-style conditional with +sequencing for the “then” clause and no “else” clause:

(when test-expr then-body ...+)

If test-expr produces a true value, then all of the +then-bodys are evaluated. The result of the last +then-body is the result of the when form. +Otherwise, no then-bodys are evaluated and the +result is #<void>.

The unless form is similar:

(unless test-expr then-body ...+)

The difference is that the test-expr result is inverted: the +then-bodys are evaluated only if the test-expr +result is #f.

Examples:
(define (enumerate lst)
  (if (null? (cdr lst))
      (printf "~a.\n" (car lst))
      (begin
        (printf "~a, " (car lst))
        (when (null? (cdr (cdr lst)))
          (printf "and "))
        (enumerate (cdr lst)))))
> (enumerate '("Larry" "Curly" "Moe"))

Larry, Curly, and Moe.

(define (print-triangle height)
  (unless (zero? height)
    (display (make-string height #\*))
    (newline)
    (print-triangle (sub1 height))))

 

> (print-triangle 4)

****

***

**

*

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/binding.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/binding.html new file mode 100644 index 00000000..98638739 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/binding.html @@ -0,0 +1,35 @@ + +4.2 Identifiers and Binding

4.2 Identifiers and Binding

The context of an expression determines the meaning of identifiers +that appear in the expression. In particular, starting a module with +the language racket, as in

#lang racket

means that, within the module, the identifiers described in this guide +start with the meaning described here: cons refers to the +function that creates a pair, car refers to the function +that extracts the first element of a pair, and so on.

+Symbols introduces the syntax of +identifiers.

Forms like define, lambda, and let +associate a meaning with one or more identifiers; that is, they +bind identifiers. The part of the program for which the +binding applies is the scope of the binding. The set of +bindings in effect for a given expression is the expression’s +environment.

For example, in

#lang racket
 
(define f
  (lambda (x)
    (let ([y 5])
      (+ x y))))
 
(f 10)

the define is a binding of f, the lambda +has a binding for x, and the let has a binding for +y. The scope of the binding for f is the entire +module; the scope of the x binding is (let ([y 5]) (+ x y)); and the scope of the y binding is just (+ x y). The environment of (+ x y) includes bindings for +y, x, and f, as well as everything in +racket.

A module-level define can bind only identifiers that are not +already defined or required into the module. A local +define or other binding forms, however, can give a new local +binding for an identifier that already has a binding; such a binding +shadows the existing binding.

Examples:
(define f
  (lambda (append)
    (define cons (append "ugly" "confusing"))
    (let ([append 'this-was])
      (list append cons))))
> (f list)

'(this-was ("ugly" "confusing"))

Similarly, a module-level define can shadow a binding +from the module’s language. For example, (define cons 1) in a +racket module shadows the cons that is +provided by racket. Intentionally shadowing a language +binding is rarely a good idea—especially for widely used bindings +like consbut shadowing relieves a programmer from having +to avoid every obscure binding that is provided by a language.

Even identifiers like define and lambda get their +meanings from bindings, though they have transformer +bindings (which means that they indicate syntactic forms) instead of +value bindings. Since define has a transformer binding, the +identifier define cannot be used by itself to get a +value. However, the normal binding for define can be +shadowed.

Examples:
> define

eval:1:0: define: bad syntax

  in: define

> (let ([define 5]) define)

5

Again, shadowing standard bindings in this way is rarely a good idea, but the +possibility is an inherent part of Racket’s flexibility.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/booleans.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/booleans.html new file mode 100644 index 00000000..3da3f7e7 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/booleans.html @@ -0,0 +1,8 @@ + +3.1 Booleans

3.1 Booleans

Racket has two distinguished constants to represent boolean values: +#t for true and #f for false. Uppercase +#T and #F are parsed as the same +values, but the lowercase forms are preferred.

The boolean? procedure recognizes the two boolean +constants. In the result of a test expression for if, +cond, and, or, etc., however, any value +other than #f counts as true.

Examples:
> (= 2 (+ 1 1))

#t

> (boolean? #t)

#t

> (boolean? #f)

#t

> (boolean? "no")

#f

> (if "no" 1 0)

1

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/boxes.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/boxes.html new file mode 100644 index 00000000..737a31c4 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/boxes.html @@ -0,0 +1,5 @@ + +3.11 Boxes

3.11 Boxes

A box is like a single-element vector. It can print as a +quoted #& followed by the printed form of the boxed value. +A #& form can also be used as an expression, but since the +resulting box is constant, it has practically no use.

Examples:
> (define b (box "apple"))
> b

'#&"apple"

> (unbox b)

"apple"

> (set-box! b '(banana boat))
> b

'#&(banana boat)

+Boxes in The Racket Reference provides more on boxes and box procedures.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/bytestrings.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/bytestrings.html new file mode 100644 index 00000000..d7f246e7 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/bytestrings.html @@ -0,0 +1,22 @@ + +3.5 Bytes and Byte Strings

3.5 Bytes and Byte Strings

A byte is an exact integer between 0 and +255, inclusive. The byte? predicate recognizes +numbers that represent bytes.

Examples:
> (byte? 0)

#t

> (byte? 256)

#f

A byte string is similar to a string—see +Strings (Unicode)but its content is a sequence of bytes +instead of characters. Byte strings can be used in applications that +process pure ASCII instead of Unicode text. The printed form of a +byte string supports such uses in particular, because a byte string +prints like the ASCII decoding of the byte string, but prefixed with a +#. Unprintable ASCII characters or non-ASCII bytes in the +byte string are written with octal notation.

+Reading Strings in The Racket Reference documents the fine points of the syntax of byte strings.

Examples:
> #"Apple"

#"Apple"

> (bytes-ref #"Apple" 0)

65

> (make-bytes 3 65)

#"AAA"

> (define b (make-bytes 2 0))
> b

#"\0\0"

> (bytes-set! b 0 1)
> (bytes-set! b 1 255)
> b

#"\1\377"

The display form of a byte string writes its raw bytes to the +current output port (see Input and Output). Technically, +display of a normal (i.e,. character) string prints the UTF-8 +encoding of the string to the current output port, since output is +ultimately defined in terms of bytes; display of a byte +string, however, writes the raw bytes with no encoding. Along the same +lines, when this documentation shows output, it technically shows the +UTF-8-decoded form of the output.

Examples:
> (display #"Apple")

Apple

> (display "\316\273")  ; same as "λ"

λ

> (display #"\316\273") ; UTF-8 encoding of λ

λ

For explicitly converting between strings and byte strings, Racket +supports three kinds of encodings directly: UTF-8, Latin-1, and the +current locale’s encoding. General facilities for byte-to-byte +conversions (especially to and from UTF-8) fill the gap to support +arbitrary string encodings.

Examples:
> (bytes->string/utf-8 #"\316\273")

"λ"

> (bytes->string/latin-1 #"\316\273")

"λ"

> (parameterize ([current-locale "C"])  ; C locale supports ASCII,
    (bytes->string/locale #"\316\273")) ; only, so...

bytes->string/locale: byte string is not a valid encoding

for the current locale

  byte string: #"\316\273"

> (let ([cvt (bytes-open-converter "cp1253" ; Greek code page
                                   "UTF-8")]
        [dest (make-bytes 2)])
    (bytes-convert cvt #"\353" 0 1 dest)
    (bytes-close-converter cvt)
    (bytes->string/utf-8 dest))

"λ"

+Byte Strings in The Racket Reference provides more on byte strings and byte-string procedures.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/case.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/case.html new file mode 100644 index 00000000..91838bfd --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/case.html @@ -0,0 +1,11 @@ + +4.12 Simple Dispatch: case

4.12 Simple Dispatch: case

The case form dispatches to a clause by matching the result +of an expression to the values for the clause:

(case expr
  [(datum ...+) body ...+]
  ...)

Each datum will be compared to the result of expr +using equal?, and then the corresponding bodys are +evaluated. The case form can dispatch to the correct clause +in O(log N) time for N datums.

Multiple datums can be supplied for each clause, and the +corresponding bodys are evaluated if any of the +datums match.

Example:
> (let ([v (random 6)])
    (printf "~a\n" v)
    (case v
      [(0) 'zero]
      [(1) 'one]
      [(2) 'two]
      [(3 4 5) 'many]))

2

'two

The last clause of a case form can use else, just +like cond:

Example:
> (case (random 6)
    [(0) 'zero]
    [(1) 'one]
    [(2) 'two]
    [else 'many])

'one

For more general pattern matching (but without the dispatch-time +guarantee), use match, which is introduced in +Pattern Matching.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/characters.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/characters.html new file mode 100644 index 00000000..c15f573a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/characters.html @@ -0,0 +1,27 @@ + +3.3 Characters

3.3 Characters

A Racket character corresponds to a Unicode scalar +value. Roughly, a scalar value is an unsigned integer whose +representation fits into 21 bits, and that maps to some notion of a +natural-language character or piece of a character. Technically, a +scalar value is a simpler notion than the concept called a +“character” in the Unicode standard, but it’s an approximation that +works well for many purposes. For example, any accented Roman letter +can be represented as a scalar value, as can any common Chinese character.

Although each Racket character corresponds to an integer, the +character datatype is separate from numbers. The +char->integer and integer->char procedures convert +between scalar-value numbers and the corresponding character.

A printable character normally prints as #\ followed +by the represented character. An unprintable character normally prints +as #\u followed by the scalar value as hexadecimal +number. A few characters are printed specially; for example, the space +and linefeed characters print as #\space and +#\newline, respectively.

+Reading Characters in The Racket Reference documents the fine points of the syntax of characters.

Examples:
> (integer->char 65)

#\A

> (char->integer #\A)

65

> #\λ

#\λ

> #\u03BB

#\λ

> (integer->char 17)

#\u0011

> (char->integer #\space)

32

The display procedure directly writes a character to the +current output port (see Input and Output), in contrast to the +character-constant syntax used to print a character result.

Examples:
> #\A

#\A

> (display #\A)

A

Racket provides several classification and conversion procedures on +characters. Beware, however, that conversions on some Unicode +characters work as a human would expect only when they are in a string +(e.g., upcasing “ß” or downcasing “Σ”).

Examples:
> (char-alphabetic? #\A)

#t

> (char-numeric? #\0)

#t

> (char-whitespace? #\newline)

#t

> (char-downcase #\A)

#\a

> (char-upcase #\ß)

#\ß

The char=? procedure compares two or more characters, and +char-ci=? compares characters ignoring case. The +eqv? and equal? procedures behave the same as +char=? on characters; use char=? when you want to +more specifically declare that the values being compared are +characters.

Examples:
> (char=? #\a #\A)

#f

> (char-ci=? #\a #\A)

#t

> (eqv? #\a #\A)

#f

+Characters in The Racket Reference provides more on characters and character procedures.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/classes.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/classes.html new file mode 100644 index 00000000..26af3f5e --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/classes.html @@ -0,0 +1,365 @@ + +13 Classes and Objects

13 Classes and Objects

This chapter is based on a paper [Flatt06].

A class expression denotes a first-class value, +just like a lambda expression:

(class superclass-expr decl-or-expr ...)

The superclass-expr determines the superclass for the new +class. Each decl-or-expr is either a declaration related to +methods, fields, and initialization arguments, or it is an expression +that is evaluated each time that the class is instantiated. In other +words, instead of a method-like constructor, a class has +initialization expressions interleaved with field and method +declarations.

By convention, class names end with %. The built-in root class is +object%. The following expression creates a class with +public methods get-size, grow, and eat:

(class object%
  (init size)                ; initialization argument
 
  (define current-size size) ; field
 
  (super-new)                ; superclass initialization
 
  (define/public (get-size)
    current-size)
 
  (define/public (grow amt)
    (set! current-size (+ amt current-size)))
 
  (define/public (eat other-fish)
    (grow (send other-fish get-size))))

The size initialization argument must be supplied via a named + argument when instantiating the class through the new form:

(new (class object% (init size) ....) [size 10])

Of course, we can also name the class and its instance:

(define fish% (class object% (init size) ....))
(define charlie (new fish% [size 10]))

In the definition of fish%, current-size is a +private field that starts out with the value of the size +initialization argument. Initialization arguments like size +are available only during class instantiation, so they cannot be +referenced directly from a method. The current-size field, in +contrast, is available to methods.

The (super-new) expression in fish% invokes the +initialization of the superclass. In this case, the superclass is +object%, which takes no initialization arguments and performs +no work; super-new must be used, anyway, because a class must +always invoke its superclass’s initialization.

Initialization arguments, field declarations, and expressions such as +(super-new) can appear in any order within a class, +and they can be interleaved with method declarations. The relative +order of expressions in the class determines the order of evaluation +during instantiation. For example, if a field’s initial value requires +calling a method that works only after superclass initialization, then +the field declaration must be placed after the super-new +call. Ordering field and initialization declarations in this way helps +avoid imperative assignment. The relative order of method declarations +makes no difference for evaluation, because methods are fully defined +before a class is instantiated.

13.1 Methods

Each of the three define/public declarations in +fish% introduces a new method. The declaration uses the same +syntax as a Racket function, but a method is not accessible as an +independent function. A call to the grow method of a +fish% object requires the send form:

> (send charlie grow 6)
> (send charlie get-size)

16

Within fish%, self methods can be called like functions, +because the method names are in scope. For example, the eat +method within fish% directly invokes the grow +method. Within a class, attempting to use a method name in any way +other than a method call results in a syntax error.

In some cases, a class must call methods that are supplied by the superclass +but not overridden. In that case, the class can use send +with this to access the method:

(define hungry-fish% (class fish% (super-new)
                       (define/public (eat-more fish1 fish2)
                         (send this eat fish1)
                         (send this eat fish2))))

 

Alternately, the class can declare the existence of a method using inherit, +which brings the method name into scope for a direct call:

(define hungry-fish% (class fish% (super-new)
                       (inherit eat)
                       (define/public (eat-more fish1 fish2)
                         (eat fish1) (eat fish2))))

 

With the inherit declaration, if fish% had not +provided an eat method, an error would be signaled in the +evaluation of the class form for hungry-fish%. In +contrast, with (send this ....), an error would not be +signaled until the eat-more method is called and the +send form is evaluated. For this reason, inherit is +preferred.

Another drawback of send is that it is less efficient than +inherit. Invocation of a method via send involves +finding a method in the target object’s class at run time, making +send comparable to an interface-based method call in Java. In +contrast, inherit-based method invocations use an offset +within the class’s method table that is computed when the class is +created.

To achieve performance similar to inherit-based method calls when +invoking a method from outside the method’s class, the programmer must use the +generic form, which produces a class- and method-specific +generic method to be invoked with send-generic:

(define get-fish-size (generic fish% get-size))

 

> (send-generic charlie get-fish-size)

16

> (send-generic (new hungry-fish% [size 32]) get-fish-size)

32

> (send-generic (new object%) get-fish-size)

generic:get-size: target is not an instance of the generic's

class

  target: (object)

  class name: fish%

Roughly speaking, the form translates the class and the external +method name to a location in the class’s method table. As illustrated +by the last example, sending through a generic method checks that its +argument is an instance of the generic’s class.

Whether a method is called directly within a class, +through a generic method, +or through send, method overriding works in the usual way:

(define picky-fish% (class fish% (super-new)
                      (define/override (grow amt)
 
                        (super grow (* 3/4 amt)))))
(define daisy (new picky-fish% [size 20]))

 

> (send daisy eat charlie)
> (send daisy get-size)

32

The grow method in picky-fish% is declared with +define/override instead of define/public, because +grow is meant as an overriding declaration. If grow +had been declared with define/public, an error would have +been signaled when evaluating the class expression, because +fish% already supplies grow.

Using define/override also allows the invocation of the +overridden method via a super call. For example, the +grow implementation in picky-fish% uses +super to delegate to the superclass implementation.

13.2 Initialization Arguments

Since picky-fish% declares no initialization arguments, any +initialization values supplied in (new picky-fish% ....) are +propagated to the superclass initialization, i.e., to fish%. +A subclass can supply additional initialization arguments for its +superclass in a super-new call, and such initialization +arguments take precedence over arguments supplied to new. For +example, the following size-10-fish% class always generates +fish of size 10:

(define size-10-fish% (class fish% (super-new [size 10])))

 

> (send (new size-10-fish%) get-size)

10

In the case of size-10-fish%, supplying a size +initialization argument with new would result in an +initialization error; because the size in super-new +takes precedence, a size supplied to new would have +no target declaration.

An initialization argument is optional if the class form +declares a default value. For example, the following default-10-fish% +class accepts a size initialization argument, but its value defaults to +10 if no value is supplied on instantiation:

(define default-10-fish% (class fish%
                           (init [size 10])
                           (super-new [size size])))

 

> (new default-10-fish%)

(object:default-10-fish% ...)

> (new default-10-fish% [size 20])

(object:default-10-fish% ...)

In this example, the super-new call propagates its own +size value as the size initialization argument to +the superclass.

13.3 Internal and External Names

The two uses of size in default-10-fish% expose the +double life of class-member identifiers. When size is the +first identifier of a bracketed pair in new or +super-new, size is an external name that +is symbolically matched to an initialization argument in a class. When +size appears as an expression within +default-10-fish%, size is an internal name +that is lexically scoped. Similarly, a call to an inherited +eat method uses eat as an internal name, whereas a +send of eat uses eat as an external name.

The full syntax of the class form allows a programmer to +specify distinct internal and external names for a class member. Since +internal names are local, they can be renamed to avoid shadowing or +conflicts. Such renaming is not frequently necessary, but workarounds +in the absence of renaming can be especially cumbersome.

13.4 Interfaces

Interfaces are useful for checking that an object or a class +implements a set of methods with a particular (implied) behavior. +This use of interfaces is helpful even without a static type system +(which is the main reason that Java has interfaces).

An interface in Racket is created using the interface +form, which merely declares the method names required to implement the +interface. An interface can extend other interfaces, which means that +implementations of the interface automatically implement the extended +interfaces.

(interface (superinterface-expr ...) id ...)

To declare that a class implements an interface, the +class* form must be used instead of class:

(class* superclass-expr (interface-expr ...) decl-or-expr ...)

For example, instead of forcing all fish classes to be derived from +fish%, we can define fish-interface and change the +fish% class to declare that it implements +fish-interface:

(define fish-interface (interface () get-size grow eat))
(define fish% (class* object% (fish-interface) ....))

If the definition of fish% does not include +get-size, grow, and eat methods, then an +error is signaled in the evaluation of the class* form, +because implementing the fish-interface interface requires +those methods.

The is-a? predicate accepts an object as its first argument +and either a class or interface as its second argument. When given a +class, is-a? checks whether the object is an instance of that +class or a derived class. When given an interface, is-a? +checks whether the object’s class implements the interface. In +addition, the implementation? predicate checks whether a +given class implements a given interface.

13.5 Final, Augment, and Inner

As in Java, a method in a class form can be specified as +final, which means that a subclass cannot override the +method. A final method is declared using public-final or +override-final, depending on whether the declaration is for a +new method or an overriding implementation.

Between the extremes of allowing arbitrary overriding and disallowing +overriding entirely, the class system also supports Beta-style +augmentable methods [Goldberg04]. A method +declared with pubment is like public, but the method +cannot be overridden in subclasses; it can be augmented only. A +pubment method must explicitly invoke an augmentation (if any) +using inner; a subclass augments the method using +augment, instead of override.

In general, a method can switch between augment and override modes in +a class derivation. The augride method specification +indicates an augmentation to a method where the augmentation is itself +overrideable in subclasses (though the superclass’s implementation +cannot be overridden). Similarly, overment overrides a method +and makes the overriding implementation augmentable.

13.6 Controlling the Scope of External Names

Java’s access modifiers (like protected) +play a role similar to define-member-name, but +unlike in Java, Racket’s mechanism for controlling access +is based on lexical scope, not the inheritance hierarchy.

As noted in Internal and External Names, class members have both +internal and external names. A member definition binds an internal +name locally, and this binding can be locally renamed. External +names, in contrast, have global scope by default, and a member +definition does not bind an external name. Instead, a member +definition refers to an existing binding for an external name, where +the member name is bound to a member key; a class ultimately +maps member keys to methods, fields, and initialization arguments.

Recall the hungry-fish% class expression:

(define hungry-fish% (class fish% ....
                       (inherit eat)
                       (define/public (eat-more fish1 fish2)
                         (eat fish1) (eat fish2))))

During its evaluation, the hungry-fish% and fish% +classes refer to the same global binding of eat. At run +time, calls to eat in hungry-fish% are matched with +the eat method in fish% through the shared method +key that is bound to eat.

The default binding for an external name is global, but a +programmer can introduce an external-name binding with the +define-member-name form.

(define-member-name id member-key-expr)

In particular, by using (generate-member-key) as the +member-key-expr, an external name can be localized for a +particular scope, because the generated member key is inaccessible +outside the scope. In other words, define-member-name gives +an external name a kind of package-private scope, but generalized from +packages to arbitrary binding scopes in Racket.

For example, the following fish% and pond% classes cooperate +via a get-depth method that is only accessible to the +cooperating classes:

(define-values (fish% pond%) ; two mutually recursive classes
  (let ()
    (define-member-name get-depth (generate-member-key))
    (define fish%
      (class ....
        (define my-depth ....)
        (define my-pond ....)
        (define/public (dive amt)
        (set! my-depth
              (min (+ my-depth amt)
                   (send my-pond get-depth))))))
    (define pond%
      (class ....
        (define current-depth ....)
        (define/public (get-depth) current-depth)))
    (values fish% pond%)))

External names are in a namespace that separates them from other Racket +names. This separate namespace is implicitly used for the method name in +send, for initialization-argument names in new, or for +the external name in a member definition. The special form +member-name-key provides access to the binding of an external name +in an arbitrary expression position: (member-name-key id) +produces the member-key binding of id in the current scope.

A member-key value is primarily used with a +define-member-name form. Normally, then, +(member-name-key id) captures the method key of id +so that it can be communicated to a use of define-member-name +in a different scope. This capability turns out to be useful for +generalizing mixins, as discussed next.

13.7 Mixins

Since class is an expression form instead of a top-level +declaration as in Smalltalk and Java, a class form can be +nested inside any lexical scope, including lambda. The result +is a mixin, i.e., a class extension that is parameterized +with respect to its superclass.

For example, we can parameterize the picky-fish% class over +its superclass to define picky-mixin:

(define (picky-mixin %)
  (class % (super-new)
    (define/override (grow amt) (super grow (* 3/4 amt)))))
(define picky-fish% (picky-mixin fish%))

Many small differences between Smalltalk-style classes and Racket +classes contribute to the effective use of mixins. In particular, the +use of define/override makes explicit that +picky-mixin expects a class with a grow method. If +picky-mixin is applied to a class without a grow +method, an error is signaled as soon as picky-mixin is +applied.

Similarly, a use of inherit enforces a “method existence” +requirement when the mixin is applied:

(define (hungry-mixin %)
  (class % (super-new)
    (inherit eat)
    (define/public (eat-more fish1 fish2)
      (eat fish1)
      (eat fish2))))

The advantage of mixins is that we can easily combine them to create +new classes whose implementation sharing does not fit into a +single-inheritance hierarchy—without the ambiguities associated with +multiple inheritance. Equipped with picky-mixin and +hungry-mixin, creating a class for a hungry, yet picky fish +is straightforward:

(define picky-hungry-fish%
  (hungry-mixin (picky-mixin fish%)))

The use of keyword initialization arguments is critical for the easy +use of mixins. For example, picky-mixin and +hungry-mixin can augment any class with suitable eat +and grow methods, because they do not specify initialization +arguments and add none in their super-new expressions:

(define person%
  (class object%
    (init name age)
    ....
    (define/public (eat food) ....)
    (define/public (grow amt) ....)))
(define child% (hungry-mixin (picky-mixin person%)))
(define oliver (new child% [name "Oliver"] [age 6]))

Finally, the use of external names for class members (instead of +lexically scoped identifiers) makes mixin use convenient. Applying +picky-mixin to person% works because the names +eat and grow match, without any a priori declaration +that eat and grow should be the same method in +fish% and person%. This feature is a potential +drawback when member names collide accidentally; some accidental +collisions can be corrected by limiting the scope external names, as +discussed in Controlling the Scope of External Names.

13.7.1 Mixins and Interfaces

Using implementation?, picky-mixin could require +that its base class implements grower-interface, which could +be implemented by both fish% and person%:

(define grower-interface (interface () grow))
(define (picky-mixin %)
  (unless (implementation? % grower-interface)
    (error "picky-mixin: not a grower-interface class"))
  (class % ....))

Another use of interfaces with a mixin is to tag classes generated by +the mixin, so that instances of the mixin can be recognized. In other +words, is-a? cannot work on a mixin represented as a +function, but it can recognize an interface (somewhat like a +specialization interface) that is consistently implemented +by the mixin. For example, classes generated by picky-mixin +could be tagged with picky-interface, enabling the +is-picky? predicate:

(define picky-interface (interface ()))
(define (picky-mixin %)
  (unless (implementation? % grower-interface)
    (error "picky-mixin: not a grower-interface class"))
  (class* % (picky-interface) ....))
(define (is-picky? o)
  (is-a? o picky-interface))
13.7.2 The mixin Form

To codify the lambda-plus-class pattern for +implementing mixins, including the use of interfaces for the domain +and range of the mixin, the class system provides a mixin +macro:

(mixin (interface-expr ...) (interface-expr ...)
  decl-or-expr ...)

The first set of interface-exprs determines the domain of the +mixin, and the second set determines the range. That is, the expansion +is a function that tests whether a given base class implements the +first sequence of interface-exprs and produces a class that +implements the second sequence of interface-exprs. Other +requirements, such as the presence of inherited methods in +the superclass, are then checked for the class expansion of +the mixin form. For example:

> (define choosy-interface (interface () choose?))
> (define hungry-interface (interface () eat))
> (define choosy-eater-mixin
    (mixin (choosy-interface) (hungry-interface)
      (inherit choose?)
      (super-new)
      (define/public (eat x)
        (cond
          [(choose? x)
           (printf "chomp chomp chomp on ~a.\n" x)]
          [else
           (printf "I'm not crazy about ~a.\n" x)]))))
> (define herring-lover%
    (class* object% (choosy-interface)
      (super-new)
      (define/public (choose? x)
        (regexp-match #px"^herring" x))))
> (define herring-eater% (choosy-eater-mixin herring-lover%))
> (define eater (new herring-eater%))
> (send eater eat "elderberry")

I'm not crazy about elderberry.

> (send eater eat "herring")

chomp chomp chomp on herring.

> (send eater eat "herring ice cream")

chomp chomp chomp on herring ice cream.

Mixins not only override methods and introduce public methods, they +can also augment methods, introduce augment-only methods, add an +overrideable augmentation, and add an augmentable override — all of +the things that a class can do (see Final, Augment, and Inner).

13.7.3 Parameterized Mixins

As noted in Controlling the Scope of External Names, external names can be bound with +define-member-name. This facility allows a mixin to be +generalized with respect to the methods that it defines and uses. For +example, we can parameterize hungry-mixin with respect to the +external member key for eat:

(define (make-hungry-mixin eat-method-key)
  (define-member-name eat eat-method-key)
  (mixin () () (super-new)
    (inherit eat)
    (define/public (eat-more x y) (eat x) (eat y))))

To obtain a particular hungry-mixin, we must apply this function to a +member key that refers to a suitable +eat method, which we can obtain using member-name-key:

((make-hungry-mixin (member-name-key eat))
 (class object% .... (define/public (eat x) 'yum)))

Above, we apply hungry-mixin to an anonymous class that provides +eat, but we can also combine it with a class that provides +chomp, instead:

((make-hungry-mixin (member-name-key chomp))
 (class object% .... (define/public (chomp x) 'yum)))

13.8 Traits

A trait is similar to a mixin, in that it encapsulates a set +of methods to be added to a class. A trait is different from a mixin +in that its individual methods can be manipulated with trait operators +such as trait-sum (merge the methods of two traits), trait-exclude +(remove a method from a trait), and trait-alias (add a copy of a +method with a new name; do not redirect any calls to the old name).

The practical difference between mixins and traits is that two traits +can be combined, even if they include a common method and even if +neither method can sensibly override the other. In that case, the +programmer must explicitly resolve the collision, usually by aliasing +methods, excluding methods, and merging a new trait that uses the +aliases.

Suppose our fish% programmer wants to define two class +extensions, spots and stripes, each of which +includes a get-color method. The fish’s spot color should not +override the stripe color nor vice versa; instead, a +spots+stripes-fish% should combine the two colors, which is +not possible if spots and stripes are implemented as +plain mixins. If, however, spots and stripes are +implemented as traits, they can be combined. First, we alias +get-color in each trait to a non-conflicting name. Second, +the get-color methods are removed from both and the traits +with only aliases are merged. Finally, the new trait is used to create +a class that introduces its own get-color method based on the +two aliases, producing the desired spots+stripes extension.

13.8.1 Traits as Sets of Mixins

One natural approach to implementing traits in Racket is as a set +of mixins, with one mixin per trait method. For example, we might +attempt to define the spots and stripes traits as follows, using +association lists to represent sets:

(define spots-trait
  (list (cons 'get-color
               (lambda (%) (class % (super-new)
                             (define/public (get-color)
                               'black))))))
(define stripes-trait
  (list (cons 'get-color
              (lambda (%) (class % (super-new)
                            (define/public (get-color)
                              'red))))))

A set representation, such as the above, allows trait-sum and +trait-exclude as simple manipulations; unfortunately, it does +not support the trait-alias operator. Although a mixin can be +duplicated in the association list, the mixin has a fixed method name, +e.g., get-color, and mixins do not support a method-rename +operation. To support trait-alias, we must parameterize the +mixins over the external method name in the same way that eat +was parameterized in Parameterized Mixins.

To support the trait-alias operation, spots-trait +should be represented as:

(define spots-trait
  (list (cons (member-name-key get-color)
              (lambda (get-color-key %)
                (define-member-name get-color get-color-key)
                (class % (super-new)
                  (define/public (get-color) 'black))))))

When the get-color method in spots-trait is aliased +to get-trait-color and the get-color method is +removed, the resulting trait is the same as

(list (cons (member-name-key get-trait-color)
            (lambda (get-color-key %)
              (define-member-name get-color get-color-key)
              (class % (super-new)
                (define/public (get-color) 'black)))))

To apply a trait T to a class C and obtain a derived +class, we use ((trait->mixin T) C). The trait->mixin +function supplies each mixin of T with the key for the mixin’s +method and a partial extension of C:

(define ((trait->mixin T) C)
  (foldr (lambda (m %) ((cdr m) (car m) %)) C T))

Thus, when the trait above is combined with other traits and then +applied to a class, the use of get-color becomes a reference +to the external name get-trait-color.

13.8.2 Inherit and Super in Traits

This first implementation of traits supports trait-alias, and it + supports a trait method that calls itself, but it does not support + trait methods that call each other. In particular, suppose that a spot-fish’s + market value depends on the color of its spots:

(define spots-trait
  (list (cons (member-name-key get-color) ....)
        (cons (member-name-key get-price)
              (lambda (get-price %) ....
                (class % ....
                  (define/public (get-price)
                    .... (get-color) ....))))))

In this case, the definition of spots-trait fails, because +get-color is not in scope for the get-price +mixin. Indeed, depending on the order of mixin application when the +trait is applied to a class, the get-color method may not be +available when get-price mixin is applied to the class. +Therefore adding an (inherit get-color) declaration to the +get-price mixin does not solve the problem.

One solution is to require the use of (send this get-color) in +methods such as get-price. This change works because +send always delays the method lookup until the method call is +evaluated. The delayed lookup is more expensive than a direct call, +however. Worse, it also delays checking whether a get-color method +even exists.

A second, effective, and efficient solution is to change the encoding +of traits. Specifically, we represent each method as a pair of mixins: +one that introduces the method and one that implements it. When a +trait is applied to a class, all of the method-introducing mixins are +applied first. Then the method-implementing mixins can use +inherit to directly access any introduced method.

(define spots-trait
  (list (list (local-member-name-key get-color)
              (lambda (get-color get-price %) ....
                (class % ....
                  (define/public (get-color) (void))))
              (lambda (get-color get-price %) ....
                (class % ....
                  (define/override (get-color) 'black))))
        (list (local-member-name-key get-price)
              (lambda (get-price get-color %) ....
                (class % ....
                  (define/public (get-price) (void))))
              (lambda (get-color get-price %) ....
                (class % ....
                  (inherit get-color)
                  (define/override (get-price)
                    .... (get-color) ....))))))

With this trait encoding, trait-alias adds a new method with +a new name, but it does not change any references to the old method.

13.8.3 The trait Form

The general-purpose trait pattern is clearly too complex for a +programmer to use directly, but it is easily codified in a +trait macro:

(trait trait-clause ...)

The ids in the optional inherit clause are available for direct +reference in the method exprs, and they must be supplied +either by other traits or the base class to which +the trait is ultimately applied.

Using this form in conjunction with trait operators such as +trait-sum, trait-exclude, trait-alias, and +trait->mixin, we can implement spots-trait and +stripes-trait as desired.

(define spots-trait
  (trait
    (define/public (get-color) 'black)
    (define/public (get-price) ... (get-color) ...)))
 
(define stripes-trait
  (trait
    (define/public (get-color) 'red)))
 
(define spots+stripes-trait
  (trait-sum
   (trait-exclude (trait-alias spots-trait
                               get-color get-spots-color)
                  get-color)
   (trait-exclude (trait-alias stripes-trait
                               get-color get-stripes-color)
                  get-color)
   (trait
     (inherit get-spots-color get-stripes-color)
     (define/public (get-color)
       .... (get-spots-color) .... (get-stripes-color) ....))))

13.9 Class Contracts

As classes are values, they can flow across contract boundaries, and we +may wish to protect parts of a given class with contracts. For this, +the class/c form is used. The class/c form has many +subforms, which describe two types of contracts on fields and methods: +those that affect uses via instantiated objects and those that affect +subclasses.

13.9.1 External Class Contracts

In its simplest form, class/c protects the public fields and methods +of objects instantiated from the contracted class. There is also an +object/c form that can be used to similarly protect the public fields +and methods of a particular object. Take the following definition of +animal%, which uses a public field for its size attribute:

(define animal%
  (class object%
    (super-new)
    (field [size 10])
    (define/public (eat food)
      (set! size (+ size (get-field size food))))))

For any instantiated animal%, accessing the size field +should return a positive number. Also, if the size field is set, +it should be assigned a positive number. Finally, the eat method +should receive an argument which is an object with a size field +that contains a positive number. To ensure these conditions, we will define +the animal% class with an appropriate contract:

(define positive/c (and/c number? positive?))
(define edible/c (object/c (field [size positive/c])))
(define/contract animal%
  (class/c (field [size positive/c])
           [eat (->m edible/c void?)])
  (class object%
    (super-new)
    (field [size 10])
    (define/public (eat food)
      (set! size (+ size (get-field size food))))))

Here we use ->m to describe the behavior of eat since we +do not need to describe any requirements for the this parameter. +Now that we have our contracted class, we can see that the contracts +on both size and eat are enforced:

> (define bob (new animal%))
> (set-field! size bob 3)
> (get-field size bob)

3

> (set-field! size bob 'large)

animal%: contract violation

  expected: positive/c

  given: 'large

  in: the size field in

      (class/c

       (eat

        (->m

         (object/c (field (size positive/c)))

         void?))

       (field (size positive/c)))

  contract from: (definition animal%)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:31:0

> (define richie (new animal%))
> (send bob eat richie)
> (get-field size bob)

13

> (define rock (new object%))
> (send bob eat rock)

eat: contract violation;

 no public field size

  in: the 1st argument of

      the eat method in

      (class/c

       (eat

        (->m

         (object/c (field (size positive/c)))

         void?))

       (field (size positive/c)))

  contract from: (definition animal%)

  contract on: animal%

  blaming: top-level

   (assuming the contract is correct)

  at: eval:31:0

> (define giant (new (class object% (super-new) (field [size 'large]))))
> (send bob eat giant)

eat: contract violation

  expected: positive/c

  given: 'large

  in: the size field in

      the 1st argument of

      the eat method in

      (class/c

       (eat

        (->m

         (object/c (field (size positive/c)))

         void?))

       (field (size positive/c)))

  contract from: (definition animal%)

  contract on: animal%

  blaming: top-level

   (assuming the contract is correct)

  at: eval:31:0

There are two important caveats for external class contracts. First, +external method contracts are only enforced when the target of dynamic +dispatch is the method implementation of the contracted class, which +lies within the contract boundary. Overriding that implementation, and +thus changing the target of dynamic dispatch, will mean that the contract +is no longer enforced for clients, since accessing the method no longer +crosses the contract boundary. Unlike external method contracts, external +field contracts are always enforced for clients of subclasses, since fields +cannot be overridden or shadowed.

Second, these contracts do not restrict subclasses of animal% +in any way. Fields and methods that are inherited and used by subclasses +are not checked by these contracts, and uses of the superclass’s methods +via super are also unchecked. The following example illustrates +both caveats:

(define large-animal%
  (class animal%
    (super-new)
    (inherit-field size)
    (set! size 'large)
    (define/override (eat food)
      (display "Nom nom nom") (newline))))

 

> (define elephant (new large-animal%))
> (send elephant eat (new object%))

Nom nom nom

> (get-field size elephant)

animal%: broke its own contract

  promised: positive/c

  produced: 'large

  in: the size field in

      (class/c

       (eat

        (->m

         (object/c (field (size positive/c)))

         void?))

       (field (size positive/c)))

  contract from: (definition animal%)

  blaming: (definition animal%)

   (assuming the contract is correct)

  at: eval:31:0

13.9.2 Internal Class Contracts

Notice that retrieving the size field from the object +elephant blames animal% for the contract violation. +This blame is correct, but unfair to the animal% class, +as we have not yet provided it with a method for protecting itself from +subclasses. To this end we add internal class contracts, which +provide directives to subclasses for how they may access and override +features of the superclass. This distinction between external and internal +class contracts allows for weaker contracts within the class hierarchy, where +invariants may be broken internally by subclasses but should be enforced +for external uses via instantiated objects.

As a simple example of what kinds of protection are available, we provide +an example aimed at the animal% class that uses all the applicable +forms:

(class/c (field [size positive/c])
         (inherit-field [size positive/c])
         [eat (->m edible/c void?)]
         (inherit [eat (->m edible/c void?)])
         (super [eat (->m edible/c void?)])
         (override [eat (->m edible/c void?)]))

This class contract not only ensures that objects of class animal% +are protected as before, but also ensure that subclasses of animal% +only store appropriate values within the size field and use +the implementation of size from animal% appropriately. +These contract forms only affect uses within the class hierarchy, and only +for method calls that cross the contract boundary.

That means that inherit will only affect subclass uses of a method +until a subclass overrides that method, and that override only +affects calls from the superclass into a subclass’s overriding implementation +of that method. Since these only affect internal uses, the override +form does not automatically enter subclasses into obligations when objects of +those classes are used. Also, use of override only makes sense, and +thus can only be used, for methods where no Beta-style augmentation has taken +place. The following example shows this difference:

(define/contract sloppy-eater%
  (class/c [eat (->m edible/c edible/c)])
  (begin
    (define/contract glutton%
      (class/c (override [eat (->m edible/c void?)]))
      (class animal%
        (super-new)
        (inherit eat)
        (define/public (gulp food-list)
          (for ([f food-list])
            (eat f)))))
    (class glutton%
      (super-new)
      (inherit-field size)
      (define/override (eat f)
        (let ([food-size (get-field size f)])
          (set! size (/ food-size 2))
          (set-field! size f (/ food-size 2))
          f)))))
> (define pig (new sloppy-eater%))
> (define slop1 (new animal%))
> (define slop2 (new animal%))
> (define slop3 (new animal%))
> (send pig eat slop1)

(object:animal% ...)

> (get-field size slop1)

5

> (send pig gulp (list slop1 slop2 slop3))

eat: contract violation

  expected: void?

  given: (object:animal% ...)

  in: the range of

      the eat method in

      (class/c

       (override (eat

                  (->m

                   (object/c

                    (field (size positive/c)))

                   void?))))

  contract from: (definition glutton%)

  contract on: glutton%

  blaming: (definition sloppy-eater%)

   (assuming the contract is correct)

  at: eval:47:0

In addition to the internal class contract forms shown here, there are +similar forms for Beta-style augmentable methods. The inner +form describes to the subclass what is expected from augmentations of +a given method. Both augment and augride tell the +subclass that the given method is a method which has been augmented and +that any calls to the method in the subclass will dynamically +dispatch to the appropriate implementation in the superclass. Such +calls will be checked according to the given contract. The two forms +differ in that use of augment signifies that subclasses can +augment the given method, whereas use of augride signifies that +subclasses must override the current augmentation instead.

This means that not all forms can be used at the same time. Only one of the +override, augment, and augride forms can be used +for a given method, and none of these forms can be used if the given method +has been finalized. In addition, super can be specified for a given +method only if augride or override can be specified. +Similarly, inner can be specified only if augment or +augride can be specified.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/cmdline-tools.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/cmdline-tools.html new file mode 100644 index 00000000..8d030f4d --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/cmdline-tools.html @@ -0,0 +1,27 @@ + +24.1 Command-Line Tools
8.6

24.1 Command-Line Tools

Racket provides, as part of its standard distribution, a number of +command-line tools that can make racketeering more pleasant.

24.1.1 Compilation and Configuration: raco

The raco (short for “Racket command”) program +provides a command-line interface to many additional tools for +compiling Racket programs and maintaining a Racket installation.

  • raco make compiles Racket source to bytecode.

    For example, if you have a program "take-over-world.rkt" and +you’d like to compile it to bytecode, along with all of its +dependencies, so that it loads more quickly, then run

      raco make take-over-the-world.rkt

    The bytecode file is written as "take-over-the-world_rkt.zo" +in a "compiled" subdirectory; ".zo" +is the file suffix for a bytecode file.

  • raco setup manages a Racket installation, including +manually installed packages.

    For example, if you create your own library collection +called "take-over", and you’d like to build all bytecode and +documentation for the collection, then run

      raco setup take-over

  • raco pkg manages packages that can be installed +through the Racket package manager.

    For example, to see the list of installed packages run:

      raco pkg show

    To install a new package named <package-name> run:

      raco pkg install <package-name>

    See Package Management in Racket for more details +about package management.

For more information on raco, see raco: Racket Command-Line Tools.

24.1.2 Interactive evaluation

The Racket REPL provides everything you expect from a modern interactive +environment. For example, it provides an ,enter command to have a +REPL that runs in the context of a given module, and an ,edit command +to invoke your editor (as specified by the EDITOR environment +variable) on the file you entered. A ,drracket command makes it easy +to use your favorite editor to write code, and still have DrRacket at hand to +try things out.

For more information, see XREPL: eXtended REPL.

24.1.3 Shell completion

Shell auto-completion for bash and zsh is available in +"share/pkgs/shell-completion/racket-completion.bash" and +"share/pkgs/shell-completion/racket-completion.zsh", +respectively. +To enable it, just run the appropriate file from your .bashrc or +your .zshrc.

The "shell-completion" collection is only available in the Racket Full +distribution. The completion scripts are also available +online.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/code-inspectors_protect.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/code-inspectors_protect.html new file mode 100644 index 00000000..3e3aa0c6 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/code-inspectors_protect.html @@ -0,0 +1,34 @@ + +15.4 Code Inspectors for Trusted and Untrusted Code

15.4 Code Inspectors for Trusted and Untrusted Code

Code inspectors provide the mechanism for determining which +modules are trusted to use functions like module->namespace +or unsafe modules like ffi/unsafe. When a module is declared, +the value of current-code-inspector is associated to the +module declaration. When a module is instantiated (i.e., when the body +of the declaration is actually executed), a sub-inspector is created +to guard the module’s exports. Access to the module’s protected +exports requires a code inspector that is stronger (i.e., higher in +the inspector hierarchy) than the module’s instantiation inspector; +note that a module’s declaration inspector is always stronger than its +instantiation inspector, so modules are declared with the same code +inspector can access each other’s exports.

To distinguish between trusted an untrusted code, load trusted code +first, then set current-code-inspector to the result of +(make-inspector (current-code-inspector)) to install a weaker +inspector, and finally load untrusted code with the weaker inspector +in place. The weaker inspector should stay in place when any untrusted +code is run. If necessary, trusted code can restore the original +inspector temporarily during the dynamic extent of trusted code (as +long as it does not call back into untrusted code).

Syntax-object constants within a module, such as literal identifiers +in a template, retain the inspector of their source module. In this +way, a macro from a trusted module can be used within an untrusted +module, and protected identifiers in the macro expansion still +work, even through they ultimately appear in an untrusted module. To +prevent abuse of identifiers by extracting them from expanded code, +functions like local-expand are protected, and +functions like expand return tainted syntax if not +given a sufficiently powerful inspector.

Compiled code from a ".zo" file is inherently untrustworthy, +unfortunately, since it can be synthesized by means other than +compile. When compiled code is written to a ".zo" +file, syntax-object constants within the compiled code lose their +inspectors. All syntax-object constants within compiled code acquire +the enclosing module’s declaration-time inspector when the code is +loaded.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/concurrency.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/concurrency.html new file mode 100644 index 00000000..71496c3e --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/concurrency.html @@ -0,0 +1,101 @@ + +18 Concurrency and Synchronization

18 Concurrency and Synchronization

Racket provides concurrency in the form of +threads, and it provides a general sync function +that can be used to synchronize both threads and other implicit forms of +concurrency, such as ports.

Threads run concurrently in the sense that one thread can preempt +another without its cooperation, but threads do not run in parallel in +the sense of using multiple hardware processors. See +Parallelism for information on parallelism in Racket.

18.1 Threads

To execute a procedure concurrently, use thread. The +following example creates two new threads from the main thread:

(displayln "This is the original thread")
(thread (lambda () (displayln "This is a new thread.")))
(thread (lambda () (displayln "This is another new thread.")))

The next example creates a new thread that would otherwise loop forever, but +the main thread uses sleep to pause itself for 2.5 seconds, then +uses kill-thread to terminate the worker thread:

(define worker (thread (lambda ()
                         (let loop ()
                           (displayln "Working...")
                           (sleep 0.2)
                           (loop)))))
(sleep 2.5)
(kill-thread worker)

In DrRacket, the main thread keeps going until the Stop button is +clicked, so in DrRacket the thread-wait is not necessary.

If the main thread finishes or is killed, the application exits, even if +other threads are still running. A thread can use thread-wait to +wait for another thread to finish. Here, the main thread uses +thread-wait to make sure the worker thread finishes before the main +thread exits:

(define worker (thread
                 (lambda ()
                   (for ([i 100])
                     (printf "Working hard... ~a~n" i)))))
(thread-wait worker)
(displayln "Worker finished")

18.2 Thread Mailboxes

Each thread has a mailbox for receiving messages. The thread-send function +asynchronously sends a message to another thread’s mailbox, while +thread-receive returns the oldest message from the current +thread’s mailbox, blocking to wait for a message if necessary. In the +following example, the main thread sends data to the worker thread to be +processed, then sends a 'done message when there is no more data and +waits for the worker thread to finish.

(define worker-thread (thread
                       (lambda ()
                         (let loop ()
                           (match (thread-receive)
                             [(? number? num)
                              (printf "Processing ~a~n" num)
                              (loop)]
                             ['done
                              (printf "Done~n")])))))
(for ([i 20])
  (thread-send worker-thread i))
(thread-send worker-thread 'done)
(thread-wait worker-thread)

In the next example, the main thread delegates work to multiple arithmetic +threads, then waits to receive the results. The arithmetic threads process work +items then send the results to the main thread.

(define (make-arithmetic-thread operation)
  (thread (lambda ()
            (let loop ()
              (match (thread-receive)
                [(list oper1 oper2 result-thread)
                 (thread-send result-thread
                              (format "~a ~a ~a = ~a"
                                      oper1
                                      (object-name operation)
                                      oper2
                                      (operation oper1 oper2)))
                 (loop)])))))
 
(define addition-thread (make-arithmetic-thread +))
(define subtraction-thread (make-arithmetic-thread -))
 
(define worklist '((+ 1 1) (+ 2 2) (- 3 2) (- 4 1)))
(for ([item worklist])
  (match item
    [(list '+ o1 o2)
     (thread-send addition-thread
                  (list o1 o2 (current-thread)))]
    [(list '- o1 o2)
     (thread-send subtraction-thread
                  (list o1 o2 (current-thread)))]))
 
(for ([i (length worklist)])
  (displayln (thread-receive)))

18.3 Semaphores

Semaphores facilitate synchronized access to an arbitrary shared resource. +Use semaphores when multiple threads must perform non-atomic operations on a +single resource.

In the following example, multiple threads print to standard output +concurrently. Without synchronization, a line printed by one thread might +appear in the middle of a line printed by another thread. By using a semaphore +initialized with a count of 1, only one thread will print at a time. +The semaphore-wait function blocks until the semaphore’s internal counter is +non-zero, then decrements the counter and returns. The semaphore-post function +increments the counter so that another thread can unblock and then print.

(define output-semaphore (make-semaphore 1))
(define (make-thread name)
  (thread (lambda ()
            (for [(i 10)]
              (semaphore-wait output-semaphore)
              (printf "thread ~a: ~a~n" name i)
              (semaphore-post output-semaphore)))))
(define threads
  (map make-thread '(A B C)))
(for-each thread-wait threads)

The pattern of waiting on a semaphore, working, and posting to the +semaphore can also be expressed using +call-with-semaphore,which has the advantage of posting to the +semaphore if control escapes (e.g., due to an exception):

(define output-semaphore (make-semaphore 1))
(define (make-thread name)
  (thread (lambda ()
            (for [(i 10)]
              (call-with-semaphore
               output-semaphore
               (lambda ()
                (printf "thread ~a: ~a~n" name i)))))))
(define threads
  (map make-thread '(A B C)))
(for-each thread-wait threads)

Semaphores are a low-level technique. Often, a better solution is to restrict +resource access to a single thread. For example, synchronizing access to +standard output might be better accomplished by having a dedicated thread for +printing output.

18.4 Channels

Channels synchronize two threads while a value is passed from one thread to the +other. Unlike a thread mailbox, multiple threads can get items from a single +channel, so channels should be used when multiple threads need to consume items +from a single work queue.

In the following example, the main thread adds items to a channel using +channel-put, while multiple worker threads consume those items using +channel-get. Each call to either procedure blocks until another +thread calls the other procedure with the same channel. The workers process +the items and then pass their results to the result thread via the result-channel.

(define result-channel (make-channel))
(define result-thread
        (thread (lambda ()
                  (let loop ()
                    (display (channel-get result-channel))
                    (loop)))))
 
(define work-channel (make-channel))
(define (make-worker thread-id)
  (thread
   (lambda ()
     (let loop ()
       (define item (channel-get work-channel))
       (case item
         [(DONE)
          (channel-put result-channel
                       (format "Thread ~a done\n" thread-id))]
         [else
          (channel-put result-channel
                       (format "Thread ~a processed ~a\n"
                               thread-id
                               item))
          (loop)])))))
(define work-threads (map make-worker '(1 2)))
(for ([item '(A B C D E F G H DONE DONE)])
  (channel-put work-channel item))
(for-each thread-wait work-threads)
(channel-put result-channel "") ; waits until result-thread has printed all other output

18.5 Buffered Asynchronous Channels

Buffered asynchronous channels are similar to the channels described above, but +the “put” operation of asynchronous channels does not block—unless the given +channel was created with a buffer limit and the limit has been reached. The +asynchronous-put operation is therefore somewhat similar to +thread-send, but unlike thread mailboxes, asynchronous channels allow +multiple threads to consume items from a single channel.

In the following +example, the main thread adds items to the work channel, which holds a maximum +of three items at a time. The worker threads process items from this channel and +then send results to the print thread.

(require racket/async-channel)
 
(define print-thread
  (thread (lambda ()
            (let loop ()
              (displayln (thread-receive))
              (loop)))))
(define (safer-printf . items)
  (thread-send print-thread
               (apply format items)))
 
(define work-channel (make-async-channel 3))
(define (make-worker-thread thread-id)
  (thread
   (lambda ()
     (let loop ()
       (define item (async-channel-get work-channel))
       (safer-printf "Thread ~a processing item: ~a" thread-id item)
       (loop)))))
 
(for-each make-worker-thread '(1 2 3))
(for ([item '(a b c d e f g h i j k l m)])
  (async-channel-put work-channel item))

Note the above example lacks any synchronization to verify that all items were +processed. If the main thread were to exit without such synchronization, it is +possible that the worker threads will not finish processing some items or the +print thread will not print all items.

18.6 Synchronizable Events and sync

There are other ways to synchronize threads. The sync function allows +threads to coordinate via synchronizable events. +Many values double as events, allowing a uniform way to synchronize threads +using different types. Examples of events include channels, ports, threads, +and alarms. This section builds up a number of examples that show how +the combination of events, threads, and sync (along with recursive functions) +allow you to implement arbitrarily sophisticated communication protocols +to coordinate concurrent parts of a program.

In the next example, a channel and an alarm are used as synchronizable events. +The workers sync on both so that they can process channel items until the +alarm is activated. The channel items are processed, and then results are sent back +to the main thread.

(define main-thread (current-thread))
(define alarm (alarm-evt (+ 3000 (current-inexact-milliseconds))))
(define channel (make-channel))
(define (make-worker-thread thread-id)
  (thread
   (lambda ()
     (define evt (sync channel alarm))
     (cond
       [(equal? evt alarm)
        (thread-send main-thread 'alarm)]
       [else
        (thread-send main-thread
                     (format "Thread ~a received ~a"
                             thread-id
                             evt))]))))
(make-worker-thread 1)
(make-worker-thread 2)
(make-worker-thread 3)
(channel-put channel 'A)
(channel-put channel 'B)
(let loop ()
  (match (thread-receive)
    ['alarm
     (displayln "Done")]
    [result
     (displayln result)
     (loop)]))

The next example shows a function for use in a simple TCP echo server. The +function uses sync/timeout to synchronize on input from the given port +or a message in the thread’s mailbox. The first argument to sync/timeout +specifies the maximum number of seconds it should wait on the given events. The +read-line-evt function returns an event that is ready when a line of input is +available in the given input port. The result of thread-receive-evt is ready when +thread-receive would not block. In a real application, the messages +received in the thread mailbox could be used for control messages, etc.

(define (serve in-port out-port)
  (let loop []
    (define evt (sync/timeout 2
                              (read-line-evt in-port 'any)
                              (thread-receive-evt)))
    (cond
      [(not evt)
       (displayln "Timed out, exiting")
       (tcp-abandon-port in-port)
       (tcp-abandon-port out-port)]
      [(string? evt)
       (fprintf out-port "~a~n" evt)
       (flush-output out-port)
       (loop)]
      [else
       (printf "Received a message in mailbox: ~a~n"
               (thread-receive))
       (loop)])))

The serve function is used in the following example, which +starts a server thread and a client thread that communicate over TCP. The +client prints three lines to the server, which echoes them back. The client’s +copy-port call blocks until EOF is received. The server times out after +two seconds, closing the ports, which allows copy-port to finish and the +client to exit. The main thread uses thread-wait to wait for the +client thread to exit (since, without thread-wait, the main thread might +exit before the other threads are finished).

(define port-num 4321)
(define (start-server)
  (define listener (tcp-listen port-num))
  (thread
    (lambda ()
      (define-values [in-port out-port] (tcp-accept listener))
      (serve in-port out-port))))
 
(start-server)
 
(define client-thread
  (thread
   (lambda ()
     (define-values [in-port out-port] (tcp-connect "localhost" port-num))
     (display "first\nsecond\nthird\n" out-port)
     (flush-output out-port)
     ; copy-port will block until EOF is read from in-port
     (copy-port in-port (current-output-port)))))
 
(thread-wait client-thread)

Sometimes, you want to attach result behavior directly to the event passed to +sync. In the following example, the worker thread synchronizes on three +channels, but each channel must be handled differently. Using +handle-evt associates a callback with the given event. When +sync selects the given event, it calls the callback to generate the +synchronization result, rather than using the event’s normal synchronization +result. Since the event is handled in the callback, there is no need to +dispatch on the return value of sync.

(define add-channel (make-channel))
(define multiply-channel (make-channel))
(define append-channel (make-channel))
 
(define (work)
  (let loop ()
    (sync (handle-evt add-channel
                      (lambda (list-of-numbers)
                        (printf "Sum of ~a is ~a~n"
                                list-of-numbers
                                (apply + list-of-numbers))))
          (handle-evt multiply-channel
                      (lambda (list-of-numbers)
                        (printf "Product of ~a is ~a~n"
                                list-of-numbers
                                (apply * list-of-numbers))))
          (handle-evt append-channel
                      (lambda (list-of-strings)
                        (printf "Concatenation of ~s is ~s~n"
                                list-of-strings
                                (apply string-append list-of-strings)))))
    (loop)))
 
(define worker (thread work))
(channel-put add-channel '(1 2))
(channel-put multiply-channel '(3 4))
(channel-put multiply-channel '(5 6))
(channel-put add-channel '(7 8))
(channel-put append-channel '("a" "b"))

The result of handle-evt invokes its callback in tail position +with respect to sync, so it is safe to +use recursion as in the following example.

(define control-channel (make-channel))
(define add-channel (make-channel))
(define subtract-channel (make-channel))
(define (work state)
  (printf "Current state: ~a~n" state)
  (sync (handle-evt add-channel
                    (lambda (number)
                      (printf "Adding: ~a~n" number)
                      (work (+ state number))))
        (handle-evt subtract-channel
                    (lambda (number)
                      (printf "Subtracting: ~a~n" number)
                      (work (- state number))))
        (handle-evt control-channel
                    (lambda (kill-message)
                      (printf "Done~n")))))
 
(define worker (thread (lambda () (work 0))))
(channel-put add-channel 2)
(channel-put subtract-channel 3)
(channel-put add-channel 4)
(channel-put add-channel 5)
(channel-put subtract-channel 1)
(channel-put control-channel 'done)
(thread-wait worker)

The wrap-evt function is like handle-evt, except +that its handler is not called in tail position with respect to +sync. At the same time, wrap-evt disables break +exceptions during its handler’s invocation.

18.7 Building Your Own Synchronization Patterns

Events also allow you to encode many different communication +patterns between multiple concurrent parts of a program. One +common such pattern is producer-consumer. Here is a way to +implement a variation on it using the above ideas. Generally +speaking, these communication patterns are implemented via +a server loop that uses sync to wait for any +number of different possibilities to occur and then +reacts to them, updating some local state.

(define/contract (produce x)
  (-> any/c void?)
  (channel-put producer-chan x))

 

(define/contract (consume)
  (-> any/c)
  (channel-get consumer-chan))

 

; private state and server loop

 

(define producer-chan (make-channel))
(define consumer-chan (make-channel))
(void
 (thread
  (λ ()
    ; the items variable holds the items that
    ; have been produced but not yet consumed
    (let loop ([items '()])
      (sync
 
       ; wait for production
       (handle-evt
        producer-chan
        (λ (i)
          ; if that event was chosen,
          ; we add an item to our list
          ; and go back around the loop
          (loop (cons i items))))
 
       ; wait for consumption, but only
       ; if we have something to produce
       (handle-evt
        (if (null? items)
            never-evt
            (channel-put-evt consumer-chan (car items)))
        (λ (_)
          ; if that event was chosen,
          ; we know that the first item item
          ; has been consumed; drop it and
          ; and go back around the loop
          (loop (cdr items)))))))))

 

; an example (non-deterministic) interaction
> (void
   (thread (λ () (sleep (/ (random 10) 100)) (produce 1)))
   (thread (λ () (sleep (/ (random 10) 100)) (produce 2))))
> (list (consume) (consume))

'(2 1)

It is possible to build up more complex synchronization patterns. Here is +a silly example where we extend the producer consumer with an operation +to wait until at least a certain number of items have been produced.

(define/contract (produce x)
  (-> any/c void?)
  (channel-put producer-chan x))
 
(define/contract (consume)
  (-> any/c)
  (channel-get consumer-chan))
 
(define/contract (wait-at-least n)
  (-> natural? void?)
  (define c (make-channel))
  ; we send a new channel over to the
  ; main loop so that we can wait here
  (channel-put wait-at-least-chan (cons n c))
  (channel-get c))

 

(define producer-chan (make-channel))
(define consumer-chan (make-channel))
(define wait-at-least-chan (make-channel))
(void
 (thread
  (λ ()
    (let loop ([items '()]
               [total-items-seen 0]
               [waiters '()])
      ; instead of waiting on just production/
      ; consumption now we wait to learn about
      ; threads that want to wait for a certain
      ; number of elements to be reached
      (apply
       sync
       (handle-evt
        producer-chan
        (λ (i) (loop (cons i items)
                     (+ total-items-seen 1)
                     waiters)))
       (handle-evt
        (if (null? items)
            never-evt
            (channel-put-evt consumer-chan (car items)))
        (λ (_) (loop (cdr items) total-items-seen waiters)))
 
       ; wait for threads that are interested
       ; the number of items produced
       (handle-evt
        wait-at-least-chan
        (λ (waiter) (loop items total-items-seen (cons waiter waiters))))
 
       ; for each thread that wants to wait,
       (for/list ([waiter (in-list waiters)])
         ; we check to see if there has been enough
         ; production
         (cond
           [(>= (car waiter) total-items-seen)
            ; if so, we send a message back on the channel
            ; and continue the loop without that item
            (handle-evt
             (channel-put-evt
              (cdr waiter)
              (void))
             (λ (_) (loop items total-items-seen (remove waiter waiters))))]
           [else
            ; otherwise, we just ignore that one
            never-evt])))))))

 

; an example (non-deterministic) interaction
> (define thds
    (for/list ([i (in-range 10)])
      (thread (λ ()
                (produce i)
                (wait-at-least 10)
                (display (format "~a -> ~a\n" i (consume)))))))
> (for ([thd (in-list thds)])
    (thread-wait thd))

0 -> 2

3 -> 3

9 -> 1

8 -> 0

6 -> 9

2 -> 8

5 -> 7

4 -> 6

7 -> 5

1 -> 4

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/conditionals.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/conditionals.html new file mode 100644 index 00000000..aa76f1bc --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/conditionals.html @@ -0,0 +1,47 @@ + +4.7 Conditionals

4.7 Conditionals

Most functions used for branching, such as < and +string?, produce either #t or #f. Racket’s +branching forms, however, treat any value other than #f as +true. We say a true value to mean any value other than +#f.

This convention for “true value” meshes well with protocols where +#f can serve as failure or to indicate that an optional value +is not supplied. (Beware of overusing this trick, and remember that an +exception is usually a better mechanism to report failure.)

For example, the member function serves double duty; it can +be used to find the tail of a list that starts with a particular item, +or it can be used to simply check whether an item is present in a +list:

> (member "Groucho" '("Harpo" "Zeppo"))

#f

> (member "Groucho" '("Harpo" "Groucho" "Zeppo"))

'("Groucho" "Zeppo")

> (if (member "Groucho" '("Harpo" "Zeppo"))
      'yep
      'nope)

'nope

> (if (member "Groucho" '("Harpo" "Groucho" "Zeppo"))
      'yep
      'nope)

'yep

4.7.1 Simple Branching: if

+Conditionals: if, cond, and, and or in The Racket Reference also documents if.

In an if form,

(if test-expr then-expr else-expr)

the test-expr is always evaluated. If it produces any value +other than #f, then then-expr is +evaluated. Otherwise, else-expr is evaluated.

An if form must have both a then-expr and an +else-expr; the latter is not optional. To perform (or skip) +side-effects based on a test-expr, use when or +unless, which we describe later in Sequencing.

4.7.2 Combining Tests: and and or

+Conditionals: if, cond, and, and or in The Racket Reference also documents and and or.

Racket’s and and or are syntactic forms, rather than +functions. Unlike a function, the and and or forms +can skip evaluation of later expressions if an earlier one determines +the answer.

(and expr ...)

An and form produces #f if any of its exprs +produces #f. Otherwise, it produces the value of its last +expr. As a special case, (and) produces +#t.

(or expr ...)

The or form produces #f if all of its +exprs produce #f. Otherwise, it produces the first +non-#f value from its exprs. As a special case, +(or) produces #f.

Examples:
> (define (got-milk? lst)
    (and (not (null? lst))
         (or (eq? 'milk (car lst))
             (got-milk? (cdr lst))))) ; recurs only if needed
> (got-milk? '(apple banana))

#f

> (got-milk? '(apple milk banana))

#t

If evaluation reaches the last expr of an and or +or form, then the expr’s value directly determines +the and or or result. Therefore, the last +expr is in tail position, which means that the above +got-milk? function runs in constant space.

+Tail Recursion introduces tail calls and tail positions.

4.7.3 Chaining Tests: cond

The cond form chains a series of tests to select a result +expression. To a first approximation, the syntax of cond is +as follows:

+Conditionals: if, cond, and, and or in The Racket Reference also documents cond.

(cond [test-expr body ...+]
      ...)

Each test-expr is evaluated in order. If it produces +#f, the corresponding bodys are ignored, and +evaluation proceeds to the next test-expr. As soon as a +test-expr produces a true value, the associated bodys +are evaluated to produce the result for the cond form, and no +further test-exprs are evaluated.

The last test-expr in a cond can be replaced by +else. In terms of evaluation, else serves as a +synonym for #t, but it clarifies that the last clause is +meant to catch all remaining cases. If else is not used, then +it is possible that no test-exprs produce a true value; in +that case, the result of the cond expression is +#<void>.

Examples:
> (cond
   [(= 2 3) (error "wrong!")]
   [(= 2 2) 'ok])

'ok

> (cond
   [(= 2 3) (error "wrong!")])
> (cond
   [(= 2 3) (error "wrong!")]
   [else 'ok])

'ok

(define (got-milk? lst)
  (cond
    [(null? lst) #f]
    [(eq? 'milk (car lst)) #t]
    [else (got-milk? (cdr lst))]))

 

> (got-milk? '(apple banana))

#f

> (got-milk? '(apple milk banana))

#t

The full syntax of cond includes two more kinds of clauses:

(cond cond-clause ...)
 
cond-clause = [test-expr then-body ...+]
  | [else then-body ...+]
  | [test-expr => proc-expr]
  | [test-expr]

The => variant captures the true result of its +test-expr and passes it to the result of the +proc-expr, which must be a function of one argument.

Examples:
> (define (after-groucho lst)
    (cond
      [(member "Groucho" lst) => cdr]
      [else (error "not there")]))
> (after-groucho '("Harpo" "Groucho" "Zeppo"))

'("Zeppo")

> (after-groucho '("Harpo" "Zeppo"))

not there

A clause that includes only a test-expr is rarely used. It +captures the true result of the test-expr, and simply +returns the result for the whole cond expression.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contract-boundaries.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contract-boundaries.html new file mode 100644 index 00000000..4dfc044d --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contract-boundaries.html @@ -0,0 +1,44 @@ + +7.1 Contracts and Boundaries

7.1 Contracts and Boundaries

Like a contract between two business partners, a software +contract is an agreement between two parties. The agreement +specifies obligations and guarantees for each “product” +(or value) that is handed from one party to the other.

A contract thus establishes a boundary between the two parties. Whenever a +value crosses this boundary, the contract monitoring system performs contract +checks, making sure the partners abide by the established contract.

In this spirit, Racket encourages contracts mainly at module +boundaries. Specifically, programmers may attach contracts to +provide clauses and thus impose constraints and promises on the use +of exported values. For example, the export specification +
#lang racket
 
(provide (contract-out [amount positive?]))
 
(define amount ...)

promises to all clients of the above module that the value of amount will +always be a positive number. The contract system monitors +the module’s obligation carefully. Every time a client +refers to amount, the monitor checks that the value +of amount is indeed a positive number.

The contracts library is built into the Racket language, but +if you wish to use racket/base, you can explicitly +require the contracts library like this:

#lang racket/base
(require racket/contract) ; now we can write contracts
 
(provide (contract-out [amount positive?]))
 
(define amount ...)
7.1.1 Contract Violations

If we bind amount to a number that is not positive,

#lang racket
 
(provide (contract-out [amount positive?]))
 
(define amount 0)

then, when the module is required, the monitoring +system signals a violation of the contract and +blames the module for breaking its promises.

An even bigger mistake would be to bind amount +to a non-number value:

#lang racket
 
(provide (contract-out [amount positive?]))
 
(define amount 'amount)

In this case, the monitoring system will apply +positive? to a symbol, but positive? +reports an error, because its domain is only numbers. To +make the contract capture our intentions for all Racket +values, we can ensure that the value is both a number and is +positive, combining the two contracts with and/c:

(provide (contract-out [amount (and/c number? positive?)]))

7.1.2 Experimenting with Contracts and Modules

All of the contracts and modules in this chapter (excluding those just +following) are written using the standard #lang syntax for +describing modules. Since modules serve as the boundary between +parties in a contract, examples involve multiple modules.

To experiment with multiple modules within a single module or within +DrRacket’s definitions area, use +Racket’s submodules. For example, try the example earlier in +this section like this:

#lang racket
 
(module+ server
  (provide (contract-out [amount (and/c number? positive?)]))
  (define amount 150))
 
(module+ main
  (require (submod ".." server))
  (+ amount 10))

Each of the modules and their contracts are wrapped in parentheses +with the module+ keyword at the front. The first form after +module is the name of the module to be used in a subsequent +require statement (where each reference through a +require prefixes the name with "..").

7.1.3 Experimenting with Nested Contract Boundaries

In many cases, it makes sense to attach contracts at module boundaries. +It is often convenient, however, to be able to use contracts at +a finer granularity than modules. The define/contract +form enables this kind of use:

#lang racket
 
(define/contract amount
  (and/c number? positive?)
  150)
 
(+ amount 10)

In this example, the define/contract form establishes a contract +boundary between the definition of amount and its surrounding +context. In other words, the two parties here are the definition and +the module that contains it.

Forms that create these nested contract boundaries can sometimes +be subtle to use because they may have unexpected performance implications +or blame a party that may seem unintuitive. These subtleties are explained +in Using define/contract and -> and Contract boundaries and define/contract.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contract-func.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contract-func.html new file mode 100644 index 00000000..d56d9054 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contract-func.html @@ -0,0 +1,132 @@ + +7.2 Simple Contracts on Functions

7.2 Simple Contracts on Functions

A mathematical function has a domain and a +range. The domain indicates the kind of values that the +function can accept as arguments, and the range indicates the kind of +values that it produces. The conventional notation for describing a +function with its domain and range is

f : A -> B

where A is the domain of the function and B is the +range.

Functions in a programming language have domains and ranges, too, and +a contract can ensure that a function receives only values in its +domain and produces only values in its range. A -> creates +such a contract for a function. The forms after a -> specify +contracts for the domains and finally a contract for the range.

Here is a module that might represent a bank account:

#lang racket
 
(provide (contract-out
          [deposit (-> number? any)]
          [balance (-> number?)]))
 
(define amount 0)
(define (deposit a) (set! amount (+ amount a)))
(define (balance) amount)

The module exports two functions:

  • deposit, which accepts a number and returns some value +that is not specified in the contract, and

  • balance, which returns a number indicating the current +balance of the account.

When a module exports a function, it establishes two channels of +communication between itself as a “server” and the “client” module +that imports the function. If the client module calls the function, it +sends a value into the server module. Conversely, if such a function +call ends and the function returns a value, the server module sends a +value back to the client module. This client–server distinction is +important, because when something goes wrong, one or the other of the +parties is to blame.

If a client module were to apply deposit to 'millions, +it would violate the contract. The contract-monitoring system would +catch this violation and blame the client for breaking the contract with +the above module. In contrast, if the balance function were +to return 'broke, the contract-monitoring system +would blame the server module.

A -> by itself is not a contract; it is a contract +combinator, which combines other contracts to form a contract.

7.2.1 Styles of ->

If you are used to mathematical functions, you may prefer a contract + arrow to appear between the domain and the range of a function, not + at the beginning. If you have read How to Design Programs, you have seen this many + times. Indeed, you may have seen contracts such as these in other + people’s code:

(provide (contract-out
          [deposit (number? . -> . any)]))

If a Racket S-expression contains two dots with a symbol in the middle, +the reader re-arranges the S-expression and place the symbol at the front, +as described in Lists and Racket Syntax. Thus,

(number? . -> . any)

is just another way of writing

(-> number? any)

7.2.2 Using define/contract and ->

The define/contract form introduced in Experimenting with Nested Contract Boundaries can +also be used to define functions that come with a contract. For example,

(define/contract (deposit amount)
  (-> number? any)
  ; implementation goes here
  ....)

which defines the deposit function with the contract from earlier. +Note that this has two potentially important impacts on the use of +deposit:

  1. The contract will be checked on any call to deposit +that is outside of the definition of deposit – +even those inside the module in which it is defined. Because +there may be many calls inside the module, this checking may cause +the contract to be checked too often, which could lead to +a performance degradation. This is especially true if the function +is called repeatedly from a loop.

  2. In some situations, a function may be written to accept a more +lax set of inputs when called by other code in the same module. +For such use cases, the contract boundary established by +define/contract is too strict.

7.2.3 any and any/c

The any contract used for deposit matches any kind +of result, and it can only be used in the range position of a function +contract. Instead of any above, we could use the more +specific contract void?, which says that the function will +always return the (void) value. The void? contract, +however, would require the contract monitoring system to check the +return value every time the function is called, even though the +“client” module can’t do much with the value. In contrast, +any tells the monitoring system not to check the +return value, it tells a potential client that the “server” module +makes no promises at all about the function’s return value, +even whether it is a single value or multiple values.

The any/c contract is similar to any, in that it +makes no demands on a value. Unlike any, any/c +indicates a single value, and it is suitable for use as an argument +contract. Using any/c as a range contract imposes a check +that the function produces a single value. That is,

(-> integer? any)

describes a function that accepts an integer and returns any number of +values, while

(-> integer? any/c)

describes a function that accepts an integer and produces a single +result (but does not say anything more about the result). The function

(define (f x) (values (+ x 1) (- x 1)))

matches (-> integer? any), but not (-> integer? any/c).

Use any/c as a result contract when it is particularly +important to promise a single result from a function. Use any +when you want to promise as little as possible (and incur as little +checking as possible) for a function’s result.

7.2.4 Rolling Your Own Contracts

The deposit function adds the given number to the value of +amount. While the function’s contract prevents clients from +applying it to non-numbers, the contract still allows them to apply +the function to complex numbers, negative numbers, or inexact numbers, +none of which sensibly represent amounts of money.

The contract system allows programmers to define their own contracts +as functions:

#lang racket
 
(define (amount? a)
  (and (number? a) (integer? a) (exact? a) (>= a 0)))
 
(provide (contract-out
          ; an amount is a natural number of cents
          ; is the given number an amount?
          [deposit (-> amount? any)]
          [amount? (-> any/c boolean?)]
          [balance (-> amount?)]))
 
(define amount 0)
(define (deposit a) (set! amount (+ amount a)))
(define (balance) amount)

This module defines an amount? function and uses it as a +contract within -> contracts. When a client calls the +deposit function as exported with the contract (-> amount? any), it must supply an exact, nonnegative integer, otherwise +the amount? function applied to the argument will return +#f, which will cause the contract-monitoring system to blame +the client. Similarly, the server module must provide an exact, +nonnegative integer as the result of balance to remain +blameless.

Of course, it makes no sense to restrict a channel of communication to +values that the client doesn’t understand. Therefore the module also +exports the amount? predicate itself, with a contract saying +that it accepts an arbitrary value and returns a boolean.

In this case, we could also have used natural-number/c in +place of amount?, since it implies exactly the same check:

(provide (contract-out
          [deposit (-> natural-number/c any)]
          [balance (-> natural-number/c)]))

Every function that accepts one argument can be treated as a predicate +and thus used as a contract. For combining existing checks into a new +one, however, contract combinators such as and/c and +or/c are often useful. For example, here is yet another way +to write the contracts above:

(define amount/c
  (and/c number? integer? exact? (or/c positive? zero?)))
 
(provide (contract-out
          [deposit (-> amount/c any)]
          [balance (-> amount/c)]))

Other values also serve double duty as contracts. For example, if a +function accepts a number or #f, (or/c number? #f) +suffices. Similarly, the amount/c contract could have been +written with a 0 in place of zero?. If you use a +regular expression as a contract, the contract accepts strings and +byte strings that match the regular expression.

Naturally, you can mix your own contract-implementing functions with +combinators like and/c. Here is a module for creating strings +from banking records:

#lang racket
 
(define (has-decimal? str)
  (define L (string-length str))
  (and (>= L 3)
       (char=? #\. (string-ref str (- L 3)))))
 
(provide (contract-out
          ; convert a random number to a string
          [format-number (-> number? string?)]
 
          ; convert an amount into a string with a decimal
          ; point, as in an amount of US currency
          [format-nat (-> natural-number/c
                          (and/c string? has-decimal?))]))
The contract of the exported function format-number specifies +that the function consumes a number and produces a string. The +contract of the exported function format-nat is more +interesting than the one of format-number. It consumes only +natural numbers. Its range contract promises a string that has a +. in the third position from the right.

If we want to strengthen the promise of the range contract for +format-nat so that it admits only strings with digits and a single +dot, we could write it like this:

#lang racket
 
(define (digit-char? x)
  (member x '(#\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\0)))
 
(define (has-decimal? str)
  (define L (string-length str))
  (and (>= L 3)
       (char=? #\. (string-ref str (- L 3)))))
 
(define (is-decimal-string? str)
  (define L (string-length str))
  (and (has-decimal? str)
       (andmap digit-char?
               (string->list (substring str 0 (- L 3))))
       (andmap digit-char?
               (string->list (substring str (- L 2) L)))))
 
....
 
(provide (contract-out
          ....
          ; convert an amount (natural number) of cents
          ; into a dollar-based string
          [format-nat (-> natural-number/c
                          (and/c string?
                                 is-decimal-string?))]))

Alternately, in this case, we could use a regular expression as a +contract:

#lang racket
 
(provide
 (contract-out
  ....
  ; convert an amount (natural number) of cents
  ; into a dollar-based string
  [format-nat (-> natural-number/c
                  (and/c string? #rx"[0-9]*\\.[0-9][0-9]"))]))
7.2.5 Contracts on Higher-order Functions

Function contracts are not just restricted to having simple +predicates on their domains or ranges. Any of the contract +combinators discussed here, including function contracts +themselves, can be used as contracts on the arguments and +results of a function.

For example,

(-> integer? (-> integer? integer?))

is a contract that describes a curried function. It matches functions +that accept one argument and then return another function accepting a +second argument before finally returning an integer. If a server +exports a function make-adder with this contract, and if +make-adder returns a value other than a function, then the +server is to blame. If make-adder does return a function, but +the resulting function is applied to a value other than an integer, +then the client is to blame.

Similarly, the contract

(-> (-> integer? integer?) integer?)

describes functions that accept other functions as its input. If a +server exports a function twice with this contract and the +twice is applied to a value other than a function of one +argument, then the client is to blame. If twice is applied to +a function of one argument and twice calls the given function +on a value other than an integer, then the server is to blame.

7.2.6 Contract Messages with “???”

You wrote your module. You added contracts. You put them into the interface +so that client programmers have all the information from interfaces. It’s a +piece of art: +
> (module bank-server racket
    (provide
     (contract-out
      [deposit (-> (λ (x)
                     (and (number? x) (integer? x) (>= x 0)))
                   any)]))
  
    (define total 0)
    (define (deposit a) (set! total (+ a total))))

Several clients used your module. Others used their +modules in turn. And all of a sudden one of them sees this error +message:

> (require 'bank-server)
> (deposit -10)

deposit: contract violation

  expected: ???

  given: -10

  in: the 1st argument of

      (-> ??? any)

  contract from: bank-server

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

What is the ??? doing there? Wouldn’t it be nice if +we had a name for this class of data much like we have string, number, +and so on?

For this situation, Racket provides flat named +contracts. The use of “contract” in this term shows that contracts +are first-class values. The “flat” means that the collection of data +is a subset of the built-in atomic classes of data; they are described +by a predicate that consumes all Racket values and produces a +boolean. The “named” part says what we want to do, which is to name +the contract so that error messages become intelligible:

> (module improved-bank-server racket
    (provide
     (contract-out
      [deposit (-> (flat-named-contract
                    'amount
                    (λ (x)
                      (and (number? x) (integer? x) (>= x 0))))
                   any)]))
  
    (define total 0)
    (define (deposit a) (set! total (+ a total))))

With this little change, the error message becomes quite readable:

> (require 'improved-bank-server)
> (deposit -10)

deposit: contract violation

  expected: amount

  given: -10

  in: the 1st argument of

      (-> amount any)

  contract from: improved-bank-server

  blaming: top-level

   (assuming the contract is correct)

  at: eval:5:0

7.2.7 Dissecting a contract error message

In general, each contract error message consists of six sections: +
  • a name for the function or method associated with the contract +and either the phrase “contract violation” or “broke its contract” +depending on whether the contract was violated by the client or the +server; e.g. in the previous example:

    deposit: contract violation

  • a description of the precise aspect of the contract that was violated,

    expected: amount

    given: -10

  • the complete contract plus a path into it showing which aspect was violated,

    in: the 1st argument of

    (-> amount any)

  • the module where the contract was put (or, more generally, the boundary that the contract mediates),

    contract from: improved-bank-server

  • who was blamed,

    blaming: top-level

    (assuming the contract is correct)

  • and the source location where the contract appears.

    at: eval:5:0

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-examples.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-examples.html new file mode 100644 index 00000000..b25c728b --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-examples.html @@ -0,0 +1,29 @@ + +7.7 Additional Examples

7.7 Additional Examples

This section illustrates the current state of Racket’s contract + implementation with a series of examples from Design by +Contract, by Example [Mitchell02].

Mitchell and McKim’s principles for design by contract DbC are derived + from the 1970s style algebraic specifications. The overall goal of DbC is + to specify the constructors of an algebra in terms of its + observers. While we reformulate Mitchell and McKim’s terminology and + we use a mostly applicative approach, we + retain their terminology of “classes” and “objects”:

  • Separate queries from commands.

    A query returns a result but does not change the observable +properties of an object. A command changes the visible +properties of an object, but does not return a result. In applicative +implementation a command typically returns an new object of the same +class.

  • Separate basic queries from derived queries.

    A derived query returns a result that is computable in +terms of basic queries.

  • For each derived query, write a post-condition contract that +specifies the result in terms of the basic queries.

  • For each command, write a post-condition contract that specifies the +changes to the observable properties in terms of the basic queries.

  • For each query and command, decide on a suitable +pre-condition contract.

Each of the following sections corresponds to a chapter in + Mitchell and McKim’s book (but not all chapters show up + here). We recommend that you read the contracts first (near + the end of the first modules), then the implementation (in + the first modules), and then the test module (at the end of + each section).

Mitchell and McKim use Eiffel as the underlying programming language and + employ a conventional imperative programming style. Our long-term goal is + to transliterate their examples into applicative Racket, + structure-oriented imperative Racket, and Racket’s class system.

Note: To mimic Mitchell and McKim’s informal notion of parametericity + (parametric polymorphism), we use first-class contracts. At several + places, this use of first-class contracts improves on Mitchell and McKim’s + design (see comments in interfaces).

7.7.1 A Customer-Manager Component

This first module contains some struct definitions in a +separate module in order to better track bugs.

#lang racket
; data definitions
 
(define id? symbol?)
(define id-equal? eq?)
(define-struct basic-customer (id name address) #:mutable)
 
; interface
(provide
 (contract-out
  [id?                   (-> any/c boolean?)]
  [id-equal?             (-> id? id? boolean?)]
  [struct basic-customer ((id id?)
                          (name string?)
                          (address string?))]))
; end of interface

This module contains the program that uses the above.

#lang racket
 
(require "1.rkt") ; the module just above
 
; implementation
; [listof (list basic-customer? secret-info)]
(define all '())
 
(define (find c)
  (define (has-c-as-key p)
    (id-equal? (basic-customer-id (car p)) c))
  (define x (filter has-c-as-key all))
  (if (pair? x) (car x) x))
 
(define (active? c)
  (pair? (find c)))
 
(define not-active? (compose not active? basic-customer-id))
 
(define count 0)
(define (get-count) count)
 
(define (add c)
  (set! all (cons (list c 'secret) all))
  (set! count (+ count 1)))
 
(define (name id)
  (define bc-with-id (find id))
  (basic-customer-name (car bc-with-id)))
 
(define (set-name id name)
  (define bc-with-id (find id))
  (set-basic-customer-name! (car bc-with-id) name))
 
(define c0 0)
; end of implementation
 
(provide
 (contract-out
  ; how many customers are in the db?
  [get-count (-> natural-number/c)]
  ; is the customer with this id active?
  [active?   (-> id? boolean?)]
  ; what is the name of the customer with this id?
  [name      (-> (and/c id? active?) string?)]
  ; change the name of the customer with this id
  [set-name  (->i ([id id?] [nn string?])
                  [result any/c] ; result contract
                  #:post (id nn) (string=? (name id) nn))]
 
  [add       (->i ([bc (and/c basic-customer? not-active?)])
                  ; A pre-post condition contract must use
                  ; a side-effect to express this contract
                  ; via post-conditions
                  #:pre () (set! c0 count)
                  [result any/c] ; result contract
                  #:post () (> count c0))]))

The tests:

#lang racket
(require rackunit rackunit/text-ui "1.rkt" "1b.rkt")
 
(add (make-basic-customer 'mf "matthias" "brookstone"))
(add (make-basic-customer 'rf "robby" "beverly hills park"))
(add (make-basic-customer 'fl "matthew" "pepper clouds town"))
(add (make-basic-customer 'sk "shriram" "i city"))
 
(run-tests
 (test-suite
  "manager"
  (test-equal? "id lookup" "matthias" (name 'mf))
  (test-equal? "count" 4 (get-count))
  (test-true "active?" (active? 'mf))
  (test-false "active? 2" (active? 'kk))
  (test-true "set name" (void? (set-name 'mf "matt")))))
7.7.2 A Parameteric (Simple) Stack
#lang racket
 
; a contract utility
(define (eq/c x) (lambda (y) (eq? x y)))
 
(define-struct stack (list p? eq))
 
(define (initialize p? eq) (make-stack '() p? eq))
(define (push s x)
  (make-stack (cons x (stack-list s)) (stack-p? s) (stack-eq s)))
(define (item-at s i) (list-ref (reverse (stack-list s)) (- i 1)))
(define (count s) (length  (stack-list s)))
(define (is-empty? s) (null? (stack-list s)))
(define not-empty? (compose not is-empty?))
(define (pop s) (make-stack (cdr (stack-list s))
                            (stack-p? s)
                            (stack-eq s)))
(define (top s) (car (stack-list s)))
 
(provide
 (contract-out
  ; predicate
  [stack?     (-> any/c boolean?)]
 
  ; primitive queries
  ; how many items are on the stack?
  [count      (-> stack? natural-number/c)]
 
  ; which item is at the given position?
  [item-at
   (->d ([s stack?] [i (and/c positive? (<=/c (count s)))])
        ()
        [result (stack-p? s)])]
 
  ; derived queries
  ; is the stack empty?
  [is-empty?
   (->d ([s stack?])
        ()
        [result (eq/c (= (count s) 0))])]
 
  ; which item is at the top of the stack
  [top
   (->d ([s (and/c stack? not-empty?)])
        ()
        [t (stack-p? s)] ; a stack item, t is its name
        #:post-cond
        ([stack-eq s] t (item-at s (count s))))]
 
  ; creation
  [initialize
   (->d ([p contract?] [s (p p . -> . boolean?)])
        ()
        ; Mitchell and McKim use (= (count s) 0) here to express
        ; the post-condition in terms of a primitive query
        [result (and/c stack? is-empty?)])]
 
  ; commands
  ; add an item to the top of the stack
  [push
   (->d ([s stack?] [x (stack-p? s)])
        ()
        [sn stack?] ; result kind
        #:post-cond
        (and (= (+ (count s) 1) (count sn))
             ([stack-eq s] x (top sn))))]
 
  ; remove the item at the top of the stack
  [pop
   (->d ([s (and/c stack? not-empty?)])
        ()
        [sn stack?] ; result kind
        #:post-cond
        (= (- (count s) 1) (count sn)))]))

The tests:

#lang racket
(require rackunit rackunit/text-ui "2.rkt")
 
(define s0 (initialize (flat-contract integer?) =))
(define s2 (push (push s0 2) 1))
 
(run-tests
 (test-suite
  "stack"
  (test-true
   "empty"
   (is-empty? (initialize (flat-contract integer?) =)))
  (test-true "push" (stack? s2))
  (test-true
   "push exn"
   (with-handlers ([exn:fail:contract? (lambda _ #t)])
     (push (initialize (flat-contract integer?)) 'a)
     #f))
  (test-true "pop" (stack? (pop s2)))
  (test-equal? "top" (top s2) 1)
  (test-equal? "toppop" (top (pop s2)) 2)))
7.7.3 A Dictionary
#lang racket
 
; a shorthand for use below
(define-syntax 
  (syntax-rules ()
    [( antecedent consequent) (if antecedent consequent #t)]))
 
; implementation
(define-struct dictionary (l value? eq?))
; the keys should probably be another parameter (exercise)
 
(define (initialize p eq) (make-dictionary '() p eq))
(define (put d k v)
  (make-dictionary (cons (cons k v) (dictionary-l d))
                   (dictionary-value? d)
                   (dictionary-eq? d)))
(define (rem d k)
  (make-dictionary
   (let loop ([l (dictionary-l d)])
     (cond
       [(null? l) l]
       [(eq? (caar l) k) (loop (cdr l))]
       [else (cons (car l) (loop (cdr l)))]))
   (dictionary-value? d)
   (dictionary-eq? d)))
(define (count d) (length (dictionary-l d)))
(define (value-for d k) (cdr (assq k (dictionary-l d))))
(define (has? d k) (pair? (assq k (dictionary-l d))))
(define (not-has? d) (lambda (k) (not (has? d k))))
; end of implementation
 
; interface
(provide
 (contract-out
  ; predicates
  [dictionary? (-> any/c boolean?)]
  ; basic queries
  ; how many items are in the dictionary?
  [count       (-> dictionary? natural-number/c)]
  ; does the dictionary define key k?
  [has?        (->d ([d dictionary?] [k symbol?])
                    ()
                    [result boolean?]
                    #:post-cond
                    ((zero? (count d)) . . (not result)))]
  ; what is the value of key k in this dictionary?
  [value-for   (->d ([d dictionary?]
                     [k (and/c symbol? (lambda (k) (has? d k)))])
                    ()
                    [result (dictionary-value? d)])]
  ; initialization
  ; post condition: for all k in symbol, (has? d k) is false.
  [initialize  (->d ([p contract?] [eq (p p . -> . boolean?)])
                    ()
                    [result (and/c dictionary? (compose zero? count))])]
  ; commands
  ; Mitchell and McKim say that put shouldn't consume Void (null ptr)
  ; for v. We allow the client to specify a contract for all values
  ; via initialize. We could do the same via a key? parameter
  ; (exercise). add key k with value v to this dictionary
  [put         (->d ([d dictionary?]
                     [k (and/c symbol? (not-has? d))]
                     [v (dictionary-value? d)])
                    ()
                    [result dictionary?]
                    #:post-cond
                    (and (has? result k)
                         (= (count d) (- (count result) 1))
                         ([dictionary-eq? d] (value-for result k) v)))]
  ; remove key k from this dictionary
  [rem         (->d ([d dictionary?]
                     [k (and/c symbol? (lambda (k) (has? d k)))])
                    ()
                    [result (and/c dictionary? (lambda (d) ((not-has? d) k)))]
                    #:post-cond
                    (= (count d) (+ (count result) 1)))]))
; end of interface

The tests:

#lang racket
(require rackunit rackunit/text-ui "3.rkt")
 
(define d0 (initialize (flat-contract integer?) =))
(define d (put (put (put d0 'a 2) 'b 2) 'c 1))
 
(run-tests
 (test-suite
  "dictionaries"
  (test-equal? "value for" 2 (value-for d 'b))
  (test-false "has?" (has? (rem d 'b) 'b))
  (test-equal? "count" 3 (count d))
  (test-case "contract check for put: symbol?"
             (define d0 (initialize (flat-contract integer?) =))
             (check-exn exn:fail:contract? (lambda () (put d0 "a" 2))))))
7.7.4 A Queue
#lang racket
 
; Note: this queue doesn't implement the capacity restriction
; of Mitchell and McKim's queue but this is easy to add.
 
; a contract utility
(define (all-but-last l) (reverse (cdr (reverse l))))
(define (eq/c x) (lambda (y) (eq? x y)))
 
; implementation
(define-struct queue (list p? eq))
 
(define (initialize p? eq) (make-queue '() p? eq))
(define items queue-list)
(define (put q x)
  (make-queue (append (queue-list q) (list x))
              (queue-p? q)
              (queue-eq q)))
(define (count s) (length  (queue-list s)))
(define (is-empty? s) (null? (queue-list s)))
(define not-empty? (compose not is-empty?))
(define (rem s)
  (make-queue (cdr (queue-list s))
              (queue-p? s)
              (queue-eq s)))
(define (head s) (car (queue-list s)))
 
; interface
(provide
 (contract-out
  ; predicate
  [queue?     (-> any/c boolean?)]
 
  ; primitive queries
  ; Imagine providing this 'query' for the interface of the module
  ; only. Then in Racket there is no reason to have count or is-empty?
  ; around (other than providing it to clients). After all items is
  ; exactly as cheap as count.
  [items      (->d ([q queue?]) () [result (listof (queue-p? q))])]
 
  ; derived queries
  [count      (->d ([q queue?])
                   ; We could express this second part of the post
                   ; condition even if count were a module "attribute"
                   ; in the language of Eiffel; indeed it would use the
                   ; exact same syntax (minus the arrow and domain).
                   ()
                   [result (and/c natural-number/c
                                  (=/c (length (items q))))])]
 
  [is-empty?  (->d ([q queue?])
                   ()
                   [result (and/c boolean?
                                  (eq/c (null? (items q))))])]
 
  [head       (->d ([q (and/c queue? (compose not is-empty?))])
                   ()
                   [result (and/c (queue-p? q)
                                  (eq/c (car (items q))))])]
  ; creation
  [initialize (-> contract?
                  (contract? contract? . -> . boolean?)
                  (and/c queue? (compose null? items)))]
 
  ; commands
  [put        (->d ([oldq queue?] [i (queue-p? oldq)])
                   ()
                   [result
                    (and/c
                     queue?
                     (lambda (q)
                       (define old-items (items oldq))
                       (equal? (items q) (append old-items (list i)))))])]
 
  [rem        (->d ([oldq (and/c queue? (compose not is-empty?))])
                   ()
                   [result
                    (and/c queue?
                           (lambda (q)
                             (equal? (cdr (items oldq)) (items q))))])]))
; end of interface

The tests:

#lang racket
(require rackunit rackunit/text-ui "5.rkt")
 
(define s (put (put (initialize (flat-contract integer?) =) 2) 1))
 
(run-tests
 (test-suite
  "queue"
  (test-true
   "empty"
   (is-empty? (initialize (flat-contract integer?) =)))
  (test-true "put" (queue? s))
  (test-equal? "count" 2 (count s))
  (test-true "put exn"
             (with-handlers ([exn:fail:contract? (lambda _ #t)])
               (put (initialize (flat-contract integer?)) 'a)
               #f))
  (test-true "remove" (queue? (rem s)))
  (test-equal? "head" 2 (head s))))
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-exists.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-exists.html new file mode 100644 index 00000000..3394502e --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-exists.html @@ -0,0 +1,19 @@ + +7.6 Abstract Contracts using #:exists and #:โˆƒ

7.6 Abstract Contracts using #:exists and #:∃

The contract system provides existential contracts that can +protect abstractions, ensuring that clients of your module +cannot depend on the precise representation choices you make +for your data structures.

You can type #:exists instead of #:∃ if you +cannot easily type unicode characters; in DrRacket, typing +\exists followed by either alt-\ or control-\ (depending +on your platform) will produce .

The contract-out form allows you to write +

#:∃ name-of-a-new-contract

as one of its clauses. This declaration +introduces the variable name-of-a-new-contract, binding it to a new +contract that hides information about the values it protects.

As an example, consider this (simple) implementation of a queue data structure: +
#lang racket
(define empty '())
(define (enq top queue) (append queue (list top)))
(define (next queue) (car queue))
(define (deq queue) (cdr queue))
(define (empty? queue) (null? queue))
 
(provide
 (contract-out
  [empty (listof integer?)]
  [enq (-> integer? (listof integer?) (listof integer?))]
  [next (-> (listof integer?) integer?)]
  [deq (-> (listof integer?) (listof integer?))]
  [empty? (-> (listof integer?) boolean?)]))
This code implements a queue purely in terms of lists, meaning that clients +of this data structure might use car and cdr directly on the +data structure (perhaps accidentally) and thus any change in the representation +(say to a more efficient representation that supports amortized constant time +enqueue and dequeue operations) might break client code.

To ensure that the queue representation is abstract, we can use #:∃ in the +contract-out expression, like this: +
(provide
 (contract-out
  #:∃ queue
  [empty queue]
  [enq (-> integer? queue queue)]
  [next (-> queue integer?)]
  [deq (-> queue queue)]
  [empty? (-> queue boolean?)]))

Now, if clients of the data structure try to use car and cdr, they +receive an error, rather than mucking about with the internals of the queues.

See also Exists Contracts and Predicates.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-first.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-first.html new file mode 100644 index 00000000..8e7f4a6a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-first.html @@ -0,0 +1,78 @@ + +7.4 Contracts: A Thorough Example

7.4 Contracts: A Thorough Example

This section develops several different flavors of contracts for one and + the same example: Racket’s argmax function. According to + its Racket documentation, the function consumes a procedure proc and + a non-empty list of values, lst. It +

returns the first element in the list lst that maximizes +the result of proc.

The emphasis on first is ours.

Examples: +
> (argmax add1 (list 1 2 3))

3

> (argmax sqrt (list 0.4 0.9 0.16))

0.9

> (argmax second '((a 2) (b 3) (c 4) (d 1) (e 4)))

'(c 4)

Here is the simplest possible contract for this function: +

version 1

#lang racket
 
(define (argmax f lov) ...)
 
(provide
 (contract-out
  [argmax (-> (-> any/c real?) (and/c pair? list?) any/c)]))
This contract captures two essential conditions of the informal + description of argmax: +
  • the given function must produce numbers that are comparable according +to <. In particular, the contract (-> any/c number?) +would not do, because number? also recognizes complex numbers in +Racket.

  • the given list must contain at least one item.

When combined with the name, the contract explains the behavior of + argmax at the same level as an ML function type in a + module signature (except for the non-empty list aspect).

Contracts may communicate significantly more than a type signature, + however. Take a look at this second contract for argmax: +

version 2

#lang racket
 
(define (argmax f lov) ...)
 
(provide
 (contract-out
  [argmax
    (->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
         (r (f lov)
            (lambda (r)
              (define f@r (f r))
              (for/and ([v lov]) (>= f@r (f v))))))]))
It is a dependent contract that names the two arguments and uses + the names to impose a predicate on the result. This predicate computes + (f r) – where r is the result of argmax – and + then validates that this value is greater than or equal to all values + of f on the items of lov.

Is it possible that argmax could cheat by returning a random value + that accidentally maximizes f over all elements of lov? + With a contract, it is possible to rule out this possibility: +

version 2 rev. a

#lang racket
 
(define (argmax f lov) ...)
 
(provide
 (contract-out
  [argmax
    (->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
         (r (f lov)
            (lambda (r)
              (define f@r (f r))
              (and (memq r lov)
                   (for/and ([v lov]) (>= f@r (f v)))))))]))
The memq function ensures that r is intensionally equal + That is, "pointer equality" for those who prefer to think at +the hardware level. to one of the members of lov. Of course, a + moment’s worth of reflection shows that it is impossible to make up such a + value. Functions are opaque values in Racket and without applying a + function, it is impossible to determine whether some random input value + produces an output value or triggers some exception. So we ignore this + possibility from here on.

Version 2 formulates the overall sentiment of argmax’s + documentation, but it fails to bring across that the result is the + first element of the given list that maximizes the given function + f. Here is a version that communicates this second aspect of + the informal documentation: +

version 3

#lang racket
 
(define (argmax f lov) ...)
 
(provide
 (contract-out
  [argmax
    (->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
         (r (f lov)
            (lambda (r)
              (define f@r (f r))
              (and (for/and ([v lov]) (>= f@r (f v)))
                   (eq? (first (memf (lambda (v) (= (f v) f@r)) lov))
                        r)))))]))
That is, the memf function determines the first element of + lov whose value under f is equal to r’s value + under f. If this element is intensionally equal to r, + the result of argmax is correct.

This second refinement step introduces two problems. First, both conditions + recompute the values of f for all elements of lov. Second, + the contract is now quite difficult to read. Contracts should have a concise + formulation that a client can comprehend with a simple scan. Let us + eliminate the readability problem with two auxiliary functions that have + reasonably meaningful names:

version 3 rev. a

#lang racket
 
(define (argmax f lov) ...)
 
(provide
 (contract-out
  [argmax
    (->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
         (r (f lov)
            (lambda (r)
              (define f@r (f r))
              (and (is-first-max? r f@r f lov)
                   (dominates-all f@r f lov)))))]))
 
; where
 
; f@r is greater or equal to all (f v) for v in lov
(define (dominates-all f@r f lov)
  (for/and ([v lov]) (>= f@r (f v))))
 
; r is eq? to the first element v of lov +for which (pred? v)
(define (is-first-max? r f@r f lov)
  (eq? (first (memf (lambda (v) (= (f v) f@r)) lov)) r))
The names of the two predicates express their functionality and, in + principle, render it unnecessary to read their definitions.

This step leaves us with the problem of the newly introduced inefficiency. + To avoid the recomputation of (f v) for all v on + lov, we change the contract so that it computes these values and + reuses them as needed:

version 3 rev. b

#lang racket
 
(define (argmax f lov) ...)
 
(provide
 (contract-out
  [argmax
    (->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
         (r (f lov)
            (lambda (r)
              (define f@r (f r))
              (define flov (map f lov))
              (and (is-first-max? r f@r (map list lov flov))
                   (dominates-all f@r flov)))))]))
 
; where
 
; f@r is greater or equal to all f@v in flov
(define (dominates-all f@r flov)
  (for/and ([f@v flov]) (>= f@r f@v)))
 
; r is (first x) for the first +x in lov+flov s.t. (= (second x) f@r)
(define (is-first-max? r f@r lov+flov)
  (define fst (first lov+flov))
  (if (= (second fst) f@r)
      (eq? (first fst) r)
      (is-first-max? r f@r (rest lov+flov))))
Now the predicate on the result once again computes all values of f + for elements of lov once.

The word "eager" comes from the literature on the linguistics +of contracts.

Version 3 may still be too eager when it comes to calling f. While + Racket’s argmax always calls f no matter how many items + lov contains, let us imagine for illustrative purposes that our + own implementation first checks whether the list is a singleton. If so, + the first element would be the only element of lov and in that + case there would be no need to compute (f r). +The argmax of Racket implicitly argues that it not +only promises the first value that maximizes f over lov +but also that f produces/produced a value for the result. + As a matter of fact, since f may diverge or raise an exception + for some inputs, argmax should avoid calling f when + possible.

The following contract demonstrates how a higher-order dependent contract + needs to be adjusted so as to avoid being over-eager:

version 4

#lang racket
 
(define (argmax f lov)
  (if (empty? (rest lov))
      (first lov)
      ...))
 
(provide
 (contract-out
  [argmax
    (->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
         (r (f lov)
            (lambda (r)
              (cond
                [(empty? (rest lov)) (eq? (first lov) r)]
                [else
                 (define f@r (f r))
                 (define flov (map f lov))
                 (and (is-first-max? r f@r (map list lov flov))
                      (dominates-all f@r flov))]))))]))
 
; where
 
; f@r is greater or equal to all f@v in flov
(define (dominates-all f@r lov) ...)
 
; r is (first x) for the first +x in lov+flov s.t. (= (second x) f@r)
(define (is-first-max? r f@r lov+flov) ...)
Note that such considerations don’t apply to the world of first-order + contracts. Only a higher-order (or lazy) language forces the programmer to + express contracts with such precision.

The problem of diverging or exception-raising functions should alert the + reader to the even more general problem of functions with side-effects. If + the given function f has visible effects – say it logs its calls + to a file – then the clients of argmax will be able to observe + two sets of logs for each call to argmax. To be precise, if the + list of values contains more than one element, the log will contain two + calls of f per value on lov. If f is expensive + to compute, doubling the calls imposes a high cost.

To avoid this cost and to signal problems with overly eager contracts, a + contract system could record the i/o of contracted function arguments and + use these hashtables in the dependency specification. This is a topic of + on-going research in PLT. Stay tuned.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-general-functions.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-general-functions.html new file mode 100644 index 00000000..195aedab --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-general-functions.html @@ -0,0 +1,186 @@ + +7.3 Contracts on Functions in General

7.3 Contracts on Functions in General

The -> contract constructor works for functions that take a +fixed number of arguments and where the result contract is independent +of the input arguments. To support other kinds of functions, Racket +supplies additional contract constructors, notably ->* and +->i.

7.3.1 Optional Arguments

Take a look at this excerpt from a string-processing module:

#lang racket
 
(provide
 (contract-out
  ; pad the given str left and right with
  ; the (optional) char so that it is centered
  [string-pad-center (->* (string? natural-number/c)
                          (char?)
                          string?)]))
 
(define (string-pad-center str width [pad #\space])
  (define field-width (min width (string-length str)))
  (define rmargin (ceiling (/ (- width field-width) 2)))
  (define lmargin (floor (/ (- width field-width) 2)))
  (string-append (build-string lmargin (λ (x) pad))
                 str
                 (build-string rmargin (λ (x) pad))))

The module exports string-pad-center, a function + that creates a string of a given width with the + given string in the center. The default fill character is + #\space; if the client module wishes to use a + different character, it may call string-pad-center + with a third argument, a char, overwriting the + default.

The function definition uses optional arguments, which is +appropriate for this kind of functionality. The interesting +point here is the formulation of the contract for the +string-pad-center.

The contract combinator ->*, demands several groups of contracts:

  • The first one is a parenthesized group of contracts for all required +arguments. In this example, we see two: string? and +natural-number/c.

  • The second one is a parenthesized group of contracts for all optional +arguments: char?.

  • The last one is a single contract: the result of the function.

Note that if a default value does not satisfy a contract, you won’t get a + contract error for this interface. If you can’t trust yourself to get + the initial value right, you need to communicate the initial value + across a boundary.

7.3.2 Rest Arguments

The max operator consumes at least one real number, but it + accepts any number of additional arguments. You can write other such + functions using a rest argument, such as in max-abs:

See Declaring a Rest Argument for an introduction to rest +arguments.

(define (max-abs n . rst)
  (foldr (lambda (n m) (max (abs n) m)) (abs n) rst))

Describing this function through a contract requires a further +extension of ->*: a #:rest keyword specifies a +contract on a list of arguments after the required and optional +arguments:

(provide
 (contract-out
  [max-abs (->* (real?) () #:rest (listof real?) real?)]))

As always for ->*, the contracts for the required arguments +are enclosed in the first pair of parentheses, which in this case is a +single real number. The empty pair of parenthesis indicates that there +are no optional arguments (not counting the rest arguments). The +contract for the rest argument follows #:rest; since all +additional arguments must be real numbers, the list of rest arguments +must satisfy the contract (listof real?).

7.3.3 Keyword Arguments

It turns out that the -> contract constructor also contains +support for keyword arguments. For example, consider this function, +which creates a simple GUI and asks the user a yes-or-no question:

See Declaring Keyword Arguments for an introduction to +keyword arguments.

#lang racket/gui
 
(define (ask-yes-or-no-question question
                                #:default answer
                                #:title title
                                #:width w
                                #:height h)
  (define d (new dialog% [label title] [width w] [height h]))
  (define msg (new message% [label question] [parent d]))
  (define (yes) (set! answer #t) (send d show #f))
  (define (no) (set! answer #f) (send d show #f))
  (define yes-b (new button%
                     [label "Yes"] [parent d]
                     [callback (λ (x y) (yes))]
                     [style (if answer '(border) '())]))
  (define no-b (new button%
                    [label "No"] [parent d]
                    [callback (λ (x y) (no))]
                    [style (if answer '() '(border))]))
  (send d show #t)
  answer)
 
(provide (contract-out
          [ask-yes-or-no-question
           (-> string?
               #:default boolean?
               #:title string?
               #:width exact-integer?
               #:height exact-integer?
               boolean?)]))

If you really want to ask a yes-or-no question +via a GUI, you should use message-box/custom. For that +matter, it’s usually better to provide buttons with more specific +answers than “yes” and “no.”

The contract for ask-yes-or-no-question uses ->, and +in the same way that lambda (or define-based +functions) allows a keyword to precede a functions formal argument, +-> allows a keyword to precede a function contract’s argument +contract. In this case, +the contract says that ask-yes-or-no-question must receive four keyword +arguments, one for each of the keywords +#:default, +#:title, +#:width, and +#:height. +As in a function definition, the order of the keywords in -> +relative to each other does not matter for clients of the function; +only the relative order of argument contracts without keywords +matters.

7.3.4 Optional Keyword Arguments

Of course, many of the parameters in +ask-yes-or-no-question (from the previous question) +have reasonable defaults and should be made optional:

(define (ask-yes-or-no-question question
                                #:default answer
                                #:title [title "Yes or No?"]
                                #:width [w 400]
                                #:height [h 200])
  ...)

To specify this function’s contract, we need to use +->* again. It supports keywords just as you might +expect in both the optional and mandatory argument +sections. In this case, we have the mandatory keyword +#:default and optional keywords +#:title, +#:width, and +#:height. So, we write the contract like this:

(provide (contract-out
          [ask-yes-or-no-question
           (->* (string?
                 #:default boolean?)
                (#:title string?
                 #:width exact-integer?
                 #:height exact-integer?)
 
                boolean?)]))

That is, we put the mandatory keywords in the first section, and we +put the optional ones in the second section.

7.3.5 Contracts for case-lambda

A function defined with case-lambda might impose different +constraints on its arguments depending on how many are provided. For +example, a report-cost function might convert either a pair +of numbers or a string into a new string:

See Arity-Sensitive Functions: case-lambda for an introduction to +case-lambda.

(define report-cost
  (case-lambda
    [(lo hi) (format "between $~a and $~a" lo hi)]
    [(desc) (format "~a of dollars" desc)]))

 

> (report-cost 5 8)

"between $5 and $8"

> (report-cost "millions")

"millions of dollars"

The contract for such a function is formed with the case-> + combinator, which combines as many functional contracts as needed: +
(provide (contract-out
          [report-cost
           (case->
            (integer? integer? . -> . string?)
            (string? . -> . string?))]))
As you can see, the contract for report-cost combines two + function contracts, which is just as many clauses as the explanation + of its functionality required.

7.3.6 Argument and Result Dependencies

The following is an excerpt from an imaginary numerics module:

(provide
 (contract-out
  [real-sqrt (->i ([argument (>=/c 1)])
                  [result (argument) (<=/c argument)])]))

The word “indy” is meant to suggest that blame may be +assigned to the contract itself, because the contract must be considered an +independent component. The name was chosen in +response to two existing labels—“lax” and “picky”—for different +semantics of function contracts in the research literature.

The contract for the exported function real-sqrt uses the +->i rather than ->* function contract. The “i” +stands for an indy dependent contract, meaning the contract for the +function range depends on the value of the argument. The appearance +of argument in the line for result’s contract means +that the result depends on the argument. In this +particular case, the argument of real-sqrt is greater or +equal to 1, so a very basic correctness check is that the result is +smaller than the argument.

In general, a dependent function contract looks just like +the more general ->* contract, but with names added +that can be used elsewhere in the contract.

Going back to the bank-account example, suppose that we generalize the +module to support multiple accounts and that we also include a +withdrawal operation. The improved bank-account module includes an +account structure type and the following functions:

(provide (contract-out
          [balance (-> account? amount/c)]
          [withdraw (-> account? amount/c account?)]
          [deposit (-> account? amount/c account?)]))

Besides requiring that a client provide a valid amount for a +withdrawal, however, the amount should be less than or equal to the specified +account’s balance, and the resulting account will have less money than +it started with. Similarly, the module might promise that a deposit +produces an account with money added to the account. The following +implementation enforces those constraints and guarantees through +contracts:

#lang racket
 
; section 1: the contract definitions
(struct account (balance))
(define amount/c natural-number/c)
 
; section 2: the exports
(provide
 (contract-out
  [create   (amount/c . -> . account?)]
  [balance  (account? . -> . amount/c)]
  [withdraw (->i ([acc account?]
                  [amt (acc) (and/c amount/c (<=/c (balance acc)))])
                 [result (acc amt)
                         (and/c account?
                                (lambda (res)
                                  (>= (balance res)
                                      (- (balance acc) amt))))])]
  [deposit  (->i ([acc account?]
                  [amt amount/c])
                 [result (acc amt)
                         (and/c account?
                                (lambda (res)
                                  (>= (balance res)
                                      (+ (balance acc) amt))))])]))
 
; section 3: the function definitions
(define balance account-balance)
 
(define (create amt) (account amt))
 
(define (withdraw a amt)
  (account (- (account-balance a) amt)))
 
(define (deposit a amt)
  (account (+ (account-balance a) amt)))

The contracts in section 2 provide typical type-like guarantees for +create and balance. For withdraw and +deposit, however, the contracts check and guarantee the more +complicated constraints on balance and deposit. The +contract on the second argument to withdraw uses +(balance acc) to check whether the supplied withdrawal amount +is small enough, where acc is the name given within +->i to the function’s first argument. The contract on the +result of withdraw uses both acc and amt to +guarantee that no more than that requested amount was withdrawn. The +contract on deposit similarly uses acc and +amount in the result contract to guarantee that at least as +much money as provided was deposited into the account.

As written above, when a contract check fails, the error message is +not great. The following revision uses flat-named-contract +within a helper function mk-account-contract to provide +better error messages.

#lang racket
 
; section 1: the contract definitions
(struct account (balance))
(define amount/c natural-number/c)
 
(define msg> "account a with balance larger than ~a expected")
(define msg< "account a with balance less than ~a expected")
 
(define (mk-account-contract acc amt op msg)
  (define balance0 (balance acc))
  (define (ctr a)
    (and (account? a) (op balance0 (balance a))))
  (flat-named-contract (format msg balance0) ctr))
 
; section 2: the exports
(provide
 (contract-out
  [create   (amount/c . -> . account?)]
  [balance  (account? . -> . amount/c)]
  [withdraw (->i ([acc account?]
                  [amt (acc) (and/c amount/c (<=/c (balance acc)))])
                 [result (acc amt) (mk-account-contract acc amt >= msg>)])]
  [deposit  (->i ([acc account?]
                  [amt amount/c])
                 [result (acc amt)
                         (mk-account-contract acc amt <= msg<)])]))
 
; section 3: the function definitions
(define balance account-balance)
 
(define (create amt) (account amt))
 
(define (withdraw a amt)
  (account (- (account-balance a) amt)))
 
(define (deposit a amt)
  (account (+ (account-balance a) amt)))
7.3.7 Checking State Changes

The ->i contract combinator can also ensure that a +function only modifies state according to certain +constraints. For example, consider this contract +(it is a slightly simplified version from the function +preferences:add-panel in the framework): +
(->i ([parent (is-a?/c area-container-window<%>)])
      [_ (parent)
       (let ([old-children (send parent get-children)])
         (λ (child)
           (andmap eq?
                   (append old-children (list child))
                   (send parent get-children))))])
It says that the function accepts a single argument, named +parent, and that parent must be +an object matching the interface area-container-window<%>.

The range contract ensures that the function only modifies +the children of parent by adding a new child to the +front of the list. It accomplishes this by using the +_ instead of a normal identifier, which tells the +contract library that the range contract does not depend on +the values of any of the results, and thus the contract +library evaluates the expression following the _ +when the function is called, instead of when it +returns. Therefore the call to the get-children method +happens before the function under the contract is called. +When the function under contract returns, its result is +passed in as child, and the contract ensures that +the children after the function return are the same as the +children before the function called, but with one more +child, at the front of the list.

To see the difference in a toy example that focuses +on this point, consider this program +
#lang racket
(define x '())
(define (get-x) x)
(define (f) (set! x (cons 'f x)))
(provide
 (contract-out
  [f (->i () [_ () (begin (set! x (cons 'ctc x)) any/c)])]
  [get-x (-> (listof symbol?))]))
If you were to require this module, call f, then +the result of get-x would be '(f ctc). In +contrast, if the contract for f were +

(->i () [res () (begin (set! x (cons 'ctc x)) any/c)])

(only changing the underscore to res), then +the result of get-x would be '(ctc f).

7.3.8 Multiple Result Values

The function split consumes a list of chars + and delivers the string that occurs before the first occurrence of + #\newline (if any) and the rest of the list: +
(define (split l)
  (define (split l w)
    (cond
      [(null? l) (values (list->string (reverse w)) '())]
      [(char=? #\newline (car l))
       (values (list->string (reverse w)) (cdr l))]
      [else (split (cdr l) (cons (car l) w))]))
  (split l '()))
It is a typical multiple-value function, returning two values by + traversing a single list.

The contract for such a function can use the ordinary +function arrow ->, since -> +treats values specially when it appears as the +last result: +
(provide (contract-out
          [split (-> (listof char?)
                     (values string? (listof char?)))]))

The contract for such a function can also be written +using ->*: +
(provide (contract-out
          [split (->* ((listof char?))
                      ()
                      (values string? (listof char?)))]))
As before, the contract for the argument with ->* is wrapped in an + extra pair of parentheses (and must always be wrapped like + that) and the empty pair of parentheses indicates that + there are no optional arguments. The contracts for the + results are inside values: a string and a list of + characters.

Now, suppose that we also want to ensure that the first result of + split is a prefix of the given word in list format. In that + case, we need to use the ->i contract combinator: +
(define (substring-of? s)
  (flat-named-contract
    (format "substring of ~s" s)
    (lambda (s2)
      (and (string? s2)
           (<= (string-length s2) (string-length s))
           (equal? (substring s 0 (string-length s2)) s2)))))
 
(provide
 (contract-out
  [split (->i ([fl (listof char?)])
              (values [s (fl) (substring-of? (list->string fl))]
                      [c (listof char?)]))]))
Like ->*, the ->i combinator uses a function over the + argument to create the range contracts. Yes, it doesn’t just return one + contract but as many as the function produces values: one contract per + value. In this case, the second contract is the same as before, ensuring + that the second result is a list of chars. In contrast, the + first contract strengthens the old one so that the result is a prefix of + the given word.

This contract is expensive to check, of course. Here is a + cheaper, though less stringent, version: +
(provide
 (contract-out
  [split (->i ([fl (listof char?)])
              (values [s (fl) (string-len/c (+ 1 (length fl)))]
                      [c (listof char?)]))]))
Stop! Why did we add 1 to the length of fl?

7.3.9 Fixed but Statically Unknown Arities

Imagine yourself writing a contract for a function that accepts some other +function and a list of numbers that eventually applies the former to the +latter. Unless the arity of the given function matches the length of the +given list, your procedure is in trouble.

Consider this n-step function: +
; (number ... -> (union #f number?)) (listof number) -> void
(define (n-step proc inits)
  (let ([inc (apply proc inits)])
    (when inc
      (n-step proc (map (λ (x) (+ x inc)) inits)))))

The argument of n-step is proc, a function +proc whose results are either numbers or false, and a list. It +then applies proc to the list inits. As long as +proc returns a number, n-step treats that number +as an increment for each of the numbers in inits and +recurs. When proc returns false, the loop stops.

Here are two uses: +
; nat -> nat
(define (f x)
  (printf "~s\n" x)
  (if (= x 0) #f -1))
(n-step f '(2))
 
; nat nat -> nat
(define (g x y)
  (define z (+ x y))
  (printf "~s\n" (list x y z))
  (if (= z 0) #f -1))
 
(n-step g '(1 1))

A contract for n-step must specify two aspects of +proc’s behavior: its arity must include the number of elements +in inits, and it must return either a number or +#f. The latter is easy, the former is difficult. At first +glance, this appears to suggest a contract that assigns a +variable-arity to proc: +
(->* ()
     #:rest (listof any/c)
     (or/c number? false/c))
This contract, however, says that the function must accept any +number of arguments, not a specific but +undetermined number. Thus, applying n-step to +(lambda (x) x) and (list 1 2) breaks the contract +because the given function accepts only one argument.

The correct contract uses the unconstrained-domain-> + combinator, which specifies only the range of a function, not its + domain. It is then possible to combine this contract with an arity test to + specify the correct contract for n-step: +
(provide
 (contract-out
  [n-step
   (->i ([proc (inits)
          (and/c (unconstrained-domain->
                  (or/c false/c number?))
                 (λ (f) (procedure-arity-includes?
                         f
                         (length inits))))]
         [inits (listof number?)])
        ()
        any)]))

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-gotchas.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-gotchas.html new file mode 100644 index 00000000..db8d7a65 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-gotchas.html @@ -0,0 +1,61 @@ + +7.9 Gotchas

7.9 Gotchas

7.9.1 Contracts and eq?

As a general rule, adding a contract to a program should +either leave the behavior of the program unchanged, or +should signal a contract violation. And this is almost true +for Racket contracts, with one exception: eq?.

The eq? procedure is designed to be fast and does +not provide much in the way of guarantees, except that if it +returns true, it means that the two values behave +identically in all respects. Internally, this is implemented +as pointer equality at a low-level so it exposes information +about how Racket is implemented (and how contracts are +implemented).

Contracts interact poorly with eq? because function +contract checking is implemented internally as wrapper +functions. For example, consider this module: +
#lang racket
 
(define (make-adder x)
  (if (= 1 x)
      add1
      (lambda (y) (+ x y))))
(provide (contract-out
          [make-adder (-> number? (-> number? number?))]))

It exports the make-adder function that is the usual curried +addition function, except that it returns Racket’s add1 when +its input is 1.

You might expect that +
(eq? (make-adder 1)
     (make-adder 1))

would return #t, but it does not. If the contract were +changed to any/c (or even (-> number? any/c)), then +the eq? call would return #t.

Moral: Do not use eq? on values that have contracts.

7.9.2 Contract boundaries and define/contract

The contract boundaries established by define/contract, which +creates a nested contract boundary, are sometimes unintuitive. This is +especially true when multiple functions or other values with contracts +interact. For example, consider these two interacting functions:

> (define/contract (f x)
    (-> integer? integer?)
    x)
> (define/contract (g)
    (-> string?)
    (f "not an integer"))
> (g)

f: contract violation

  expected: integer?

  given: "not an integer"

  in: the 1st argument of

      (-> integer? integer?)

  contract from: (function f)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2:0

One might expect that the function g will be blamed +for breaking the terms of its contract with f. +Blaming g would be right if f and g +were directly establishing contracts with each other. +They aren’t, however. Instead, the access between f +and g is mediated through the top-level of the enclosing +module.

More precisely, f and the top-level of the module have +the (-> integer? integer?) contract mediating their +interaction; g and the top-level have (-> string?) +mediating their interaction, but there is no contract directly +between f and g. This means that the reference to +f in the body of g is really the top-level +of the module’s responsibility, not g’s. In other words, +the function f has been given to g with +no contract between g and the top-level and thus +the top-level is blamed.

If we wanted to add a contract between g and the +top-level, we can use define/contract’s +#:freevar declaration and see the expected blame:

> (define/contract (f x)
    (-> integer? integer?)
    x)
> (define/contract (g)
    (-> string?)
    #:freevar f (-> integer? integer?)
    (f "not an integer"))
> (g)

f: contract violation

  expected: integer?

  given: "not an integer"

  in: the 1st argument of

      (-> integer? integer?)

  contract from: top-level

  blaming: (function g)

   (assuming the contract is correct)

  at: eval:6:0

Moral: if two values with contracts should interact, + put them in separate modules with contracts at + the module boundary or use #:freevar.

7.9.3 Exists Contracts and Predicates

Much like the eq? example above, #:∃ contracts +can change the behavior of a program.

Specifically, +the null? predicate (and many other predicates) return #f +for #:∃ contracts, and changing one of those contracts to any/c +means that null? might now return #t instead, resulting in +arbitrarily different behavior depending on how this boolean might flow around +in the program.

Moral: Do not use predicates on #:∃ contracts.

7.9.4 Defining Recursive Contracts

When defining a self-referential contract, it is natural to use +define. For example, one might try to write a contract on +streams like this:

> (define stream/c
    (promise/c
     (or/c null?
           (cons/c number? stream/c))))

stream/c: undefined;

 cannot reference an identifier before its definition

  in module: top-level

Unfortunately, this does not work because the value of +stream/c is needed before it is defined. Put another way, all +of the combinators evaluate their arguments eagerly, even though the +values that they accept do not.

Instead, use +
(define stream/c
  (promise/c
   (or/c
    null?
    (cons/c number? (recursive-contract stream/c)))))

The use of recursive-contract delays the evaluation of the +identifier stream/c until after the contract is first +checked, long enough to ensure that stream/c is defined.

See also Checking Properties of Data Structures.

7.9.5 Mixing set! and contract-out

The contract library assumes that variables exported via +contract-out are not assigned to, but does not enforce +it. Accordingly, if you try to set! those variables, you +may be surprised. Consider the following example:

> (module server racket
    (define (inc-x!) (set! x (+ x 1)))
    (define x 0)
    (provide (contract-out [inc-x! (-> void?)]
                           [x integer?])))
> (module client racket
    (require 'server)
  
    (define (print-latest) (printf "x is ~s\n" x))
  
    (print-latest)
    (inc-x!)
    (print-latest))
> (require 'client)

x is 0

x is 0

Both calls to print-latest print 0, even though the +value of x has been incremented (and the change is visible +inside the module x).

To work around this, export accessor functions, rather than +exporting the variable directly, like this:

#lang racket
 
(define (get-x) x)
(define (inc-x!) (set! x (+ x 1)))
(define x 0)
(provide (contract-out [inc-x! (-> void?)]
                       [get-x (-> integer?)]))

Moral: This is a bug that we will address in a future release.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-struct.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-struct.html new file mode 100644 index 00000000..f8205366 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts-struct.html @@ -0,0 +1,107 @@ + +7.5 Contracts on Structures

7.5 Contracts on Structures

Modules deal with structures in two ways. First they export +struct definitions, i.e., the ability to create +structs of a certain kind, to access their fields, to modify +them, and to distinguish structs of this kind against every +other kind of value in the world. Second, on occasion a +module exports a specific struct and wishes to promise that +its fields contain values of a certain kind. This section +explains how to protect structs with contracts for both +uses.

7.5.1 Guarantees for a Specific Value

If your module defines a variable to be a structure value, then you can +specify the structure’s shape using struct/c.

#lang racket
 
(struct posn [x y])
 
(define origin (posn 0 0))
 
(provide
  (contract-out
    [origin (struct/c posn zero? zero?)]))

In this example, the module defines a structure shape for representing +2-dimensional positions and then creates one specific instance: +origin. The export of this instance guarantees that its fields +are 0, i.e., they represent (0,0), on the Cartesian grid.

See also vector/c and similar contract +combinators for (flat) compound data.

7.5.2 Guarantees for All Values

The book How to Design Programs teaches that posns should contain only +numbers in their two fields. With contracts we would enforce this +informal data definition as follows:

#lang racket
(struct posn (x y))
 
(provide
  (contract-out
    [struct posn ((x number?) (y number?))]
    [p-okay posn?]
    [p-sick posn?]))
 
(define p-okay (posn 10 20))
(define p-sick (posn 'a 'b))

This module exports the entire structure definition: posn, +posn?, posn-x, posn-y, +set-posn-x!, and set-posn-y!. Each function enforces +or promises that the two fields of a posn structure are +numbers — when the values flow across the module boundary. Thus, if +a client calls posn on 10 and 'a, the +contract system signals a contract violation.

The creation of p-sick inside of the posn module, +however, does not violate the contracts. The function posn is +used internally, so 'a and 'b don’t cross the module +boundary. Similarly, when p-sick crosses the boundary of +posn, the contract promises a posn? and nothing +else. In particular, this check does not require that the +fields of p-sick are numbers.

The association of contract checking with module boundaries implies that +p-okay and p-sick look alike from a client’s +perspective until the client extracts the pieces:

#lang racket
(require lang/posn)
 
... (posn-x p-sick) ...

Using posn-x is the only way the client can find out what +a posn contains in the x field. The application of +posn-x sends p-sick back into the +posn module and the result value – 'a here – back to +the client, again across the module boundary. At this very point, the contract +system discovers that a promise is broken. Specifically, posn-x +doesn’t return a number but a symbol and is therefore blamed.

This specific example shows that the explanation for a contract violation +doesn’t always pinpoint the source of the error. The good news is that the +error is located in the posn module. The bad news is that the +explanation is misleading. Although it is true that posn-x +produced a symbol instead of a number, it is the fault of the programmer who +created a posn from symbols, i.e., the programmer who added

(define p-sick (posn 'a 'b))

to the module. So, when you are looking for bugs based on contract + violations, keep this example in mind.

If we want to fix the contract for p-sick so that the error +is caught when sick is exported, a single change suffices:

(provide
 (contract-out
  ...
  [p-sick (struct/c posn number? number?)]))

That is, instead of exporting p-sick as a plain +posn?, we use a struct/c contract to enforce +constraints on its components.

7.5.3 Checking Properties of Data Structures

Contracts written using struct/c immediately +check the fields of the data structure, but sometimes this +can have disastrous effects on the performance of a program +that does not, itself, inspect the entire data structure.

As an example, consider the binary search tree +search algorithm. A binary search tree is like a binary +tree, except that the numbers are organized in the tree to +make searching the tree fast. In particular, for each +interior node in the tree, all of the numbers in the left +subtree are smaller than the number in the node, and all of +the numbers in the right subtree are larger than the number +in the node.

We can implement a search function in? that takes +advantage of the structure of the binary search tree. +
#lang racket
 
(struct node (val left right))
 
; determines if `n' is in the binary search tree `b',
; exploiting the binary search tree invariant
(define (in? n b)
  (cond
    [(null? b) #f]
    [else (cond
            [(= n (node-val b))
             #t]
            [(< n (node-val b))
             (in? n (node-left b))]
            [(> n (node-val b))
             (in? n (node-right b))])]))
 
; a predicate that identifies binary search trees
(define (bst-between? b low high)
  (or (null? b)
      (and (<= low (node-val b) high)
           (bst-between? (node-left b) low (node-val b))
           (bst-between? (node-right b) (node-val b) high))))
 
(define (bst? b) (bst-between? b -inf.0 +inf.0))
 
(provide (struct-out node))
(provide
  (contract-out
    [bst? (any/c . -> . boolean?)]
    [in? (number? bst? . -> . boolean?)]))

In a full binary search tree, this means that +the in? function only has to explore a +logarithmic number of nodes.

The contract on in? guarantees that its input +is a binary search tree. But a little careful thought +reveals that this contract defeats the purpose of the binary +search tree algorithm. In particular, consider the +inner cond in the in? +function. This is where the in? function gets +its speed: it avoids searching an entire subtree at each +recursive call. Now compare that to the bst-between? +function. In the case that it returns #t, it +traverses the entire tree, meaning that the speedup +of in? is lost.

In order to fix that, we can employ a new strategy for +checking the binary search tree contract. In particular, if +we only checked the contract on the nodes +that in? looks at, we can still guarantee that +the tree is at least partially well-formed, but without +changing the complexity.

To do that, we need to use struct/dc to define +bst-between?. Like struct/c, struct/dc defines a +contract for a structure. Unlike +struct/c, it allows fields to be marked as lazy, so that +the contracts are only checked when the matching selector is called. +Also, it does not allow mutable fields to be marked as lazy.

The struct/dc form accepts a contract for each +field of the struct and returns a contract on the +struct. More interestingly, struct/dc allows us to write dependent +contracts, i.e., contracts where some of the contracts on +the fields depend on the values of other fields. We can use +this to define the binary search tree contract:

#lang racket
 
(struct node (val left right))
 
; determines if `n' is in the binary search tree `b'
(define (in? n b) ... as before ...)
 
; bst-between : number number -> contract
; builds a contract for binary search trees
; whose values are between low and high
(define (bst-between/c low high)
  (or/c null?
        (struct/dc node [val (between/c low high)]
                        [left (val) #:lazy (bst-between/c low val)]
                        [right (val) #:lazy (bst-between/c val high)])))
 
(define bst/c (bst-between/c -inf.0 +inf.0))
 
(provide (struct-out node))
(provide
  (contract-out
    [bst/c contract?]
    [in? (number? bst/c . -> . boolean?)]))

In general, each use of struct/dc must name the +fields and then specify contracts for each field. In the +above, the val field is a contract that accepts +values between low and high. +The left and right fields are +dependent on the value of the val field, +indicated by their second sub-expressions. They are +also marked with the #:lazy keyword to indicate +that they should be checked only when the appropriate +accessor is called on the struct instance. Their contracts +are built by recursive calls to +the bst-between/c function. Taken together, +this contract ensures the same thing that +the bst-between? function checked in the +original example, but here the checking only happens +as in? explores the tree.

Although this contract improves the performance +of in?, restoring it to the logarithmic +behavior that the contract-less version had, it is still +imposes a fairly large constant overhead. So, the contract +library also provides define-opt/c that brings +down that constant factor by optimizing its body. Its shape +is just like the define above. It expects its +body to be a contract and then optimizes that contract.

(define-opt/c (bst-between/c low high)
  (or/c null?
        (struct/dc node [val (between/c low high)]
                        [left (val) #:lazy (bst-between/c low val)]
                        [right (val) #:lazy (bst-between/c val high)])))
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts.html new file mode 100644 index 00000000..35720e0a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/contracts.html @@ -0,0 +1,3 @@ + +7 Contracts

7 Contracts

This chapter provides a gentle introduction to Racket’s +contract system.

+Contracts in The Racket Reference provides more on contracts.

    7.1 Contracts and Boundaries

      7.1.1 Contract Violations

      7.1.2 Experimenting with Contracts and Modules

      7.1.3 Experimenting with Nested Contract Boundaries

    7.2 Simple Contracts on Functions

      7.2.1 Styles of ->

      7.2.2 Using define/contract and ->

      7.2.3 any and any/c

      7.2.4 Rolling Your Own Contracts

      7.2.5 Contracts on Higher-order Functions

      7.2.6 Contract Messages with “???”

      7.2.7 Dissecting a contract error message

    7.3 Contracts on Functions in General

      7.3.1 Optional Arguments

      7.3.2 Rest Arguments

      7.3.3 Keyword Arguments

      7.3.4 Optional Keyword Arguments

      7.3.5 Contracts for case-lambda

      7.3.6 Argument and Result Dependencies

      7.3.7 Checking State Changes

      7.3.8 Multiple Result Values

      7.3.9 Fixed but Statically Unknown Arities

    7.4 Contracts: A Thorough Example

    7.5 Contracts on Structures

      7.5.1 Guarantees for a Specific Value

      7.5.2 Guarantees for All Values

      7.5.3 Checking Properties of Data Structures

    7.6 Abstract Contracts using #:exists and #:∃

    7.7 Additional Examples

      7.7.1 A Customer-Manager Component

      7.7.2 A Parameteric (Simple) Stack

      7.7.3 A Dictionary

      7.7.4 A Queue

    7.8 Building New Contracts

      7.8.1 Contract Struct Properties

      7.8.2 With all the Bells and Whistles

    7.9 Gotchas

      7.9.1 Contracts and eq?

      7.9.2 Contract boundaries and define/contract

      7.9.3 Exists Contracts and Predicates

      7.9.4 Defining Recursive Contracts

      7.9.5 Mixing set! and contract-out

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/control.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/control.html new file mode 100644 index 00000000..7553da35 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/control.html @@ -0,0 +1,4 @@ + +10 Exceptions and Control

10 Exceptions and Control

Racket provides an especially rich set of control operations—not +only operations for raising and catching exceptions, but also +operations for grabbing and restoring portions of a computation.

    10.1 Exceptions

    10.2 Prompts and Aborts

    10.3 Continuations

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/conts.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/conts.html new file mode 100644 index 00000000..408a2561 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/conts.html @@ -0,0 +1,32 @@ + +10.3 Continuations

10.3 Continuations

A continuation is a value that encapsulates a piece of an +expression’s evaluation context. The call-with-composable-continuation +function captures the current continuation starting outside +the current function call and running up to the nearest enclosing +prompt. (Keep in mind that each REPL interaction is implicitly +wrapped in a prompt.)

For example, in

(+ 1 (+ 1 (+ 1 0)))

at the point where 0 is evaluated, the expression context +includes three nested addition expressions. We can grab that context by +changing 0 to grab the continuation before returning 0:

> (define saved-k #f)
> (define (save-it!)
    (call-with-composable-continuation
     (lambda (k) ; k is the captured continuation
       (set! saved-k k)
       0)))
> (+ 1 (+ 1 (+ 1 (save-it!))))

3

The continuation saved in save-k encapsulates the +program context (+ 1 (+ 1 (+ 1 ?))), where ? +represents a place to plug in a result value—because that was the +expression context when save-it! was called. The +continuation is encapsulated so that it behaves like the +function (lambda (v) (+ 1 (+ 1 (+ 1 v)))):

> (saved-k 0)

3

> (saved-k 10)

13

> (saved-k (saved-k 0))

6

The continuation captured by +call-with-composable-continuation is determined dynamically, +not syntactically. For example, with

> (define (sum n)
    (if (zero? n)
        (save-it!)
        (+ n (sum (sub1 n)))))
> (sum 5)

15

the continuation in saved-k becomes (lambda (x) (+ 5 (+ 4 (+ 3 (+ 2 (+ 1 x)))))):

> (saved-k 0)

15

> (saved-k 10)

25

A more traditional continuation operator in Racket (or Scheme) is +call-with-current-continuation, which is usually abbreviated +call/cc. It is like +call-with-composable-continuation, but applying the captured +continuation first aborts (to the current prompt) before +restoring the saved continuation. In addition, Scheme systems +traditionally support a single prompt at the program start, instead of +allowing new prompts via +call-with-continuation-prompt. Continuations as in Racket +are sometimes called delimited continuations, since a +program can introduce new delimiting prompts, and continuations as +captured by call-with-composable-continuation are sometimes +called composable continuations, because they do not have a +built-in abort.

For an example of how continuations are useful, see +More: Systems Programming with Racket. For specific +control operators that have more convenient names than the primitives +described here, see racket/control.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/datatypes.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/datatypes.html new file mode 100644 index 00000000..e5022a9a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/datatypes.html @@ -0,0 +1,5 @@ + +3 Built-In Datatypes

3 Built-In Datatypes

The previous chapter introduced some of +Racket’s built-in datatypes: numbers, booleans, strings, lists, and +procedures. This section provides a more complete coverage of the +built-in datatypes for simple forms of data.

    3.1 Booleans

    3.2 Numbers

    3.3 Characters

    3.4 Strings (Unicode)

    3.5 Bytes and Byte Strings

    3.6 Symbols

    3.7 Keywords

    3.8 Pairs and Lists

    3.9 Vectors

    3.10 Hash Tables

    3.11 Boxes

    3.12 Void and Undefined

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/default-ports.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/default-ports.html new file mode 100644 index 00000000..3d9ffdf9 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/default-ports.html @@ -0,0 +1,13 @@ + +8.2 Default Ports

8.2 Default Ports

For most simple I/O functions, the target port is an optional +argument, and the default is the current input port or +current output port. Furthermore, error messages are written +to the current error port, which is an output port. The +current-input-port, current-output-port, and +current-error-port functions return the corresponding current +ports.

Examples:
> (display "Hi")

Hi

> (display "Hi" (current-output-port)) ; the same

Hi

If you start the racket program in a terminal, then the +current input, output, and error ports are all connected to the +terminal. More generally, they are connected to the OS-level stdin, +stdout, and stderr. In this guide, the examples show output written to +stdout in purple, and output written to stderr in red italics.

Examples:
(define (swing-hammer)
  (display "Ouch!" (current-error-port)))
> (swing-hammer)

Ouch!

The current-port functions are actually parameters, which means +that their values can be set with parameterize.

See Dynamic Binding: parameterize for an introduction to parameters.

Example:
> (let ([s (open-output-string)])
    (parameterize ([current-error-port s])
      (swing-hammer)
      (swing-hammer)
      (swing-hammer))
    (get-output-string s))

"Ouch!Ouch!Ouch!"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/define-struct.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/define-struct.html new file mode 100644 index 00000000..3077dea0 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/define-struct.html @@ -0,0 +1,170 @@ + +5 Programmer-Defined Datatypes

5 Programmer-Defined Datatypes

+Structures in The Racket Reference also documents structure types.

New datatypes are normally created with the struct +form, which is the topic of this chapter. The class-based object +system, which we defer to Classes and Objects, offers an alternate +mechanism for creating new datatypes, but even classes and objects are +implemented in terms of structure types.

5.1 Simple Structure Types: struct

+Defining Structure Types: struct in The Racket Reference also documents struct.

To a first approximation, the syntax of struct is

(struct struct-id (field-id ...))

Examples:

(struct posn (x y))

The struct form binds struct-id and a number of +identifiers that are built from struct-id and the +field-ids:

  • struct-id : a constructor function that +takes as many arguments as the number of field-ids, +and returns an instance of the structure type.

    Example:
    > (posn 1 2)

    #<posn>

  • struct-id? : a predicate +function that takes a single argument and returns #t +if it is an instance of the structure type, #f +otherwise.

    Examples:
    > (posn? 3)

    #f

    > (posn? (posn 1 2))

    #t

  • struct-id-field-id : for +each field-id, an accessor that extracts +the value of the corresponding field from an instance of the +structure type.

    Examples:
    > (posn-x (posn 1 2))

    1

    > (posn-y (posn 1 2))

    2

  • struct:struct-id : a +structure type descriptor, which is a value that +represents the structure type as a first-class value (with +#:super, as discussed later in +More Structure Type Options).

A struct form places no constraints on the kinds of +values that can appear for fields in an instance of the structure +type. For example, (posn "apple" #f) produces an +instance of posn, even though "apple" and +#f are not valid coordinates for the obvious uses of +posn instances. Enforcing constraints on field values, such +as requiring them to be numbers, is normally the job of a contract, as +discussed later in Contracts.

5.2 Copying and Update

The struct-copy form clones a structure and optionally +updates specified fields in the clone. This process is sometimes +called a functional update, because the result is a +structure with updated field values. but the original structure is not +modified.

(struct-copy struct-id struct-expr [field-id expr] ...)

The struct-id that appears after struct-copy must +be a structure type name bound by struct (i.e., the +name that cannot be used directly as an expression). The +struct-expr must produce an instance of the structure type. +The result is a new instance of the structure type that is like the old +one, except that the field indicated by each field-id gets +the value of the corresponding expr.

Examples:
> (define p1 (posn 1 2))
> (define p2 (struct-copy posn p1 [x 3]))
> (list (posn-x p2) (posn-y p2))

'(3 2)

> (list (posn-x p1) (posn-y p1))

'(1 2)

5.3 Structure Subtypes

An extended form of struct can be used to define a +structure subtype, which is a structure type that extends an +existing structure type:

(struct struct-id super-id (field-id ...))

The super-id must be a structure type name bound by +struct (i.e., the name that cannot be used directly as +an expression).

Examples:
(struct posn (x y))
(struct 3d-posn posn (z))

A structure subtype inherits the fields of its supertype, and the +subtype constructor accepts the values for the subtype fields after +values for the supertype fields. An instance of a structure subtype +can be used with the predicate and accessors of the +supertype.

Examples:
> (define p (3d-posn 1 2 3))
> p

#<3d-posn>

> (posn? p)

#t

> (3d-posn-z p)

3

; a 3d-posn has an x field, but there is no 3d-posn-x selector:
> (3d-posn-x p)

3d-posn-x: undefined;

 cannot reference an identifier before its definition

  in module: top-level

; use the supertype's posn-x selector to access the x field:
> (posn-x p)

1

5.4 Opaque versus Transparent Structure Types

With a structure type definition like

(struct posn (x y))

an instance of the structure type prints in a way that does not show +any information about the fields’ values. That is, structure types by +default are opaque. If the accessors and mutators of a +structure type are kept private to a module, then no other module can +rely on the representation of the type’s instances.

To make a structure type transparent, use the +#:transparent keyword after the field-name sequence:

(struct posn (x y)
        #:transparent)

 

> (posn 1 2)

(posn 1 2)

An instance of a transparent structure type prints like a call to the +constructor, so that it shows the structures field values. A +transparent structure type also allows reflective operations, such as +struct? and struct-info, to be used on its instances +(see Reflection and Dynamic Evaluation).

Structure types are opaque by default, because opaque structure +instances provide more encapsulation guarantees. That is, a library +can use an opaque structure to encapsulate data, and clients of the +library cannot manipulate the data in the structure except as allowed +by the library.

5.5 Structure Comparisons

A generic equal? comparison automatically recurs on the +fields of a transparent structure type, but equal? defaults +to mere instance identity for opaque structure types:

(struct glass (width height) #:transparent)

 

> (equal? (glass 1 2) (glass 1 2))

#t

(struct lead (width height))

 

> (define slab (lead 1 2))
> (equal? slab slab)

#t

> (equal? slab (lead 1 2))

#f

To support instances comparisons via equal? without making +the structure type transparent, you can use the #:methods +keyword, gen:equal+hash, and implement three methods:

(struct lead (width height)
  #:methods
  gen:equal+hash
  [(define (equal-proc a b equal?-recur)
     ; compare a and b
     (and (equal?-recur (lead-width a) (lead-width b))
          (equal?-recur (lead-height a) (lead-height b))))
   (define (hash-proc a hash-recur)
     ; compute primary hash code of a
     (+ (hash-recur (lead-width a))
        (* 3 (hash-recur (lead-height a)))))
   (define (hash2-proc a hash2-recur)
     ; compute secondary hash code of a
     (+ (hash2-recur (lead-width a))
             (hash2-recur (lead-height a))))])

 

> (equal? (lead 1 2) (lead 1 2))

#t

The first function in the list implements the equal? test on +two leads; the third argument to the function is used instead +of equal? for recursive equality testing, so that data cycles +can be handled correctly. The other two functions compute primary and +secondary hash codes for use with hash tables:

> (define h (make-hash))
> (hash-set! h (lead 1 2) 3)
> (hash-ref h (lead 1 2))

3

> (hash-ref h (lead 2 1))

hash-ref: no value found for key

  key: #<lead>

The first function provided with gen:equal+hash is not +required to recursively compare the fields of the structure. For +example, a structure type representing a set might implement equality +by checking that the members of the set are the same, independent of +the order of elements in the internal representation. Just take care +that the hash functions produce the same value for any two structure +types that are supposed to be equivalent.

5.6 Structure Type Generativity

Each time that a struct form is evaluated, it +generates a structure type that is distinct from all existing +structure types, even if some other structure type has the same name +and fields.

This generativity is useful for enforcing abstractions and +implementing programs such as interpreters, but beware of placing a +struct form in positions that are evaluated multiple +times.

Examples:
(define (add-bigger-fish lst)
  (struct fish (size) #:transparent) ; new every time
  (cond
   [(null? lst) (list (fish 1))]
   [else (cons (fish (* 2 (fish-size (car lst))))
               lst)]))
> (add-bigger-fish null)

(list (fish 1))

> (add-bigger-fish (add-bigger-fish null))

fish-size: contract violation

  expected: fish?

  given: (fish 1)

(struct fish (size) #:transparent)
(define (add-bigger-fish lst)
  (cond
   [(null? lst) (list (fish 1))]
   [else (cons (fish (* 2 (fish-size (car lst))))
               lst)]))

 

> (add-bigger-fish (add-bigger-fish null))

(list (fish 2) (fish 1))

5.7 Prefab Structure Types

Although a transparent structure type prints in a way that +shows its content, the printed form of the structure cannot be used in +an expression to get the structure back, unlike the printed form of a +number, string, symbol, or list.

A prefab (“previously fabricated”) structure type is a +built-in type that is known to the Racket printer and expression +reader. Infinitely many such types exist, and they are indexed by +name, field count, supertype, and other such details. The printed form +of a prefab structure is similar to a vector, but it starts +#s instead of just #, and the first element in the +printed form is the prefab structure type’s name.

The following examples show instances of the sprout +prefab structure type that has one field. The first instance has a +field value 'bean, and the second has field value +'alfalfa:

> '#s(sprout bean)

'#s(sprout bean)

> '#s(sprout alfalfa)

'#s(sprout alfalfa)

Like numbers and strings, prefab structures are “self-quoting,” so +the quotes above are optional:

> #s(sprout bean)

'#s(sprout bean)

When you use the #:prefab keyword with +struct, instead of generating a new structure type, +you obtain bindings that work with the existing prefab structure type:

> (define lunch '#s(sprout bean))
> (struct sprout (kind) #:prefab)
> (sprout? lunch)

#t

> (sprout-kind lunch)

'bean

> (sprout 'garlic)

'#s(sprout garlic)

The field name kind above does not matter for finding +the prefab structure type; only the name sprout and the +number of fields matters. At the same time, the prefab structure type +sprout with three fields is a different structure type +than the one with a single field:

> (sprout? #s(sprout bean #f 17))

#f

> (struct sprout (kind yummy? count) #:prefab) ; redefine
> (sprout? #s(sprout bean #f 17))

#t

> (sprout? lunch)

#f

A prefab structure type can have another prefab structure type as its +supertype, it can have mutable fields, and it can have auto +fields. Variations in any of these dimensions correspond to different +prefab structure types, and the printed form of the structure type’s +name encodes all of the relevant details.

> (struct building (rooms [location #:mutable]) #:prefab)
> (struct house building ([occupied #:auto]) #:prefab
    #:auto-value 'no)
> (house 5 'factory)

'#s((house (1 no) building 2 #(1)) 5 factory no)

Every prefab structure type is transparentbut even +less abstract than a transparent type, because instances can be +created without any access to a particular structure-type declaration +or existing examples. Overall, the different options for structure +types offer a spectrum of possibilities from more abstract to more +convenient:

  • Opaque (the default) : Instances cannot be inspected or +forged without access to the structure-type declaration. As +discussed in the next section, constructor guards and +properties can be attached to the structure type to +further protect or to specialize the behavior of its +instances.

  • Transparent : Anyone can inspect or create an instance +without access to the structure-type declaration, which means +that the value printer can show the content of an instance. All +instance creation passes through a constructor guard, +however, so that the content of an instance can be controlled, +and the behavior of instances can be specialized through +properties. Since the structure type is generated by its +definition, instances cannot be manufactured simply through the +name of the structure type, and therefore cannot be generated +automatically by the expression reader.

  • Prefab : Anyone can inspect or create an instance at any +time, without prior access to a structure-type declaration or +an example instance. Consequently, the expression reader can +manufacture instances directly. The instance cannot have a +constructor guard or properties.

Since the expression reader can generate prefab instances, they +are useful when convenient serialization is more important than +abstraction. Opaque and transparent structures also can +be serialized, however, if they are defined with +serializable-struct as described in +Datatypes and Serialization.

5.8 More Structure Type Options

The full syntax of struct supports many options, both +at the structure-type level and at the level of individual fields:

(struct struct-id maybe-super (field ...)
        struct-option ...)
 
maybe-super = 
  | super-id
     
field = field-id
  | [field-id field-option ...]

A struct-option always starts with a keyword:

#:mutable

Causes all fields of the structure to be mutable, and introduces + for each field-id a mutator + set-struct-id-field-id! + that sets the value of the corresponding field in an instance of + the structure type.

Examples:
> (struct dot (x y) #:mutable)
(define d (dot 1 2))
> (dot-x d)

1

> (set-dot-x! d 10)
> (dot-x d)

10

The #:mutable option can also be used as a +field-option, in which case it makes an individual field +mutable.

Examples:
> (struct person (name [age #:mutable]))
(define friend (person "Barney" 5))
> (set-person-age! friend 6)
> (set-person-name! friend "Mary")

set-person-name!: undefined;

 cannot reference an identifier before its definition

  in module: top-level

#:transparent

Controls reflective access to structure instances, as discussed +in a previous section, Opaque versus Transparent Structure Types.

#:inspector inspector-expr

Generalizes #:transparent to support more controlled access +to reflective operations.

#:prefab

Accesses a built-in structure type, as discussed +in a previous section, Prefab Structure Types.

#:auto-value auto-expr

Specifies a value to be used for all automatic fields in the +structure type, where an automatic field is indicated by the +#:auto field option. The constructor procedure does not +accept arguments for automatic fields. Automatic fields are +implicitly mutable (via reflective operations), but mutator +functions are bound only if #:mutable is also specified.

Examples:
> (struct posn (x y [z #:auto])
               #:transparent
               #:auto-value 0)
> (posn 1 2)

(posn 1 2 0)

#:guard guard-expr

Specifies a + constructor guard procedure to be called whenever an + instance of the structure type is created. The guard takes as many + arguments as non-automatic fields in the structure type, plus one + more for the name of the instantiated type (in case a sub-type is + instantiated, in which case it’s best to report an error using the + sub-type’s name). The guard should return the same number of values + as given, minus the name argument. The guard can raise an exception + if one of the given arguments is unacceptable, or it can convert an + argument.

Examples:
> (struct thing (name)
          #:transparent
          #:guard (lambda (name type-name)
                    (cond
                      [(string? name) name]
                      [(symbol? name) (symbol->string name)]
                      [else (error type-name
                                   "bad name: ~e"
                                   name)])))
> (thing "apple")

(thing "apple")

> (thing 'apple)

(thing "apple")

> (thing 1/2)

thing: bad name: 1/2

The guard is called even when subtype instances are created. In that + case, only the fields accepted by the constructor are provided to + the guard (but the subtype’s guard gets both the original fields and + fields added by the subtype).

Examples:
> (struct person thing (age)
          #:transparent
          #:guard (lambda (name age type-name)
                    (if (negative? age)
                        (error type-name "bad age: ~e" age)
                        (values name age))))
> (person "John" 10)

(person "John" 10)

> (person "Mary" -1)

person: bad age: -1

> (person 10 10)

person: bad name: 10

#:methods interface-expr [body ...]

Associates method definitions for the structure type that correspond +to a generic interface. For example, implementing the +methods for gen:dict allows instances of a structure +type to be used as dictionaries. Implementing +the methods for gen:custom-write allows the customization +of how an instance of a structure type is displayed.

Examples:
> (struct cake (candles)
          #:methods gen:custom-write
          [(define (write-proc cake port mode)
             (define n (cake-candles cake))
             (show "   ~a   ~n" n #\. port)
             (show " .-~a-. ~n" n #\| port)
             (show " | ~a | ~n" n #\space port)
             (show "---~a---~n" n #\- port))
           (define (show fmt n ch port)
             (fprintf port fmt (make-string n ch)))])
> (display (cake 5))

   .....   

 .-|||||-.

 |       |

-----------

#:property prop-expr val-expr

Associates a property and value with the structure type. + For example, the prop:procedure property allows a + structure instance to be used as a function; the property value + determines how a call is implemented when using the structure as a + function.

Examples:
> (struct greeter (name)
          #:property prop:procedure
                     (lambda (self other)
                       (string-append
                        "Hi " other
                        ", I'm " (greeter-name self))))
(define joe-greet (greeter "Joe"))
> (greeter-name joe-greet)

"Joe"

> (joe-greet "Mary")

"Hi Mary, I'm Joe"

> (joe-greet "John")

"Hi John, I'm Joe"

#:super super-expr

An alternative to supplying a super-id next to +struct-id. Instead of the name of a structure type (which is +not an expression), super-expr should produce a +structure type descriptor value. An advantage of +#:super is that structure type descriptors are values, so +they can be passed to procedures.

Examples:
(define (raven-constructor super-type)
  (struct raven ()
          #:super super-type
          #:transparent
          #:property prop:procedure (lambda (self)
                                      'nevermore))
  raven)
> (let ([r ((raven-constructor struct:posn) 1 2)])
    (list r (r)))

(list (raven 1 2) 'nevermore)

> (let ([r ((raven-constructor struct:thing) "apple")])
    (list r (r)))

(list (raven "apple") 'nevermore)

+Structures in The Racket Reference provides more on structure types.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/define.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/define.html new file mode 100644 index 00000000..b1a7eb83 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/define.html @@ -0,0 +1,38 @@ + +4.5 Definitions: define

4.5 Definitions: define

A basic definition has the form

(define id expr)

in which case id is bound to the result of +expr.

Examples:
(define salutation (list-ref '("Hi" "Hello") (random 2)))
> salutation

"Hi"

4.5.1 Function Shorthand

The define form also supports a shorthand for function +definitions:

(define (id arg ...) body ...+)

which is a shorthand for

(define id (lambda (arg ...) body ...+))

Examples:
(define (greet name)
  (string-append salutation ", " name))
> (greet "John")

"Hi, John"

(define (greet first [surname "Smith"] #:hi [hi salutation])
  (string-append hi ", " first " " surname))

 

> (greet "John")

"Hi, John Smith"

> (greet "John" #:hi "Hey")

"Hey, John Smith"

> (greet "John" "Doe")

"Hi, John Doe"

The function shorthand via define also supports a +rest argument (i.e., a final argument to collect extra +arguments in a list):

(define (id arg ... . rest-id) body ...+)

which is a shorthand

(define id (lambda (arg ... . rest-id) body ...+))

Examples:
(define (avg . l)
  (/ (apply + l) (length l)))
> (avg 1 2 3)

2

4.5.2 Curried Function Shorthand

Consider the following make-add-suffix function that takes a +string and returns another function that takes a string:

(define make-add-suffix
  (lambda (s2)
    (lambda (s) (string-append s s2))))

 

Although it’s not common, result of make-add-suffix could be +called directly, like this:

> ((make-add-suffix "!") "hello")

"hello!"

In a sense, make-add-suffix is a function that takes two +arguments, but it takes them one at a time. A function that takes some +of its arguments and returns a function to consume more is sometimes +called a curried function.

Using the function-shorthand form of define, +make-add-suffix can be written equivalently as

(define (make-add-suffix s2)
  (lambda (s) (string-append s s2)))

This shorthand reflects the shape of the function call +(make-add-suffix "!"). The define form further +supports a shorthand for defining curried functions that reflects +nested function calls:

(define ((make-add-suffix s2) s)
  (string-append s s2))

 

> ((make-add-suffix "!") "hello")

"hello!"

(define louder (make-add-suffix "!"))
(define less-sure (make-add-suffix "?"))

 

> (less-sure "really")

"really?"

> (louder "really")

"really!"

The full syntax of the function shorthand for define is as follows:

(define (head args) body ...+)
 
head = id
  | (head args)
     
args = arg ...
  | arg ... . rest-id

The expansion of this shorthand has one nested lambda form +for each head in the definition, where the innermost +head corresponds to the outermost lambda.

4.5.3 Multiple Values and define-values

A Racket expression normally produces a single result, but some +expressions can produce multiple results. For example, +quotient and remainder each produce a single value, +but quotient/remainder produces the same two values at once:

> (quotient 13 3)

4

> (remainder 13 3)

1

> (quotient/remainder 13 3)

4

1

As shown above, the REPL prints each result value on its own +line.

Multiple-valued functions can be implemented in terms of the +values function, which takes any number of values and +returns them as the results:

> (values 1 2 3)

1

2

3

(define (split-name name)
  (let ([parts (regexp-split " " name)])
    (if (= (length parts) 2)
        (values (list-ref parts 0) (list-ref parts 1))
        (error "not a <first> <last> name"))))

 

> (split-name "Adam Smith")

"Adam"

"Smith"

The define-values form binds multiple identifiers at once to +multiple results produced from a single expression:

(define-values (id ...) expr)

The number of results produced by the expr must match the +number of ids.

Examples:
(define-values (given surname) (split-name "Adam Smith"))
> given

"Adam"

> surname

"Smith"

A define form (that is not a function shorthand) is +equivalent to a define-values form with a single id.

+Definitions: define, define-syntax, ... in The Racket Reference provides more on definitions.

4.5.4 Internal Definitions

When the grammar for a syntactic form specifies body, then +the corresponding form can be either a definition or an expression. +A definition as a body is an internal definition.

Expressions and internal definitions in a body sequence can +be mixed, as long as the last body is an expression.

For example, the syntax of lambda is

(lambda gen-formals
  body ...+)

so the following are valid instances of the grammar:

(lambda (f)                ; no definitions
  (printf "running\n")
  (f 0))
 
(lambda (f)                ; one definition
  (define (log-it what)
    (printf "~a\n" what))
  (log-it "running")
  (f 0)
  (log-it "done"))
 
(lambda (f n)              ; two definitions
  (define (call n)
    (if (zero? n)
        (log-it "done")
        (begin
          (log-it "running")
          (f n)
          (call (- n 1)))))
  (define (log-it what)
    (printf "~a\n" what))
  (call n))

Internal definitions in a particular body sequence are +mutually recursive; that is, any definition can refer to any other +definition—as long as the reference isn’t actually evaluated before +its definition takes place. If a definition is referenced too early, +an error occurs.

Examples:
(define (weird)
  (define x x)
  x)
> (weird)

x: undefined;

 cannot use before initialization

A sequence of internal definitions using just define is +easily translated to an equivalent letrec form (as introduced +in the next section). However, other definition forms can appear as a +body, including define-values, struct (see +Programmer-Defined Datatypes) or define-syntax (see +Macros).

+Internal Definitions in The Racket Reference documents the fine points of internal definitions.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/dialects.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/dialects.html new file mode 100644 index 00000000..5db265aa --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/dialects.html @@ -0,0 +1,13 @@ + +23 Dialects of Racket and Scheme

23 Dialects of Racket and Scheme

We use “Racket” to refer to a specific dialect of the Lisp language, +and one that is based on the Scheme branch of the Lisp family. +Despite Racket’s similarity to Scheme, the #lang prefix on +modules is a particular feature of Racket, and programs that start +with #lang are unlikely to run in other implementations of +Scheme. At the same time, programs that do not start with #lang +do not work with the default mode of most Racket tools.

“Racket” is not, however, the only dialect of Lisp that is supported +by Racket tools. On the contrary, Racket tools are designed to support +multiple dialects of Lisp and even multiple languages, which allows +the Racket tool suite to serve multiple communities. Racket also gives +programmers and researchers the tools they need to explore and create +new languages.

    23.1 More Rackets

    23.2 Standards

      23.2.1 R5RS

      23.2.2 R6RS

    23.3 Teaching

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/doc-bibliography.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/doc-bibliography.html new file mode 100644 index 00000000..37078956 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/doc-bibliography.html @@ -0,0 +1,2 @@ + +Bibliography

Bibliography

[Goldberg04] David Goldberg, Robert Bruce Findler, and Matthew Flatt, “Super and Inner—Together at Last!,” Object-Oriented Programming, Languages, Systems, and Applications, 2004. http://www.cs.utah.edu/plt/publications/oopsla04-gff.pdf
[Flatt02] Matthew Flatt, “Composable and Compilable Macros: You Want it When?,” International Conference on Functional Programming, 2002.
[Flatt06] Matthew Flatt, Robert Bruce Findler, and Matthias Felleisen, “Scheme with Classes, Mixins, and Traits (invited tutorial),” Asian Symposium on Programming Languages and Systems, 2006. http://www.cs.utah.edu/plt/publications/aplas06-fff.pdf
[Mitchell02] Richard Mitchell and Jim McKim, Design by Contract, by Example. 2002.
[Sitaram05] Dorai Sitaram, “pregexp: Portable Regular Expressions for Scheme and Common Lisp.” 2002. http://www.ccs.neu.edu/home/dorai/pregexp/

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/doc-index.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/doc-index.html new file mode 100644 index 00000000..44aff935 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/doc-index.html @@ -0,0 +1,17 @@ + +Index

Index

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

 

"main.rkt"
#!
.bat
.zo
3m
A Customer-Manager Component
A Dictionary
A Note to Readers with Lisp/Scheme Experience
A Parameteric (Simple) Stack
A Queue
Abbreviating quote with '
aborts
Abstract Contracts using #:exists and #:∃
accessor
Adding Collections
Adding Contracts to Signatures
Adding Contracts to Units
Additional Examples
Alternation
An Aside on Indenting Code
An Extended Example
And More
Anonymous Functions with lambda
any and any/c
Argument and Result Dependencies
Arity-Sensitive Functions: case-lambda
assertions
Assignment and Redefinition
Assignment: set!
attached
available
backreference
Backreferences
Backtracking
backtracking
Basic Assertions
BC
benchmarking
blocking
Booleans
box
Boxes
bracketed +character class
Breaking an Iteration
Buffered Asynchronous Channels
Building New Contracts
Building Your Own Synchronization Patterns
Built-In Datatypes
byte
byte string
Bytecode, Machine Code, and Just-in-Time (JIT) Compilers
Bytes and Byte Strings
Bytes, Characters, and Encodings
call-by-reference
CGC
Chaining Tests: cond
Channels
character
character class
Characters
Characters and Character Classes
Checking Properties of Data Structures
Checking State Changes
Class Contracts
Classes and Objects
cloister
Cloisters
closures
Clustering
Clusters
Code inspectors
Code Inspectors for Trusted and Untrusted Code
collection
Combining Tests: and and or
Command-Line Tools
Command-Line Tools and Your Editor of Choice
comments
Compilation and Configuration: raco
Compile and Run-Time Phases
Compile-Time Instantiation
complex
components
composable continuations
concurrency
Concurrency and Synchronization
Conditionals
Conditionals with if, and, or, and cond
conservative garbage collector
constructor
constructor guard
continuation
Continuations
Contract boundaries and define/contract
contract +combinator
Contract Messages with “???”
Contract Struct Properties
Contract Violations
Contracts
Contracts and Boundaries
Contracts and eq?
Contracts for case-lambda
Contracts for Units
Contracts on Functions in General
Contracts on Higher-order Functions
Contracts on Structures
Contracts: A Thorough Example
Controlling the Scope of External Names
Copying and Update
Creating and Installing Namespaces
Creating Executables
Creating Languages
Creating Stand-Alone Executables
CS
current continuation
current namespace
Curried Function Shorthand
Datatypes and Serialization
Declaration versus Instantiation
Declaring a Rest Argument
Declaring Keyword Arguments
Declaring Optional Arguments
Default Ports
default +prompt tag
define-syntax and syntax-rules
define-syntax-rule
Defining new #lang Languages
Defining Recursive Contracts
Definitions
Definitions and Interactions
definitions area
Definitions: define
delimited continuations
Designating a #lang Language
destructing +bind
Dialects of Racket and Scheme
Dissecting a contract error message
Distributed Places
domain
Dynamic Binding: parameterize
Effects After: begin0
Effects Before: begin
Effects If...: when and unless
Emacs
eval
Evaluation Order and Arity
exception
Exceptions
Exceptions and Control
Exists Contracts and Predicates
expander
expands
Experimenting with Contracts and Modules
Experimenting with Nested Contract Boundaries
Exports: provide
Expressions and Definitions
Extended Example: Call-by-Reference Functions
External Class Contracts
Final, Augment, and Inner
First-Class Units
Fixed but Statically Unknown Arities
fixnum
Fixnum and Flonum Optimizations
flat named +contracts
flonum
for and for*
for/and and for/or
for/first and for/last
for/fold and for*/fold
for/list and for*/list
for/vector and for*/vector
Foreign Pointers
Function Calls (Procedure Applications)
Function Calls (Procedure Applications)
Function Calls, Again
Function Shorthand
Function-Call Optimizations
functional update
Functions (Procedures): lambda
futures
General Macro Transformers
General Phase Levels
generational garbage collector
Gotchas
Graphics and GUIs
greedy
Guarantees for a Specific Value
Guarantees for All Values
Guidelines for Using Assignment
hash table
Hash Tables
Highlighting
I/O Patterns
identifier macro
Identifier Macros
identifier +syntax object
Identifiers
Identifiers and Binding
implicit begin
Implicit Form Bindings
Imports: require
incremental +garbage-collection
Indentation
index pairs
Inherit and Super in Traits
Initialization Arguments
Input and Output
Installing a Language
instantiated
instantiates
instantiation
integer
Interacting with Racket
Interactive evaluation
Interactive Mode
Interfaces
Internal and External Names
Internal Class Contracts
Internal Definitions
invoked
Invoking Units
Iteration Performance
Iterations and Comprehensions
JIT
just-in-time
keyword
Keyword Arguments
Keyword Arguments
Keywords
Lazy Visits via Available Modules
letrec Performance
Lexical Scope
Library Collections
link
Linking Units
list
List Iteration from Scratch
Lists and Racket Syntax
Lists, Iteration, and Recursion
Load Mode
Local Binding
Local Binding with +define, let, and let*
Local Scopes
Lookahead
Lookbehind
Looking Ahead and Behind
macro
macro pattern +variables
macro transformer
Macro Transformer Procedures
macro-generating +macro
Macro-Generating Macros
Macros
Main and Test Submodules
main submodule
major collections
Major Modes
Manipulating Namespaces
Matching Regexp Patterns
Matching Sequences
Memory Management
meta-compile phase level
metacharacters
metasequences
Methods
minor collections
Minor Modes
Miscellaneous
mixin
Mixing Patterns and Expressions: syntax-case
Mixing set! and contract-out
Mixins
Mixins and Interfaces
Module Basics
Module Instantiations and Visits
module language
Module Languages
Module Mode
module path
Module Paths
Module References Within a Collection
Module Syntax
Module-Handling Configuration
Modules
Modules and Macros
Modules and Performance
More Libraries
More Rackets
More Structure Type Options
multi-line mode
Multiple Result Values
Multiple Values and define-values
Multiple Values: let-values, let*-values, letrec-values
Multiple Values: set!-values
Multiple-Valued Sequences
mutable pair
Mutation and Performance
mutator
Named let
namespace
Namespaces
Namespaces and Modules
non-capturing
Non-capturing Clusters
non-greedy
Notation
number
Numbers
opaque
Opaque versus Transparent Structure Types
Optional Arguments
Optional Keyword Arguments
Organizing Modules
package
Packages and Collections
Packages specific to Evil Mode
pair
Pairs and Lists
Pairs, Lists, and Racket Syntax
Parallel Binding: let
Parallelism
parallelism
Parallelism with Futures
Parallelism with Places
parameter
Parameterized Mixins
Pattern Matching
pattern variables
pattern-based macro
Pattern-Based Macros
Performance
Performance in DrRacket
phase
phase level
phase level +-1
phase level +2
Phases and Bindings
Phases and Modules
place
place +channel
Plugins
port
POSIX character class
POSIX character classes
Predefined List Loops
predicate
prefab
Prefab Structure Types
Programmer-Defined Datatypes
prompt
prompt tag
Prompts and Aborts
property
protected
Protected Exports
protected method
Quantifiers
quantifiers
Quasiquoting: quasiquote and
Quoting Pairs and Symbols with quote
Quoting: quote and
R5RS
R6RS
Racket Essentials
Racket Virtual Machine Implementations
range
rational
Reachability and Garbage Collection
reader
Reader Extensions
Reading and Writing Racket Data
readtable
Readtables
real
Recursion versus Iteration
Recursive Binding: letrec
Reducing Garbage Collection Pauses
Reflection and Dynamic Evaluation
regexp
Regular Expression Performance
Regular Expressions
REPL
REPLs
rest +argument
Rest Arguments
Rolling Your Own Contracts
run-time configuration
Running and Creating Executables
Running racket and gracket
S-expression
Scribble
Scripting Evaluation and Using load
Scripts
Semaphores
Sequence Constructors
Sequencing
Sequential Binding: let*
serialization
set! Transformers
shadows
Sharing Data and Code Across Namespaces
Shell completion
signatures
Signatures and Units
Simple Branching: if
Simple Contracts on Functions
Simple Definitions and Expressions
Simple Dispatch: case
Simple Structure Types: struct
Simple Values
Some Frequently Used Character Classes
Source Locations
Source-Handling Configuration
speed
Standards
string
Strings (Unicode)
Structure Comparisons
Structure Subtypes
structure type descriptor
Structure Type Generativity
Structured Editing
Styles of ->
subcluster
Sublime Text
submatch
submodule
Submodules
subpattern
symbol
Symbols
Synchronizable Events and sync
synchronized
Syntax Objects
syntax objects
tail position
Tail Recursion
tainted
Tainted Syntax
Teaching
template
template phase level
text string
The #lang Shorthand
The apply Function
The mixin Form
The module Form
The Racket Guide
The trait Form
The Web Server
Thread Mailboxes
Threads
threads
Traits
Traits as Sets of Mixins
transformer
transformer +binding
transparent
Unchecked, Unsafe Operations
unit versus module
Units
Units (Components)
Unix Scripts
Using #lang reader
Using #lang s-exp
Using #lang s-exp syntax/module-reader
Using define/contract and ->
Using Foreign Libraries
Varieties of Ports
vector
Vectors
Vim
visit
Visiting Modules
Visual Studio Code
Void and Undefined
Weak Boxes and Testing
Welcome to Racket
Whole-module Signatures and Units
Windows Batch Files
With all the Bells and Whistles
with-syntax and generate-temporaries
Writing Regexp Patterns

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/encodings.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/encodings.html new file mode 100644 index 00000000..f4f4fe66 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/encodings.html @@ -0,0 +1,26 @@ + +8.5 Bytes, Characters, and Encodings

8.5 Bytes, Characters, and Encodings

Functions like read-line, read, display, +and write all work in terms of characters (which +correspond to Unicode scalar values). Conceptually, they are +implemented in terms of read-char and write-char.

More primitively, ports read and write bytes, instead of +characters. The functions read-byte and +write-byte read and write raw bytes. Other functions, such as +read-bytes-line, build on top of byte operations instead of +character operations.

In fact, the read-char and write-char functions are +conceptually implemented in terms of read-byte and +write-byte. When a single byte’s value is less than 128, then +it corresponds to an ASCII character. Any other byte is treated as +part of a UTF-8 sequence, where UTF-8 is a particular standard way of +encoding Unicode scalar values in bytes (which has the nice property +that ASCII characters are encoded as themselves). Thus, a single +read-char may call read-byte multiple times, and a +single write-char may generate multiple output bytes.

The read-char and write-char operations +always use a UTF-8 encoding. If you have a text stream that +uses a different encoding, or if you want to generate a text stream in +a different encoding, use reencode-input-port or +reencode-output-port. The reencode-input-port +function converts an input stream from an encoding that you specify +into a UTF-8 stream; that way, read-char sees UTF-8 +encodings, even though the original used a different encoding. Beware, +however, that read-byte also sees the re-encoded data, +instead of the original byte stream.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/eval.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/eval.html new file mode 100644 index 00000000..8f7051f1 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/eval.html @@ -0,0 +1,72 @@ + +15.1 eval

15.1 eval

This example will not work within a module or in DrRacket’s definitions window, +but it will work in the interactions window, for reasons that are +explained by the end of Namespaces.

The eval function takes a representation of an expression or definition +(as a “quoted” form or syntax object) and evaluates it:

> (eval '(+ 1 2))

3

The power of eval is that an expression can be +constructed dynamically:

> (define (eval-formula formula)
    (eval `(let ([x 2]
                 [y 3])
             ,formula)))
> (eval-formula '(+ x y))

5

> (eval-formula '(+ (* x y) y))

9

Of course, if we just wanted to evaluate expressions with given values +for x and y, we do not need eval. A more +direct approach is to use first-class functions:

> (define (apply-formula formula-proc)
    (formula-proc 2 3))
> (apply-formula (lambda (x y) (+ x y)))

5

> (apply-formula (lambda (x y) (+ (* x y) y)))

9

However, if expressions like (+ x y) and (+ (* x y) y) are read from a file supplied by a user, for example, then +eval might be appropriate. Similarly, the REPL reads +expressions that are typed by a user and uses eval to +evaluate them.

Also, eval is often used directly or indirectly on whole +modules. For example, a program might load a module on demand using +dynamic-require, which is essentially a wrapper around +eval to dynamically load the module code.

15.1.1 Local Scopes

The eval function cannot see local bindings in the context +where it is called. For example, calling eval inside an +unquoted let form to evaluate a formula does not make values +visible for x and y:

> (define (broken-eval-formula formula)
    (let ([x 2]
          [y 3])
      (eval formula)))
> (broken-eval-formula '(+ x y))

x: undefined;

 cannot reference an identifier before its definition

  in module: top-level

The eval function cannot see the x and y +bindings precisely because it is a function, and Racket is a lexically +scoped language. Imagine if eval were implemented as

(define (eval x)
  (eval-expanded (macro-expand x)))

then at the point when eval-expanded is called, the most +recent binding of x is to the expression to evaluate, not the +let binding in broken-eval-formula. Lexical scope +prevents such confusing and fragile behavior, and consequently +prevents eval from seeing local bindings in the context where +it is called.

You might imagine that even though eval cannot see the local +bindings in broken-eval-formula, there must actually be a +data structure mapping x to 2 and y to +3, and you would like a way to get that data structure. In +fact, no such data structure exists; the compiler is free to replace +every use of x with 2 at compile time, so that the +local binding of x does not exist in any concrete sense at +run-time. Even when variables cannot be eliminated by +constant-folding, normally the names of the variables can be +eliminated, and the data structures that hold local values do not +resemble a mapping from names to values.

15.1.2 Namespaces

Since eval cannot see the bindings from the context where it +is called, another mechanism is needed to determine dynamically +available bindings. A namespace is a first-class value that +encapsulates the bindings available for dynamic evaluation.

Informally, the term namespace is sometimes +used interchangeably with environment or +scope. In Racket, the term namespace has the +more specific, dynamic meaning given above, and it should not be +confused with static lexical concepts.

Some functions, such as eval, accept an optional namespace +argument. More often, the namespace used by a dynamic operation is the +current namespace as determined by the +current-namespace parameter.

When eval is used in a REPL, the current namespace is the one +that the REPL uses for evaluating expressions. That’s why the +following interaction successfully accesses x via +eval:

> (define x 3)
> (eval 'x)

3

In contrast, try the following simple module and running it directly +in DrRacket or supplying the file as a command-line argument to +racket:

#lang racket
 
(eval '(cons 1 2))

This fails because the initial current namespace is empty. When you +run racket in interactive mode (see +Interactive Mode), the initial namespace is +initialized with the exports of the racket module, but when +you run a module directly, the initial namespace starts empty.

In general, it’s a bad idea to use eval with whatever +namespace happens to be installed. Instead, create a namespace +explicitly and install it for the call to eval:

#lang racket
 
(define ns (make-base-namespace))
(eval '(cons 1 2) ns) ; works

The make-base-namespace function creates a namespace that is +initialized with the exports of racket/base. The later +section Manipulating Namespaces provides more information on creating +and configuring namespaces.

15.1.3 Namespaces and Modules

As with let bindings, lexical scope means that eval +cannot automatically see the definitions of a module in which +it is called. Unlike let bindings, however, Racket provides a +way to reflect a module into a namespace.

The module->namespace function takes a quoted module +path and produces a namespace for evaluating expressions and +definitions as if they appeared in the module body:

> (module m racket/base
    (define x 11))
> (require 'm)
> (define ns (module->namespace ''m))
> (eval 'x ns)

11

The double quoting in ''m is because 'm +is a module path that refers to an interactively declared module, and +so ''m is the quoted form of the path.

The module->namespace function is mostly useful from outside +a module, where the module’s full name is known. Inside a +module form, however, the full name of a module may not be +known, because it may depend on where the module source is located +when it is eventually loaded.

From within a module, use define-namespace-anchor to +declare a reflection hook on the module, and use +namespace-anchor->namespace to reel in the module’s +namespace:

#lang racket
 
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
 
(define x 1)
(define y 2)
 
(eval '(cons x y) ns) ; produces (1 . 2)
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/exe.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/exe.html new file mode 100644 index 00000000..21af7f3c --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/exe.html @@ -0,0 +1,4 @@ + +21.3 Creating Stand-Alone Executables

21.3 Creating Stand-Alone Executables

For information on creating and distributing executables, see +raco exe: Creating Stand-Alone Executables and raco distribute: Sharing Stand-Alone Executables in +raco: Racket Command-Line Tools.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/exns.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/exns.html new file mode 100644 index 00000000..63abd52b --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/exns.html @@ -0,0 +1,30 @@ + +10.1 Exceptions

10.1 Exceptions

Whenever a run-time error occurs, an exception is +raised. Unless the exception is caught, then it is handled by printing +a message associated with the exception, and then escaping from the +computation.

> (/ 1 0)

/: division by zero

> (car 17)

car: contract violation

  expected: pair?

  given: 17

To catch an exception, use the with-handlers form:

(with-handlers ([predicate-expr handler-expr] ...)
  body ...+)

Each predicate-expr in a handler determines a kind of +exception that is caught by the with-handlers form, and the +value representing the exception is passed to the handler procedure +produced by handler-expr. The result of the +handler-expr is the result of the with-handlers +expression.

For example, a divide-by-zero error raises an instance of the +exn:fail:contract:divide-by-zero structure type:

> (with-handlers ([exn:fail:contract:divide-by-zero?
                   (lambda (exn) +inf.0)])
    (/ 1 0))

+inf.0

> (with-handlers ([exn:fail:contract:divide-by-zero?
                   (lambda (exn) +inf.0)])
    (car 17))

car: contract violation

  expected: pair?

  given: 17

The error function is one way to raise your own exception. It +packages an error message and other information into an +exn:fail structure:

> (error "crash!")

crash!

> (with-handlers ([exn:fail? (lambda (exn) 'air-bag)])
    (error "crash!"))

'air-bag

The exn:fail:contract:divide-by-zero and exn:fail +structure types are sub-types of the exn structure +type. Exceptions raised by core forms and functions always raise an +instance of exn or one of its sub-types, but an exception +does not have to be represented by a structure. The raise +function lets you raise any value as an exception:

> (raise 2)

uncaught exception: 2

> (with-handlers ([(lambda (v) (equal? v 2)) (lambda (v) 'two)])
    (raise 2))

'two

> (with-handlers ([(lambda (v) (equal? v 2)) (lambda (v) 'two)])
    (/ 1 0))

/: division by zero

Multiple predicate-exprs in a with-handlers form +let you handle different kinds of exceptions in different ways. The +predicates are tried in order, and if none of them match, then the +exception is propagated to enclosing contexts.

> (define (always-fail n)
    (with-handlers ([even? (lambda (v) 'even)]
                    [positive? (lambda (v) 'positive)])
      (raise n)))
> (always-fail 2)

'even

> (always-fail 3)

'positive

> (always-fail -3)

uncaught exception: -3

> (with-handlers ([negative? (lambda (v) 'negative)])
   (always-fail -3))

'negative

Using (lambda (v) #t) as a predicate captures all exceptions, of course:

> (with-handlers ([(lambda (v) #t) (lambda (v) 'oops)])
    (car 17))

'oops

Capturing all exceptions is usually a bad idea, however. If the user +types Ctl-C in a terminal window or clicks the Stop button +in DrRacket to interrupt a computation, then normally the +exn:break exception should not be caught. To catch only +exceptions that represent errors, use exn:fail? as the +predicate:

> (with-handlers ([exn:fail? (lambda (v) 'oops)])
    (car 17))

'oops

> (with-handlers ([exn:fail? (lambda (v) 'oops)])
    (break-thread (current-thread)) ; simulate Ctl-C
    (car 17))

user break

Exceptions carry information about the error that occurred. The +exn-message accessor provides a descriptive message for the +exception. The exn-continuation-marks accessor provides +information about the point where the exception was raised. +

The continuation-mark-set->context procedure provides best-effort structured backtrace information.

> (with-handlers ([exn:fail?
                   (lambda (v)
                     ((error-display-handler) (exn-message v) v))])
    (car 17))

car: contract violation

  expected: pair?

  given: 17

  context...:

   /home/scheme/pltbuild/racket/racket/collects/racket/private/more-scheme.rkt:148:2: call-with-break-parameterization

   /home/scheme/pltbuild/racket/build/user/8.6/pkgs/sandbox-lib/racket/sandbox.rkt:921:7

   /home/scheme/pltbuild/racket/build/user/8.6/pkgs/sandbox-lib/racket/sandbox.rkt:891:2: user-process

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/figure.css b/clones/download.racket-lang.org/releases/8.6/doc/guide/figure.css new file mode 100644 index 00000000..905d5b67 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/figure.css @@ -0,0 +1,37 @@ + +.Centertext { + text-align: center; + margin: 0 0 0 0; +} + +.Figure, .FigureMulti, .FigureMultiWide, .Herefigure { + margin: 1em 0 1em 0; + border: 1px solid #1818FF; +} + +.Figure, .FigureMulti, .Herefigure { + width: 100%; +} + +.FigureMultiWide { + width: 125%; +} + +.Centerfigure { + text-align: center; + margin: 0 0 0 0; +} + +.Leftfigure { + text-align: left; + margin: 0 0 0 0; +} + +.Rightfigure { + text-align: right; + margin: 0 0 0 0; +} + +.FigureInside { + margin: 1em 1em 1em 1em; +} diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/figure.js b/clones/download.racket-lang.org/releases/8.6/doc/guide/figure.js new file mode 100644 index 00000000..b85af46c --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/figure.js @@ -0,0 +1,27 @@ + +AddOnLoad(function () { + /* Lift figure targets to the start of the figure's blockquote, + so that clicking on a target reference shows the figure + content, instead of scrolling the figure caption to the + top of the page. */ + var targets = document.getElementsByTagName("a"); + for (var i = 0; i < targets.length; i++) { + var a = targets[i]; + var n = a.attributes["x-target-lift"]; + if (n) { + var s = n.value; + var p = a.parentNode; + while (p && (p.className != s)) { + p = p.parentNode; + } + if (p) { + var cs = p.children; + a.parentNode.removeChild(a); + if (cs.length > 0) + p.insertBefore(a, cs[0]); + else + p.appendChild(a); + } + } + } +}); diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/finger.png b/clones/download.racket-lang.org/releases/8.6/doc/guide/finger.png new file mode 100644 index 0000000000000000000000000000000000000000..af521e80ad42a9ae5407c620edc296e7c4bba598 GIT binary patch literal 430 zcmV;f0a5;mP)eTsH8vpRWL7c@7w$U2V zgi@`8IW*&B=1?m>V;Oz8ig#GY1&kt(uaRJL+|!8fSVRHkJ&~^XDC0gRu!4Eqz@dty zF5_O6gc~p!Nf9Mxd4uOT6++))|5)r5@Cfa=i3Q1`CbZ!=hVh`9z`8RzWV-*AXPoi+C>$z!PbFr~XFZC^~RnYUHzs60YM8UZEf3*hQz`yocb^Zf> Y0+i!VsAM9jdH?_b07*qoM6N<$g28abDF6Tf literal 0 HcmV?d00001 diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/firstclassunits.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/firstclassunits.html new file mode 100644 index 00000000..fb7c7adb --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/firstclassunits.html @@ -0,0 +1,46 @@ + +14.4 First-Class Units

14.4 First-Class Units

The define-unit form combines define with a +unit form, similar to the way that (define (f x) ....) combines define followed by an identifier with an +implicit lambda.

Expanding the shorthand, the definition of toy-store@ could +almost be written as

(define toy-store@
  (unit
   (import toy-factory^)
   (export toy-store^)
 
   (define inventory null)
 
   (define (store-color) 'green)
   ....))

A difference between this expansion and define-unit is that +the imports and exports of toy-store@ cannot be +inferred. That is, besides combining define and +unit, define-unit attaches static information to the +defined identifier so that its signature information is available +statically to define-values/invoke-unit/infer and other +forms.

Despite the drawback of losing static signature information, +unit can be useful in combination with other forms that work +with first-class values. For example, we could wrap a unit +that creates a toy store in a lambda to supply the store’s +color:

"toy-store-maker.rkt"

#lang racket
 
(require "toy-store-sig.rkt"
         "toy-factory-sig.rkt")
 
(define toy-store@-maker
  (lambda (the-color)
    (unit
     (import toy-factory^)
     (export toy-store^)
 
     (define inventory null)
 
     (define (store-color) the-color)
 
     ; the rest is the same as before
 
     (define (maybe-repaint t)
       (if (eq? (toy-color t) (store-color))
           t
           (repaint t (store-color))))
 
     (define (stock! n)
       (set! inventory
             (append inventory
                     (map maybe-repaint
                          (build-toys n)))))
 
     (define (get-inventory) inventory))))
 
(provide toy-store@-maker)

To invoke a unit created by toy-store@-maker, we must use +define-values/invoke-unit, instead of the +/infer variant:

> (require "simple-factory-unit.rkt")
> (define-values/invoke-unit/infer simple-factory@)

Factory started.

> (require "toy-store-maker.rkt")
> (define-values/invoke-unit (toy-store@-maker 'purple)
    (import toy-factory^)
    (export toy-store^))
> (stock! 2)
> (get-inventory)

(list (toy 'purple) (toy 'purple))

In the define-values/invoke-unit form, the (import toy-factory^) line takes bindings from the current context that match +the names in toy-factory^ (the ones that we created by +invoking simple-factory@), and it supplies them as imports to +toy-store@. The (export toy-store^) clause indicates +that the unit produced by toy-store@-maker will export +toy-store^, and the names from that signature are defined +after invoking the unit.

To link a unit from toy-store@-maker, we can use the +compound-unit form:

> (require "store-specific-factory-unit.rkt")
> (define toy-store+factory@
    (compound-unit
     (import)
     (export TF TS)
     (link [((TF : toy-factory^)) store-specific-factory@ TS]
           [((TS : toy-store^)) toy-store@ TF])))

This compound-unit form packs a lot of information into one +place. The left-hand-side TF and TS in the +link clause are binding identifiers. The identifier +TF is essentially bound to the elements of +toy-factory^ as implemented by +store-specific-factory@. The identifier TS is +similarly bound to the elements of toy-store^ as implemented +by toy-store@. Meanwhile, the elements bound to TS +are supplied as imports for store-specific-factory@, since +TS follows store-specific-factory@. The elements +bound to TF are similarly supplied to +toy-store@. Finally, (export TF TS) indicates that +the elements bound to TF and TS are exported from +the compound unit.

The above compound-unit form uses +store-specific-factory@ as a first-class unit, even though +its information could be inferred. Every unit can be used as a +first-class unit, in addition to its use in inference contexts. Also, +various forms let a programmer bridge the gap between inferred and +first-class worlds. For example, define-unit-binding binds a +new identifier to the unit produced by an arbitrary expression; it +statically associates signature information to the identifier, and it +dynamically checks the signatures against the first-class unit +produced by the expression.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/for.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/for.html new file mode 100644 index 00000000..75692eca --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/for.html @@ -0,0 +1,130 @@ + +11 Iterations and Comprehensions

11 Iterations and Comprehensions

The for family of syntactic forms support iteration over +sequences. Lists, vectors, strings, byte strings, input +ports, and hash tables can all be used as sequences, and constructors +like in-range offer even more kinds of sequences.

Variants of for accumulate iteration results in different +ways, but they all have the same syntactic shape. Simplifying for +now, the syntax of for is

(for ([id sequence-expr] ...)
  body ...+)

A for loop iterates through the sequence produced by the +sequence-expr. For each element of the sequence, +for binds the element to id, and then it evaluates +the bodys for side effects.

Examples:
> (for ([i '(1 2 3)])
    (display i))

123

> (for ([i "abc"])
    (printf "~a..." i))

a...b...c...

> (for ([i 4])
    (display i))

0123

The for/list variant of for is more Racket-like. It +accumulates body results into a list, instead of +evaluating body only for side effects. In more +technical terms, for/list implements a list +comprehension.

Examples:
> (for/list ([i '(1 2 3)])
    (* i i))

'(1 4 9)

> (for/list ([i "abc"])
    i)

'(#\a #\b #\c)

> (for/list ([i 4])
    i)

'(0 1 2 3)

The full syntax of for accommodates multiple sequences to +iterate in parallel, and the for* variant nests the +iterations instead of running them in parallel. More variants of +for and for* accumulate body results +in different ways. In all of these variants, predicates that prune +iterations can be included along with bindings.

Before details on the variations of for, though, it’s best to +see the kinds of sequence generators that make interesting examples.

11.1 Sequence Constructors

The in-range function generates a sequence of numbers, given +an optional starting number (which defaults to 0), a number +before which the sequence ends, and an optional step (which defaults +to 1). Using a non-negative integer k directly as +a sequence is a shorthand for (in-range k).

Examples:
> (for ([i 3])
    (display i))

012

> (for ([i (in-range 3)])
    (display i))

012

> (for ([i (in-range 1 4)])
    (display i))

123

> (for ([i (in-range 1 4 2)])
    (display i))

13

> (for ([i (in-range 4 1 -1)])
    (display i))

432

> (for ([i (in-range 1 4 1/2)])
    (printf " ~a " i))

 1  3/2  2  5/2  3  7/2

The in-naturals function is similar, except that the +starting number must be an exact non-negative integer (which defaults +to 0), the step is always 1, and there is no upper +limit. A for loop using just in-naturals will never +terminate unless a body expression raises an exception or otherwise +escapes.

Example:
> (for ([i (in-naturals)])
    (if (= i 10)
        (error "too much!")
        (display i)))

0123456789

too much!

The stop-before and stop-after functions construct +a new sequence given a sequence and a predicate. The new sequence is +like the given sequence, but truncated either immediately before or +immediately after the first element for which the predicate returns +true.

Example:
> (for ([i (stop-before "abc def"
                        char-whitespace?)])
    (display i))

abc

Sequence constructors like in-list, in-vector and +in-string simply make explicit the use of a list, vector, or +string as a sequence. Along with in-range, +these constructors raise an exception when given the +wrong kind of value, and since they otherwise avoid a run-time +dispatch to determine the sequence type, they enable more efficient +code generation; see Iteration Performance for more information.

Examples:
> (for ([i (in-string "abc")])
    (display i))

abc

> (for ([i (in-string '(1 2 3))])
    (display i))

in-string: contract violation

  expected: string

  given: '(1 2 3)

+Sequences in The Racket Reference provides more on sequences.

11.2 for and for*

A more complete syntax of for is

(for (clause ...)
  body ...+)
 
clause = [id sequence-expr]
  | #:when boolean-expr
  | #:unless boolean-expr

When multiple [id sequence-expr] clauses are provided +in a for form, the corresponding sequences are traversed in +parallel:

> (for ([i (in-range 1 4)]
        [chapter '("Intro" "Details" "Conclusion")])
    (printf "Chapter ~a. ~a\n" i chapter))

Chapter 1. Intro

Chapter 2. Details

Chapter 3. Conclusion

With parallel sequences, the for expression stops iterating +when any sequence ends. This behavior allows in-naturals, +which creates an infinite sequence of numbers, to be used for +indexing:

> (for ([i (in-naturals 1)]
        [chapter '("Intro" "Details" "Conclusion")])
    (printf "Chapter ~a. ~a\n" i chapter))

Chapter 1. Intro

Chapter 2. Details

Chapter 3. Conclusion

The for* form, which has the same syntax as for, +nests multiple sequences instead of running them in parallel:

> (for* ([book '("Guide" "Reference")]
         [chapter '("Intro" "Details" "Conclusion")])
    (printf "~a ~a\n" book chapter))

Guide Intro

Guide Details

Guide Conclusion

Reference Intro

Reference Details

Reference Conclusion

Thus, for* is a shorthand for nested fors in the +same way that let* is a shorthand for nested lets.

The #:when boolean-expr form of a clause is +another shorthand. It allows the bodys to evaluate only +when the boolean-expr produces a true value:

> (for* ([book '("Guide" "Reference")]
         [chapter '("Intro" "Details" "Conclusion")]
         #:when (not (equal? chapter "Details")))
    (printf "~a ~a\n" book chapter))

Guide Intro

Guide Conclusion

Reference Intro

Reference Conclusion

A boolean-expr with #:when can refer to any of the +preceding iteration bindings. In a for form, this scoping +makes sense only if the test is nested in the iteration of the +preceding bindings; thus, bindings separated by #:when are +mutually nested, instead of in parallel, even with for.

> (for ([book '("Guide" "Reference" "Notes")]
        #:when (not (equal? book "Notes"))
        [i (in-naturals 1)]
        [chapter '("Intro" "Details" "Conclusion" "Index")]
        #:when (not (equal? chapter "Index")))
    (printf "~a Chapter ~a. ~a\n" book i chapter))

Guide Chapter 1. Intro

Guide Chapter 2. Details

Guide Chapter 3. Conclusion

Reference Chapter 1. Intro

Reference Chapter 2. Details

Reference Chapter 3. Conclusion

An #:unless clause is analogous to a #:when clause, but +the bodys evaluate only when the boolean-expr +produces a false value.

11.3 for/list and for*/list

The for/list form, which has the same syntax as for, +evaluates the bodys to obtain values that go into a +newly constructed list:

> (for/list ([i (in-naturals 1)]
             [chapter '("Intro" "Details" "Conclusion")])
    (string-append (number->string i) ". " chapter))

'("1. Intro" "2. Details" "3. Conclusion")

A #:when clause in a for-list form prunes the result +list along with evaluations of the bodys:

> (for/list ([i (in-naturals 1)]
             [chapter '("Intro" "Details" "Conclusion")]
             #:when (odd? i))
    chapter)

'("Intro" "Conclusion")

This pruning behavior of #:when is more useful with +for/list than for. Whereas a plain when +form normally suffices with for, a when expression +form in a for/list would cause the result list to contain +#<void>s instead of omitting list elements.

The for*/list form is like for*, nesting multiple +iterations:

> (for*/list ([book '("Guide" "Ref.")]
              [chapter '("Intro" "Details")])
    (string-append book " " chapter))

'("Guide Intro" "Guide Details" "Ref. Intro" "Ref. Details")

A for*/list form is not quite the same thing as nested +for/list forms. Nested for/lists would produce a +list of lists, instead of one flattened list. Much like +#:when, then, the nesting of for*/list is more +useful than the nesting of for*.

11.4 for/vector and for*/vector

The for/vector form can be used with the same syntax as the +for/list form, but the evaluated bodys go into a +newly-constructed vector instead of a list:

> (for/vector ([i (in-naturals 1)]
               [chapter '("Intro" "Details" "Conclusion")])
    (string-append (number->string i) ". " chapter))

'#("1. Intro" "2. Details" "3. Conclusion")

The for*/vector form behaves similarly, but the iterations are +nested as in for*.

The for/vector and for*/vector forms also allow the +length of the vector to be constructed to be supplied in advance. The +resulting iteration can be performed more efficiently than plain +for/vector or for*/vector:

> (let ([chapters '("Intro" "Details" "Conclusion")])
    (for/vector #:length (length chapters) ([i (in-naturals 1)]
                                            [chapter chapters])
      (string-append (number->string i) ". " chapter)))

'#("1. Intro" "2. Details" "3. Conclusion")

If a length is provided, the iteration stops when the vector is filled +or the requested iterations are complete, whichever comes first. If +the provided length exceeds the requested number of iterations, then +the remaining slots in the vector are initialized to the default +argument of make-vector.

11.5 for/and and for/or

The for/and form combines iteration results with +and, stopping as soon as it encounters #f:

> (for/and ([chapter '("Intro" "Details" "Conclusion")])
    (equal? chapter "Intro"))

#f

The for/or form combines iteration results with or, +stopping as soon as it encounters a true value:

> (for/or ([chapter '("Intro" "Details" "Conclusion")])
    (equal? chapter "Intro"))

#t

As usual, the for*/and and for*/or forms provide the +same facility with nested iterations.

11.6 for/first and for/last

The for/first form returns the result of the first time that +the bodys are evaluated, skipping further iterations. +This form is most useful with a #:when clause.

> (for/first ([chapter '("Intro" "Details" "Conclusion" "Index")]
              #:when (not (equal? chapter "Intro")))
    chapter)

"Details"

If the bodys are evaluated zero times, then the result +is #f.

The for/last form runs all iterations, returning the value of +the last iteration (or #f if no iterations are run):

> (for/last ([chapter '("Intro" "Details" "Conclusion" "Index")]
              #:when (not (equal? chapter "Index")))
    chapter)

"Conclusion"

As usual, the for*/first and for*/last forms provide +the same facility with nested iterations:

> (for*/first ([book '("Guide" "Reference")]
               [chapter '("Intro" "Details" "Conclusion" "Index")]
               #:when (not (equal? chapter "Intro")))
    (list book chapter))

'("Guide" "Details")

> (for*/last ([book '("Guide" "Reference")]
              [chapter '("Intro" "Details" "Conclusion" "Index")]
              #:when (not (equal? chapter "Index")))
    (list book chapter))

'("Reference" "Conclusion")

11.7 for/fold and for*/fold

The for/fold form is a very general way to combine iteration +results. Its syntax is slightly different than the syntax of +for, because accumulation variables must be declared at the +beginning:

(for/fold ([accum-id init-expr] ...)
          (clause ...)
  body ...+)

In the simple case, only one [accum-id init-expr] is +provided, and the result of the for/fold is the final value +for accum-id, which starts out with the value of +init-expr. In the clauses and +bodys, accum-id can be referenced to get its +current value, and the last body provides the value of +accum-id for the next iteration.

Examples:
> (for/fold ([len 0])
            ([chapter '("Intro" "Conclusion")])
    (+ len (string-length chapter)))

15

> (for/fold ([prev #f])
            ([i (in-naturals 1)]
             [chapter '("Intro" "Details" "Details" "Conclusion")]
             #:when (not (equal? chapter prev)))
    (printf "~a. ~a\n" i chapter)
    chapter)

1. Intro

2. Details

4. Conclusion

"Conclusion"

When multiple accum-ids are specified, then the last +body must produce multiple values, one for each +accum-id. The for/fold expression itself produces +multiple values for the results.

Example:
> (for/fold ([prev #f]
             [counter 1])
            ([chapter '("Intro" "Details" "Details" "Conclusion")]
             #:when (not (equal? chapter prev)))
    (printf "~a. ~a\n" counter chapter)
    (values chapter
            (add1 counter)))

1. Intro

2. Details

3. Conclusion

"Conclusion"

4

11.8 Multiple-Valued Sequences

In the same way that a function or expression can produce multiple +values, individual iterations of a sequence can produce multiple +elements. For example, a hash table as a sequence generates two +values for each iteration: a key and a value.

In the same way that let-values binds multiple results to +multiple identifiers, for can bind multiple sequence elements +to multiple iteration identifiers:

While let must be changed to let-values +to bind multiple identifiers, for simply allows a +parenthesized list of identifiers instead of a single +identifier in any clause.

> (for ([(k v) #hash(("apple" . 1) ("banana" . 3))])
    (printf "~a count: ~a\n" k v))

apple count: 1

banana count: 3

This extension to multiple-value bindings works for all for +variants. For example, for*/list nests iterations, builds a +list, and also works with multiple-valued sequences:

> (for*/list ([(k v) #hash(("apple" . 1) ("banana" . 3))]
              [(i) (in-range v)])
    k)

'("apple" "banana" "banana" "banana")

11.9 Breaking an Iteration

An even more complete syntax of for is

(for (clause ...)
  body-or-break ... body)
 
clause = [id sequence-expr]
  | #:when boolean-expr
  | #:unless boolean-expr
  | break
     
body-or-break = body
  | break
     
break = #:break boolean-expr
  | #:final boolean-expr

That is, a #:break or #:final clause can +be included among the binding clauses and body of the iteration. Among +the binding clauses, #:break is like #:unless +but when its boolean-expr is true, all sequences within the +for are stopped. Among the bodys, +#:break has the same effect on sequences when its +boolean-expr is true, and it also prevents later +bodys from evaluation in the current iteration.

For example, while using #:unless between clauses effectively +skips later sequences as well as the body,

> (for ([book '("Guide" "Story" "Reference")]
        #:unless (equal? book "Story")
        [chapter '("Intro" "Details" "Conclusion")])
    (printf "~a ~a\n" book chapter))

Guide Intro

Guide Details

Guide Conclusion

Reference Intro

Reference Details

Reference Conclusion

using #:break causes the entire for iteration +to terminate:

> (for ([book '("Guide" "Story" "Reference")]
        #:break (equal? book "Story")
        [chapter '("Intro" "Details" "Conclusion")])
    (printf "~a ~a\n" book chapter))

Guide Intro

Guide Details

Guide Conclusion

> (for* ([book '("Guide" "Story" "Reference")]
         [chapter '("Intro" "Details" "Conclusion")])
    #:break (and (equal? book "Story")
                 (equal? chapter "Conclusion"))
    (printf "~a ~a\n" book chapter))

Guide Intro

Guide Details

Guide Conclusion

Story Intro

Story Details

A #:final clause is similar to #:break, +but it does not immediately terminate the iteration. Instead, it +allows at most one more element to be drawn for each sequence and at +most one more evaluation of the bodys.

> (for* ([book '("Guide" "Story" "Reference")]
         [chapter '("Intro" "Details" "Conclusion")])
    #:final (and (equal? book "Story")
                 (equal? chapter "Conclusion"))
    (printf "~a ~a\n" book chapter))

Guide Intro

Guide Details

Guide Conclusion

Story Intro

Story Details

Story Conclusion

> (for ([book '("Guide" "Story" "Reference")]
        #:final (equal? book "Story")
        [chapter '("Intro" "Details" "Conclusion")])
    (printf "~a ~a\n" book chapter))

Guide Intro

Guide Details

Guide Conclusion

Story Intro

11.10 Iteration Performance

Ideally, a for iteration should run as fast as a loop that +you write by hand as a recursive-function invocation. A hand-written +loop, however, is normally specific to a particular kind of data, such +as lists. In that case, the hand-written loop uses selectors like +car and cdr directly, instead of handling all forms +of sequences and dispatching to an appropriate iterator.

The for forms can provide the performance of hand-written +loops when enough information is apparent about the sequences to +iterate. Specifically, the clause should have one of the following +fast-clause forms:

  fast-clause = [id fast-seq]
  | [(id) fast-seq]
  | [(id id) fast-indexed-seq]
  | [(id ...) fast-parallel-seq]

  fast-seq = (in-range expr)
  | (in-range expr expr)
  | (in-range expr expr expr)
  | (in-inclusive-range expr expr)
  | (in-inclusive-range expr expr expr)
  | (in-naturals)
  | (in-naturals expr)
  | (in-list expr)
  | (in-mlist expr)
  | (in-vector expr)
  | (in-string expr)
  | (in-bytes expr)
  | (in-value expr)
  | (stop-before fast-seq predicate-expr)
  | (stop-after fast-seq predicate-expr)

  fast-indexed-seq = (in-indexed fast-seq)
  | (stop-before fast-indexed-seq predicate-expr)
  | (stop-after fast-indexed-seq predicate-expr)

  fast-parallel-seq = (in-parallel fast-seq ...)
  | (stop-before fast-parallel-seq predicate-expr)
  | (stop-after fast-parallel-seq predicate-expr)

Examples:
> (time (for ([i (in-range 100000)])
          (for ([elem (in-list '(a b c d e f g h))]) ; fast
            (void))))

cpu time: 7 real time: 3 gc time: 0

> (time (for ([i (in-range 100000)])
          (for ([elem '(a b c d e f g h)])           ; slower
            (void))))

cpu time: 7 real time: 3 gc time: 0

> (time (let ([seq (in-list '(a b c d e f g h))])
          (for ([i (in-range 100000)])
            (for ([elem seq])                        ; slower
              (void)))))

cpu time: 45 real time: 23 gc time: 0

The grammars above are not complete, because the set of syntactic +patterns that provide good performance is extensible, just like the +set of sequence values. The documentation for a sequence constructor +should indicate the performance benefits of using it directly in +a for clause.

+Iterations and Comprehensions: for, for/list, ... in The Racket Reference provides more on iterations and comprehensions.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_reader.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_reader.html new file mode 100644 index 00000000..75c9f0ff --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_reader.html @@ -0,0 +1,23 @@ + +17.3.2 Using #lang reader
17.3.2 Using #lang reader

The reader language for #lang is similar to +s-exp, in that it acts as a kind of meta-language. +Whereas s-exp lets a programmer specify a module +language at the expander layer of parsing, +reader lets a programmer specify a language at the +reader level.

A #lang reader must be followed by +a module path, and the specified module must provide two functions: +read and read-syntax. The protocol is +the same as for a #reader implementation, but for +#lang, the read and read-syntax +functions must produce a module form that is based on the +rest of the input file for the module.

The following "literal.rkt" module implements a language that +treats its entire body as literal text and exports the text as a +data string:

"literal.rkt"

#lang racket
(require syntax/strip-context)
 
(provide (rename-out [literal-read read]
                     [literal-read-syntax read-syntax]))
 
(define (literal-read in)
  (syntax->datum
   (literal-read-syntax #f in)))
 
(define (literal-read-syntax src in)
  (with-syntax ([str (port->string in)])
    (strip-context
     #'(module anything racket
         (provide data)
         (define data 'str)))))

The "literal.rkt" language uses strip-context on the +generated module expression, because a +read-syntax function should return a syntax object with +no lexical context. Also, the "literal.rkt" language creates +a module named anything, which is an arbitrary choice; +the language is intended to be used in a file, and the longhand module +name is ignored when it appears in a required file.

The "literal.rkt" language can be used in a module +"tuvalu.rkt":

"tuvalu.rkt"

#lang reader "literal.rkt"
Technology!
System!
Perfect!

Importing "tuvalu.rkt" binds data to a +string version of the module content:

> (require "tuvalu.rkt")
> data

"\nTechnology!\nSystem!\nPerfect!\n"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_syntax.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_syntax.html new file mode 100644 index 00000000..40033cd0 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-lang_syntax.html @@ -0,0 +1,43 @@ + +17.3.1 Designating a #lang Language
17.3.1 Designating a #lang Language

The syntax of a language intentionally overlaps with the +syntax of a module path as used in require or as a +module language, so that names like racket, +racket/base, slideshow, or +scribble/manual can be used both as #lang +languages and as module paths.

At the same time, the syntax of language is far more +restricted than a module path, because only a-z, +A-Z, 0-9, +/ (not at the start or end), +_, -, and + are allowed in a +language name. These restrictions keep the syntax of +#lang as simple as possible. Keeping the syntax of #lang +simple, in turn, is important because the syntax is inherently +inflexible and non-extensible; the #lang protocol allows a +language to refine and define syntax in a practically +unconstrained way, but the #lang protocol itself must remain +fixed so that various different tools can “boot” into the extended +world.

Fortunately, the #lang protocol provides a natural way to refer +to languages in ways other than the rigid language syntax: +by defining a language that implements its own nested +protocol. We have already seen one example (in Using #lang s-exp): the +s-exp language allows a programmer to +specify a module language using the general module path +syntax. Meanwhile, s-exp takes care of the +reader-level responsibilities of a #lang language.

Unlike racket, s-exp cannot be used as a +module path with require. Although the syntax of +language for #lang overlaps with the syntax of module +paths, a language is not used directly as a module +path. Instead, a language obtains a module path by trying two +locations: first, it looks for a reader submodule of the +main module for language. If this is not a valid module path, +then language is suffixed with /lang/reader. +(If neither is a valid module path, an error is raised.) The resulting +module supplies read and read-syntax +functions using a protocol that is similar to the one for +#reader.

+Reader Extensions introduces #reader.

A consequence of the way that a #lang language is +turned into a module path is that the language must be installed in a +collection, similar to the way that "racket" or +"slideshow" are collections that are distributed with Racket. +Again, however, there’s an escape from this restriction: the +reader language lets you specify a reader-level +implementation of a language using a general module path.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-languages.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-languages.html new file mode 100644 index 00000000..3081074d --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-languages.html @@ -0,0 +1,9 @@ + +17.3 Defining new #lang Languages

17.3 Defining new #lang Languages

When loading a module as a source program that starts

#lang language

the language determines the way that the rest of the module +is parsed at the reader level. The reader-level parse +must produce a module form as a syntax object. As +always, the second sub-form after module specifies the +module language that controls the meaning of the module’s body +forms. Thus, a language specified after #lang +controls both the reader-level and expander-level +parsing of a module.

    17.3.1 Designating a #lang Language

    17.3.2 Using #lang reader

    17.3.3 Using #lang s-exp syntax/module-reader

    17.3.4 Installing a Language

    17.3.5 Source-Handling Configuration

    17.3.6 Module-Handling Configuration

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-reader.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-reader.html new file mode 100644 index 00000000..595dd2de --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-reader.html @@ -0,0 +1,84 @@ + +17.2 Reader Extensions

17.2 Reader Extensions

+Reading via an Extension in The Racket Reference provides more on reader extensions.

The reader layer of the Racket language can be extended through +the #reader form. A reader extension is implemented +as a module that is named after #reader. The module +exports functions that parse raw characters into a form to be consumed +by the expander layer.

The syntax of #reader is

#reader module-path reader-specific

where module-path names a module that provides +read and read-syntax functions. The +reader-specific part is a sequence of characters that is +parsed as determined by the read and +read-syntax functions from module-path.

For example, suppose that file "five.rkt" contains

"five.rkt"

#lang racket/base
 
(provide read read-syntax)
 
(define (read in) (list (read-string 5 in)))
(define (read-syntax src in) (list (read-string 5 in)))

Then, the program

#lang racket/base
 
'(1 #reader"five.rkt"234567 8)

is equivalent to

#lang racket/base
 
'(1 ("23456") 7 8)

because the read and read-syntax +functions of "five.rkt" both read five characters from the +input stream and put them into a string and then a list. The reader +functions from "five.rkt" are not obliged to follow Racket +lexical conventions and treat the continuous sequence 234567 +as a single number. Since only the 23456 part is consumed by +read or read-syntax, the 7 +remains to be parsed in the usual Racket way. Similarly, the reader +functions from "five.rkt" are not obliged to ignore +whitespace, and

#lang racket/base
 
'(1 #reader"five.rkt" 234567 8)

is equivalent to

#lang racket/base
 
'(1 (" 2345") 67 8)

since the first character immediately after "five.rkt" is a +space.

A #reader form can be used in the REPL, too:

> '#reader"five.rkt"abcde

'("abcde")

17.2.1 Source Locations

The difference between read and +read-syntax is that read is meant to be +used for data while read-syntax is meant to be used to +parse programs. More precisely, the read function will +be used when the enclosing stream is being parsed by the Racket +read, and read-syntax is used when the +enclosing stream is being parsed by the Racket read-syntax +function. Nothing requires read and +read-syntax to parse input in the same way, but making +them different would confuse programmers and tools.

The read-syntax function can return the same kind of +value as read, but it should normally return a +syntax object that connects the parsed expression with source +locations. Unlike the "five.rkt" example, the +read-syntax function is typically implemented directly +to produce syntax objects, and then read can use +read-syntax and strip away syntax object +wrappers to produce a raw result.

The following "arith.rkt" module implements a reader to +parse simple infix arithmetic expressions into Racket forms. For +example, 1*2+3 parses into the Racket form (+ (* 1 2) 3). The supported operators are +, -, +*, and /, while operands can be unsigned integers +or single-letter variables. The implementation uses +port-next-location to obtain the current source location, and +it uses datum->syntax to turn raw values into syntax +objects.

"arith.rkt"

#lang racket
(require syntax/readerr)
 
(provide read read-syntax)
 
(define (read in)
  (syntax->datum (read-syntax #f in)))
 
(define (read-syntax src in)
  (skip-whitespace in)
  (read-arith src in))
 
(define (skip-whitespace in)
  (regexp-match #px"^\\s*" in))
 
(define (read-arith src in)
  (define-values (line col pos) (port-next-location in))
  (define expr-match
    (regexp-match
     ; Match an operand followed by any number of
     ; operatoroperand sequences, and prohibit an
     ; additional operator from following immediately:
     #px"^([a-z]|[0-9]+)(?:[-+*/]([a-z]|[0-9]+))*(?![-+*/])"
     in))
 
  (define (to-syntax v delta span-str)
    (datum->syntax #f v (make-srcloc delta span-str)))
  (define (make-srcloc delta span-str)
    (and line
         (vector src line (+ col delta) (+ pos delta)
                 (string-length span-str))))
 
  (define (parse-expr s delta)
    (match (or (regexp-match #rx"^(.*)([+-])(.*?)$" s)
               (regexp-match #rx"^(.*)([*/])(.*?)$" s))
      [(list _ a-str op-str b-str)
       (define a-len (string-length a-str))
       (define a (parse-expr a-str delta))
       (define b (parse-expr b-str (+ delta 1 a-len)))
       (define op (to-syntax (string->symbol op-str)
                             (+ delta a-len) op-str))
       (to-syntax (list op a b) delta s)]
      [_ (to-syntax (or (string->number s)
                        (string->symbol s))
                    delta s)]))
 
  (unless expr-match
    (raise-read-error "bad arithmetic syntax"
                      src line col pos
                      (and pos (- (file-position in) pos))))
  (parse-expr (bytes->string/utf-8 (car expr-match)) 0))

If the "arith.rkt" reader is used in an expression position, +then its parse result will be treated as a Racket expression. If it is +used in a quoted form, however, then it just produces a number or a +list:

> #reader"arith.rkt" 1*2+3

5

> '#reader"arith.rkt" 1*2+3

'(+ (* 1 2) 3)

The "arith.rkt" reader could also be used in positions that +make no sense. Since the read-syntax implementation +tracks source locations, syntax errors can at least refer to parts of +the input in terms of their original locations (at the beginning of +the error message):

> (let #reader"arith.rkt" 1*2+3 8)

repl:1:27: let: bad syntax (not an identifier and expression

for a binding)

  at: +

  in: (let (+ (* 1 2) 3) 8)

17.2.2 Readtables

A reader extension’s ability to parse input characters in an arbitrary +way can be powerful, but many cases of lexical extension call for a +less general but more composable approach. In much the same way that +the expander level of Racket syntax can be extended through +macros, the reader level of Racket syntax can be +composably extended through a readtable.

The Racket reader is a recursive-descent parser, and the +readtable maps characters to parsing handlers. For example, the +default readtable maps ( to a handler that recursively +parses subforms until it finds a ). The +current-readtable parameter determines the +readtable that is used by read or +read-syntax. Rather than parsing raw characters directly, a +reader extension can install an extended readtable and then +chain to read or read-syntax.

+See Dynamic Binding: parameterize for an introduction to +parameters.

The make-readtable function constructs a new readtable +as an extension of an existing one. It accepts a sequence of +specifications in terms of a character, a type of mapping for the +character, and (for certain types of mappings) a parsing +procedure. For example, to extend the readtable so that $ +can be used to start and end infix expressions, implement a +read-dollar function and use:

(make-readtable (current-readtable)
                #\$ 'terminating-macro read-dollar)

The protocol for read-dollar requires the function to accept +different numbers of arguments depending on whether it is being used +in read or read-syntax mode. In read mode, +the parser function is given two arguments: the character that +triggered the parser function and the input port that is being +read. In read-syntax mode, the function must accept four +additional arguments that provide the source location of the +character.

The following "dollar.rkt" module defines a +read-dollar function in terms of the read and +read-syntax functions provided by "arith.rkt", +and it puts read-dollar together with new read and +read-syntax functions that install the readtable and +chain to Racket’s read or read-syntax:

"dollar.rkt"

#lang racket
(require syntax/readerr
         (prefix-in arith: "arith.rkt"))
 
(provide (rename-out [$-read read]
                     [$-read-syntax read-syntax]))
 
(define ($-read in)
  (parameterize ([current-readtable (make-$-readtable)])
    (read in)))
 
(define ($-read-syntax src in)
  (parameterize ([current-readtable (make-$-readtable)])
    (read-syntax src in)))
 
(define (make-$-readtable)
  (make-readtable (current-readtable)
                  #\$ 'terminating-macro read-dollar))
 
(define read-dollar
  (case-lambda
   [(ch in)
    (check-$-after (arith:read in) in (object-name in))]
   [(ch in src line col pos)
    (check-$-after (arith:read-syntax src in) in src)]))
 
(define (check-$-after val in src)
  (regexp-match #px"^\\s*" in) ; skip whitespace
  (let ([ch (peek-char in)])
    (unless (equal? ch #\$) (bad-ending ch src in))
    (read-char in))
  val)
 
(define (bad-ending ch src in)
  (let-values ([(line col pos) (port-next-location in)])
    ((if (eof-object? ch)
         raise-read-error
         raise-read-eof-error)
     "expected a closing `$'"
     src line col pos
     (if (eof-object? ch) 0 1))))

With this reader extension, a single #reader can be +used at the beginning of an expression to enable multiple uses of +$ that switch to infix arithmetic:

> #reader"dollar.rkt" (let ([a $1*2+3$] [b $5/6$]) $a+b$)

35/6

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-tables.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-tables.html new file mode 100644 index 00000000..15a4f937 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/hash-tables.html @@ -0,0 +1,29 @@ + +3.10 Hash Tables

3.10 Hash Tables

A hash table implements a mapping from keys to values, where +both keys and values can be arbitrary Racket values, and access and +update to the table are normally constant-time operations. Keys are +compared using equal?, eqv?, or eq?, depending on whether +the hash table is created with make-hash, +make-hasheqv, or make-hasheq.

Examples:
> (define ht (make-hash))
> (hash-set! ht "apple" '(red round))
> (hash-set! ht "banana" '(yellow long))
> (hash-ref ht "apple")

'(red round)

> (hash-ref ht "coconut")

hash-ref: no value found for key

  key: "coconut"

> (hash-ref ht "coconut" "not there")

"not there"

The hash, hasheqv, and hasheq functions +create immutable hash tables from an initial set of keys and values, +in which each value is provided as an argument after its key. Immutable +hash tables can be extended with hash-set, which produces a +new immutable hash table in constant time.

Examples:
> (define ht (hash "apple" 'red "banana" 'yellow))
> (hash-ref ht "apple")

'red

> (define ht2 (hash-set ht "coconut" 'brown))
> (hash-ref ht "coconut")

hash-ref: no value found for key

  key: "coconut"

> (hash-ref ht2 "coconut")

'brown

A literal immutable hash table can be written as an expression by using +#hash (for an equal?-based table), +#hasheqv (for an eqv?-based table), or +#hasheq (for an eq?-based table). A parenthesized +sequence must immediately follow #hash, #hasheq, +or #hasheqv, where each element is a dotted +key–value pair. The #hash, etc. forms implicitly +quote their key and value sub-forms.

Examples:
> (define ht #hash(("apple" . red)
                   ("banana" . yellow)))
> (hash-ref ht "apple")

'red

+Reading Hash Tables in The Racket Reference documents the fine points of the syntax of hash table literals.

Both mutable and immutable hash tables print like immutable hash +tables, using a quoted #hash, #hasheqv, or +#hasheq form if all keys and values can be expressed with +quote or using hash, hasheq, or +hasheqv otherwise:

Examples:
> #hash(("apple" . red)
        ("banana" . yellow))

'#hash(("apple" . red) ("banana" . yellow))

> (hash 1 (srcloc "file.rkt" 1 0 1 (+ 4 4)))

(hash 1 (srcloc "file.rkt" 1 0 1 8))

A mutable hash table can optionally retain its keys +weakly, so each mapping is retained only so long as the key +is retained elsewhere.

Examples:
> (define ht (make-weak-hasheq))
> (hash-set! ht (gensym) "can you see me?")
> (collect-garbage)
> (hash-count ht)

0

Beware that even a weak hash table retains its values strongly, as +long as the corresponding key is accessible. This creates a catch-22 +dependency when a value refers back to its key, so that the mapping is +retained permanently. To break the cycle, map the key to an ephemeron +that pairs the value with its key (in addition to the implicit pairing +of the hash table).

+Ephemerons in The Racket Reference documents the fine points of using ephemerons.

Examples:
> (define ht (make-weak-hasheq))
> (let ([g (gensym)])
    (hash-set! ht g (list g)))
> (collect-garbage)
> (hash-count ht)

1

> (define ht (make-weak-hasheq))
> (let ([g (gensym)])
    (hash-set! ht g (make-ephemeron g (list g))))
> (collect-garbage)
> (hash-count ht)

0

+Hash Tables in The Racket Reference provides more on hash tables and hash-table procedures.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/i_o.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/i_o.html new file mode 100644 index 00000000..65af8f28 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/i_o.html @@ -0,0 +1,9 @@ + +8 Input and Output

8 Input and Output

A Racket port corresponds to the Unix notion of a stream +(not to be confused with racket/stream’s streams).

A Racket port represents a source or sink of data, such as a +file, a terminal, a TCP connection, or an in-memory string. Ports +provide sequential access in which data can be read or written a piece +of a time, without requiring the data to be consumed or produced all +at once. More specifically, an input port represents a +source from which a program can read data, and an output +port represents a sink to which a program can write data.

    8.1 Varieties of Ports

    8.2 Default Ports

    8.3 Reading and Writing Racket Data

    8.4 Datatypes and Serialization

    8.5 Bytes, Characters, and Encodings

    8.6 I/O Patterns

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/icons.css b/clones/download.racket-lang.org/releases/8.6/doc/guide/icons.css new file mode 100644 index 00000000..4923ee0f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/icons.css @@ -0,0 +1,8 @@ +.imageleft { + float: left; + margin-right: 0.3em; +} + +.imageleft img { + width: 1.5em; +} diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/index.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/index.html new file mode 100644 index 00000000..55834df4 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/index.html @@ -0,0 +1,10 @@ + +The Racket Guide
8.6

The Racket Guide

Matthew Flatt,
Robert Bruce Findler,
and PLT

This guide is intended for programmers who are new to Racket or new to +some part of Racket. It assumes programming experience, so if you are +new to programming, consider instead reading How to Design Programs. If you want an +especially quick introduction to Racket, start with Quick: An Introduction to Racket with Pictures.

Chapter 2 provides a brief introduction to +Racket. From Chapter 3 on, this guide dives +into details—covering much of the Racket toolbox, but leaving +precise details to The Racket Reference and other reference manuals.

The source of this manual is available on +GitHub.

    1 Welcome to Racket

      1.1 Interacting with Racket

      1.2 Definitions and Interactions

      1.3 Creating Executables

      1.4 A Note to Readers with Lisp/Scheme Experience

    2 Racket Essentials

      2.1 Simple Values

      2.2 Simple Definitions and Expressions

        2.2.1 Definitions

        2.2.2 An Aside on Indenting Code

        2.2.3 Identifiers

        2.2.4 Function Calls (Procedure Applications)

        2.2.5 Conditionals with if, and, or, and cond

        2.2.6 Function Calls, Again

        2.2.7 Anonymous Functions with lambda

        2.2.8 Local Binding with +define, let, and let*

      2.3 Lists, Iteration, and Recursion

        2.3.1 Predefined List Loops

        2.3.2 List Iteration from Scratch

        2.3.3 Tail Recursion

        2.3.4 Recursion versus Iteration

      2.4 Pairs, Lists, and Racket Syntax

        2.4.1 Quoting Pairs and Symbols with quote

        2.4.2 Abbreviating quote with '

        2.4.3 Lists and Racket Syntax

    3 Built-In Datatypes

      3.1 Booleans

      3.2 Numbers

      3.3 Characters

      3.4 Strings (Unicode)

      3.5 Bytes and Byte Strings

      3.6 Symbols

      3.7 Keywords

      3.8 Pairs and Lists

      3.9 Vectors

      3.10 Hash Tables

      3.11 Boxes

      3.12 Void and Undefined

    4 Expressions and Definitions

      4.1 Notation

      4.2 Identifiers and Binding

      4.3 Function Calls (Procedure Applications)

        4.3.1 Evaluation Order and Arity

        4.3.2 Keyword Arguments

        4.3.3 The apply Function

      4.4 Functions (Procedures): lambda

        4.4.1 Declaring a Rest Argument

        4.4.2 Declaring Optional Arguments

        4.4.3 Declaring Keyword Arguments

        4.4.4 Arity-Sensitive Functions: case-lambda

      4.5 Definitions: define

        4.5.1 Function Shorthand

        4.5.2 Curried Function Shorthand

        4.5.3 Multiple Values and define-values

        4.5.4 Internal Definitions

      4.6 Local Binding

        4.6.1 Parallel Binding: let

        4.6.2 Sequential Binding: let*

        4.6.3 Recursive Binding: letrec

        4.6.4 Named let

        4.6.5 Multiple Values: let-values, let*-values, letrec-values

      4.7 Conditionals

        4.7.1 Simple Branching: if

        4.7.2 Combining Tests: and and or

        4.7.3 Chaining Tests: cond

      4.8 Sequencing

        4.8.1 Effects Before: begin

        4.8.2 Effects After: begin0

        4.8.3 Effects If...: when and unless

      4.9 Assignment: set!

        4.9.1 Guidelines for Using Assignment

        4.9.2 Multiple Values: set!-values

      4.10 Quoting: quote and

      4.11 Quasiquoting: quasiquote and

      4.12 Simple Dispatch: case

      4.13 Dynamic Binding: parameterize

    5 Programmer-Defined Datatypes

      5.1 Simple Structure Types: struct

      5.2 Copying and Update

      5.3 Structure Subtypes

      5.4 Opaque versus Transparent Structure Types

      5.5 Structure Comparisons

      5.6 Structure Type Generativity

      5.7 Prefab Structure Types

      5.8 More Structure Type Options

    6 Modules

      6.1 Module Basics

        6.1.1 Organizing Modules

        6.1.2 Library Collections

        6.1.3 Packages and Collections

        6.1.4 Adding Collections

        6.1.5 Module References Within a Collection

      6.2 Module Syntax

        6.2.1 The module Form

        6.2.2 The #lang Shorthand

        6.2.3 Submodules

        6.2.4 Main and Test Submodules

      6.3 Module Paths

      6.4 Imports: require

      6.5 Exports: provide

      6.6 Assignment and Redefinition

      6.7 Modules and Macros

      6.8 Protected Exports

    7 Contracts

      7.1 Contracts and Boundaries

        7.1.1 Contract Violations

        7.1.2 Experimenting with Contracts and Modules

        7.1.3 Experimenting with Nested Contract Boundaries

      7.2 Simple Contracts on Functions

        7.2.1 Styles of ->

        7.2.2 Using define/contract and ->

        7.2.3 any and any/c

        7.2.4 Rolling Your Own Contracts

        7.2.5 Contracts on Higher-order Functions

        7.2.6 Contract Messages with “???”

        7.2.7 Dissecting a contract error message

      7.3 Contracts on Functions in General

        7.3.1 Optional Arguments

        7.3.2 Rest Arguments

        7.3.3 Keyword Arguments

        7.3.4 Optional Keyword Arguments

        7.3.5 Contracts for case-lambda

        7.3.6 Argument and Result Dependencies

        7.3.7 Checking State Changes

        7.3.8 Multiple Result Values

        7.3.9 Fixed but Statically Unknown Arities

      7.4 Contracts: A Thorough Example

      7.5 Contracts on Structures

        7.5.1 Guarantees for a Specific Value

        7.5.2 Guarantees for All Values

        7.5.3 Checking Properties of Data Structures

      7.6 Abstract Contracts using #:exists and #:∃

      7.7 Additional Examples

        7.7.1 A Customer-Manager Component

        7.7.2 A Parameteric (Simple) Stack

        7.7.3 A Dictionary

        7.7.4 A Queue

      7.8 Building New Contracts

        7.8.1 Contract Struct Properties

        7.8.2 With all the Bells and Whistles

      7.9 Gotchas

        7.9.1 Contracts and eq?

        7.9.2 Contract boundaries and define/contract

        7.9.3 Exists Contracts and Predicates

        7.9.4 Defining Recursive Contracts

        7.9.5 Mixing set! and contract-out

    8 Input and Output

      8.1 Varieties of Ports

      8.2 Default Ports

      8.3 Reading and Writing Racket Data

      8.4 Datatypes and Serialization

      8.5 Bytes, Characters, and Encodings

      8.6 I/O Patterns

    9 Regular Expressions

      9.1 Writing Regexp Patterns

      9.2 Matching Regexp Patterns

      9.3 Basic Assertions

      9.4 Characters and Character Classes

        9.4.1 Some Frequently Used Character Classes

        9.4.2 POSIX character classes

      9.5 Quantifiers

      9.6 Clusters

        9.6.1 Backreferences

        9.6.2 Non-capturing Clusters

        9.6.3 Cloisters

      9.7 Alternation

      9.8 Backtracking

      9.9 Looking Ahead and Behind

        9.9.1 Lookahead

        9.9.2 Lookbehind

      9.10 An Extended Example

    10 Exceptions and Control

      10.1 Exceptions

      10.2 Prompts and Aborts

      10.3 Continuations

    11 Iterations and Comprehensions

      11.1 Sequence Constructors

      11.2 for and for*

      11.3 for/list and for*/list

      11.4 for/vector and for*/vector

      11.5 for/and and for/or

      11.6 for/first and for/last

      11.7 for/fold and for*/fold

      11.8 Multiple-Valued Sequences

      11.9 Breaking an Iteration

      11.10 Iteration Performance

    12 Pattern Matching

    13 Classes and Objects

      13.1 Methods

      13.2 Initialization Arguments

      13.3 Internal and External Names

      13.4 Interfaces

      13.5 Final, Augment, and Inner

      13.6 Controlling the Scope of External Names

      13.7 Mixins

        13.7.1 Mixins and Interfaces

        13.7.2 The mixin Form

        13.7.3 Parameterized Mixins

      13.8 Traits

        13.8.1 Traits as Sets of Mixins

        13.8.2 Inherit and Super in Traits

        13.8.3 The trait Form

      13.9 Class Contracts

        13.9.1 External Class Contracts

        13.9.2 Internal Class Contracts

    14 Units (Components)

      14.1 Signatures and Units

      14.2 Invoking Units

      14.3 Linking Units

      14.4 First-Class Units

      14.5 Whole-module Signatures and Units

      14.6 Contracts for Units

        14.6.1 Adding Contracts to Signatures

        14.6.2 Adding Contracts to Units

      14.7 unit versus module

    15 Reflection and Dynamic Evaluation

      15.1 eval

        15.1.1 Local Scopes

        15.1.2 Namespaces

        15.1.3 Namespaces and Modules

      15.2 Manipulating Namespaces

        15.2.1 Creating and Installing Namespaces

        15.2.2 Sharing Data and Code Across Namespaces

      15.3 Scripting Evaluation and Using load

      15.4 Code Inspectors for Trusted and Untrusted Code

    16 Macros

      16.1 Pattern-Based Macros

        16.1.1 define-syntax-rule

        16.1.2 Lexical Scope

        16.1.3 define-syntax and syntax-rules

        16.1.4 Matching Sequences

        16.1.5 Identifier Macros

        16.1.6 set! Transformers

        16.1.7 Macro-Generating Macros

        16.1.8 Extended Example: Call-by-Reference Functions

      16.2 General Macro Transformers

        16.2.1 Syntax Objects

        16.2.2 Macro Transformer Procedures

        16.2.3 Mixing Patterns and Expressions: syntax-case

        16.2.4 with-syntax and generate-temporaries

        16.2.5 Compile and Run-Time Phases

        16.2.6 General Phase Levels

          16.2.6.1 Phases and Bindings

          16.2.6.2 Phases and Modules

        16.2.7 Tainted Syntax

      16.3 Module Instantiations and Visits

        16.3.1 Declaration versus Instantiation

        16.3.2 Compile-Time Instantiation

        16.3.3 Visiting Modules

        16.3.4 Lazy Visits via Available Modules

    17 Creating Languages

      17.1 Module Languages

        17.1.1 Implicit Form Bindings

        17.1.2 Using #lang s-exp

      17.2 Reader Extensions

        17.2.1 Source Locations

        17.2.2 Readtables

      17.3 Defining new #lang Languages

        17.3.1 Designating a #lang Language

        17.3.2 Using #lang reader

        17.3.3 Using #lang s-exp syntax/module-reader

        17.3.4 Installing a Language

        17.3.5 Source-Handling Configuration

        17.3.6 Module-Handling Configuration

    18 Concurrency and Synchronization

      18.1 Threads

      18.2 Thread Mailboxes

      18.3 Semaphores

      18.4 Channels

      18.5 Buffered Asynchronous Channels

      18.6 Synchronizable Events and sync

      18.7 Building Your Own Synchronization Patterns

    19 Performance

      19.1 Performance in DrRacket

      19.2 Racket Virtual Machine Implementations

      19.3 Bytecode, Machine Code, and Just-in-Time (JIT) Compilers

      19.4 Modules and Performance

      19.5 Function-Call Optimizations

      19.6 Mutation and Performance

      19.7 letrec Performance

      19.8 Fixnum and Flonum Optimizations

      19.9 Unchecked, Unsafe Operations

      19.10 Foreign Pointers

      19.11 Regular Expression Performance

      19.12 Memory Management

      19.13 Reachability and Garbage Collection

      19.14 Weak Boxes and Testing

      19.15 Reducing Garbage Collection Pauses

    20 Parallelism

      20.1 Parallelism with Futures

      20.2 Parallelism with Places

      20.3 Distributed Places

    21 Running and Creating Executables

      21.1 Running racket and gracket

        21.1.1 Interactive Mode

        21.1.2 Module Mode

        21.1.3 Load Mode

      21.2 Scripts

        21.2.1 Unix Scripts

        21.2.2 Windows Batch Files

      21.3 Creating Stand-Alone Executables

    22 More Libraries

      22.1 Graphics and GUIs

      22.2 The Web Server

      22.3 Using Foreign Libraries

      22.4 And More

    23 Dialects of Racket and Scheme

      23.1 More Rackets

      23.2 Standards

        23.2.1 R5RS

        23.2.2 R6RS

      23.3 Teaching

    24 Command-Line Tools and Your Editor of Choice

      24.1 Command-Line Tools

        24.1.1 Compilation and Configuration: raco

        24.1.2 Interactive evaluation

        24.1.3 Shell completion

      24.2 Emacs

        24.2.1 Major Modes

        24.2.2 Minor Modes

        24.2.3 Packages specific to Evil Mode

      24.3 Vim

        24.3.1 Plugins

        24.3.2 Indentation

        24.3.3 Highlighting

        24.3.4 Structured Editing

        24.3.5 REPLs

        24.3.6 Scribble

        24.3.7 Miscellaneous

      24.4 Sublime Text

      24.5 Visual Studio Code

    Bibliography

    Index

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/intro.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/intro.html new file mode 100644 index 00000000..57dd0a85 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/intro.html @@ -0,0 +1,75 @@ + +1 Welcome to Racket

1 Welcome to Racket

Depending on how you look at it, Racket is

  • a programming languagea dialect of Lisp and a +descendant of Scheme;

    See Dialects of Racket and Scheme for more information on +other dialects of Lisp and how they relate to Racket.

  • a family of programming languages—variants of +Racket, and more; or

  • a set of toolsfor using a family of programming languages.

Where there is no room for confusion, we use simply Racket.

Racket’s main tools are

  • racket, the core compiler, interpreter, and run-time system;

  • DrRacket, the programming environment; and

  • raco, a command-line tool for executing Racket +commands that install packages, build libraries, and more.

Most likely, you’ll want to explore the Racket language using +DrRacket, especially at the beginning. If you prefer, you can also +work with the command-line racket interpreter and your favorite +text editor; see also Command-Line Tools and Your Editor of Choice. The rest of this guide +presents the language mostly independent of your choice of editor.

If you’re using DrRacket, you’ll need to choose the proper language, +because DrRacket accommodates many different variants of Racket, as +well as other languages. Assuming that you’ve never used DrRacket +before, start it up, type the line

#lang racket

in DrRacket’s top text area, and then click the Run button +that’s above the text area. DrRacket then understands that you mean to +work in the normal variant of Racket (as opposed to the smaller +racket/base or many other possibilities).

More Rackets describes some of the other +possibilities.

If you’ve used DrRacket before with something other than a program +that starts #lang, DrRacket will remember the last language +that you used, instead of inferring the language from the #lang +line. In that case, use the Language|Choose Language... +menu item. In the dialog that appears, select the first item, which +tells DrRacket to use the language that is declared in a source +program via #lang. Put the #lang line above in the top +text area, still.

1.1 Interacting with Racket

DrRacket’s bottom text area and the racket command-line program +(when started with no options) both act as a kind of calculator. You +type a Racket expression, hit the Return key, and the answer is +printed. In the terminology of Racket, this kind of calculator is +called a read-eval-print loop or REPL.

A number by itself is an expression, and the answer is just the +number:

> 5

5

A string is also an expression that evaluates to itself. A string is +written with double quotes at the start and end of the string:

> "Hello, world!"

"Hello, world!"

Racket uses parentheses to wrap larger expressions—almost any kind +of expression, other than simple constants. For example, a function +call is written: open parenthesis, function name, argument +expression, and closing parenthesis. The following expression calls +the built-in function substring with the arguments +"the boy out of the country", 4, and 7:

> (substring "the boy out of the country" 4 7)

"boy"

1.2 Definitions and Interactions

You can define your own functions that work like substring by +using the define form, like this:

(define (extract str)
  (substring str 4 7))

 

> (extract "the boy out of the country")

"boy"

> (extract "the country out of the boy")

"cou"

Although you can evaluate the define form in the REPL, +definitions are normally a part of a program that you want to keep and +use later. So, in DrRacket, you’d normally put the definition in the +top text area—called the definitions areaalong with the +#lang prefix:

#lang racket
 
(define (extract str)
  (substring str 4 7))

If calling (extract "the boy") is part of the main action of +your program, that would go in the definitions area, too. But +if it was just an example expression that you were using to explore +extract, then you’d more likely leave the definitions +area as above, click Run, and then evaluate +(extract "the boy") in the REPL.

When using command-line racket instead of DrRacket, you’d save +the above text in a file using your favorite editor. If you save it as +"extract.rkt", then after starting racket in the same +directory, you’d evaluate the following sequence:

If you use xrepl, you can use +,enter extract.rkt.

> (enter! "extract.rkt")
> (extract "the gal out of the city")

"gal"

The enter! form both loads the code and switches the +evaluation context to the inside of the module, just like DrRacket’s +Run button.

1.3 Creating Executables

If your file (or definitions area in DrRacket) contains

#lang racket
 
(define (extract str)
  (substring str 4 7))
 
(extract "the cat out of the bag")

then it is a complete program that prints “cat” when run. You can +run the program within DrRacket or using enter! in +racket, but if the program is saved in src-filename, +you can also run it from a command line with

  racket src-filename

To package the program as an executable, you have a few options:

  • In DrRacket, you can select the Racket|Create + Executable... menu item.

  • From a command-line prompt, run raco exe +src-filename, where src-filename contains +the program. See raco exe: Creating Stand-Alone Executables for more information.

  • With Unix or Mac OS, you can turn the program file into an +executable script by inserting the line

    See Scripts for more information on +script files.

      #! /usr/bin/env racket

    at the very beginning of the file. Also, change the file +permissions to executable using chmod +x +filename on the command line.

    The script works as long as racket is in the user’s +executable search path. Alternately, use a full path to +racket after #! (with a space between #! +and the path), in which case the user’s executable search path +does not matter.

1.4 A Note to Readers with Lisp/Scheme Experience

If you already know something about Scheme or Lisp, you might be +tempted to put just

(define (extract str)
  (substring str 4 7))

into "extract.rktl" and run racket with

> (load "extract.rktl")
> (extract "the dog out")

"dog"

That will work, because racket is willing to imitate a +traditional Lisp environment, but we strongly recommend against using +load or writing programs outside of a module.

Writing definitions outside of a module leads to bad error messages, +bad performance, and awkward scripting to combine and run +programs. The problems are not specific to racket; they’re +fundamental limitations of the traditional top-level environment, +which Scheme and Lisp implementations have historically fought with ad +hoc command-line flags, compiler directives, and build tools. The +module system is designed to avoid these problems, so start with +#lang, and you’ll be happier with Racket in the long run.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/io-patterns.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/io-patterns.html new file mode 100644 index 00000000..30ad4e52 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/io-patterns.html @@ -0,0 +1,19 @@ + +8.6 I/O Patterns

8.6 I/O Patterns

For these examples, say you have two files in the same directory as +your program, "oneline.txt" and "manylines.txt".

"oneline.txt"

 I am one line, but there is an empty line after this one.

 

"manylines.txt"

 I am

 a message

 split over a few lines.

 

If you have a file that is quite small, you can get +away with reading in the file as a string:

Examples:
> (define file-contents
    (port->string (open-input-file "oneline.txt") #:close? #t))
> (string-suffix? file-contents "after this one.")

#f

> (string-suffix? file-contents "after this one.\n")

#t

> (string-suffix? (string-trim file-contents) "after this one.")

#t

We use port->string from racket/port to do the +reading to a string: the #:close? #t keyword argument ensures +that our file is closed after the read.

We use string-trim from racket/string to remove +any extraneous whitespace at the very beginning and very end of our file. +(Lots of formatters out there insist that text files end with a single +blank line).

See also read-line if your file has one line of text.

If, instead, you want to process individual lines of a file, then you can +use for with in-lines:

> (define (upcase-all in)
    (for ([l (in-lines in)])
      (display (string-upcase l))
      (newline)))
> (upcase-all (open-input-string
               (string-append
                "Hello, World!\n"
                "Can you hear me, now?")))

HELLO, WORLD!

CAN YOU HEAR ME, NOW?

You could also combine computations over each line. So if you want to +know how many lines contain “m”, you could do:

Example:
> (with-input-from-file "manylines.txt"
    (lambda ()
      (for/sum ([l (in-lines)]
                 #:when (string-contains? l "m"))
        1)))

2

Here, with-input-from-file from racket/port sets +the default input port to be the file "manylines.txt" inside +the thunk. It also closes the file after the computation has been +completed (and in a few other cases).

However, if you want to determine whether “hello” appears in a file, +then you could search separate lines, but it’s even easier to simply +apply a regular expression (see Regular Expressions) to the stream:

> (define (has-hello? in)
    (regexp-match? #rx"hello" in))
> (has-hello? (open-input-string "hello"))

#t

> (has-hello? (open-input-string "goodbye"))

#f

If you want to copy one port into another, use copy-port from +racket/port, which efficiently transfers large blocks +when lots of data is available, but also transfers small blocks +immediately if that’s all that is available:

> (define o (open-output-string))
> (copy-port (open-input-string "broom") o)
> (get-output-string o)

"broom"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/keywords.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/keywords.html new file mode 100644 index 00000000..909f0a70 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/keywords.html @@ -0,0 +1,14 @@ + +3.7 Keywords

3.7 Keywords

A keyword value is similar to a symbol (see +Symbols), but its printed form is prefixed with +#:.

+Reading Keywords in The Racket Reference documents the fine points of the syntax of keywords.

Examples:
> (string->keyword "apple")

'#:apple

> '#:apple

'#:apple

> (eq? '#:apple (string->keyword "apple"))

#t

More precisely, a keyword is analogous to an identifier; in the same +way that an identifier can be quoted to produce a symbol, a keyword +can be quoted to produce a value. The same term “keyword” is used in +both cases, but we sometimes use keyword value to refer more +specifically to the result of a quote-keyword expression or of +string->keyword. An unquoted keyword is not an expression, +just as an unquoted identifier does not produce a symbol:

Examples:
> not-a-symbol-expression

not-a-symbol-expression: undefined;

 cannot reference an identifier before its definition

  in module: top-level

> #:not-a-keyword-expression

eval:2:0: #%datum: keyword misused as an expression

  at: #:not-a-keyword-expression

Despite their similarities, keywords are used in a different way than +identifiers or symbols. Keywords are intended for use (unquoted) as +special markers in argument lists and in certain syntactic forms. For +run-time flags and enumerations, use symbols instead of keywords. The +example below illustrates the distinct roles of keywords and symbols.

Examples:
> (define dir (find-system-path 'temp-dir)) ; not '#:temp-dir
> (with-output-to-file (build-path dir "stuff.txt")
    (lambda () (printf "example\n"))
    ; optional #:mode argument can be 'text or 'binary
    #:mode 'text
    ; optional #:exists argument can be 'replace, 'truncate, ...
    #:exists 'replace)

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/lambda.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/lambda.html new file mode 100644 index 00000000..b77bbeaf --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/lambda.html @@ -0,0 +1,39 @@ + +4.4 Functions: lambda

4.4 Functions (Procedures): lambda

A lambda expression creates a function. In the simplest +case, a lambda expression has the form

(lambda (arg-id ...)
  body ...+)

A lambda form with n arg-ids accepts +n arguments:

> ((lambda (x) x)
   1)

1

> ((lambda (x y) (+ x y))
   1 2)

3

> ((lambda (x y) (+ x y))
   1)

arity mismatch;

 the expected number of arguments does not match the given

number

  expected: 2

  given: 1

4.4.1 Declaring a Rest Argument

A lambda expression can also have the form

(lambda rest-id
  body ...+)

That is, a lambda expression can have a single +rest-id that is not surrounded by parentheses. The resulting +function accepts any number of arguments, and the arguments are put +into a list bound to rest-id.

Examples:
> ((lambda x x)
   1 2 3)

'(1 2 3)

> ((lambda x x))

'()

> ((lambda x (car x))
   1 2 3)

1

Functions with a rest-id often use apply to call +another function that accepts any number of arguments.

+The apply Function describes apply.

Examples:
(define max-mag
  (lambda nums
    (apply max (map magnitude nums))))
> (max 1 -2 0)

1

> (max-mag 1 -2 0)

2

The lambda form also supports required arguments combined +with a rest-id:

(lambda (arg-id ...+ . rest-id)
  body ...+)

The result of this form is a function that requires at least as many +arguments as arg-ids, and also accepts any number of +additional arguments.

Examples:
(define max-mag
  (lambda (num . nums)
    (apply max (map magnitude (cons num nums)))))
> (max-mag 1 -2 0)

2

> (max-mag)

max-mag: arity mismatch;

 the expected number of arguments does not match the given

number

  expected: at least 1

  given: 0

A rest-id variable is sometimes called a rest +argument, because it accepts the “rest” of the function arguments.

4.4.2 Declaring Optional Arguments

Instead of just an identifier, an argument (other than a rest +argument) in a lambda form can be specified with an +identifier and a default value:

(lambda gen-formals
  body ...+)
 
gen-formals = (arg ...)
  | rest-id
  | (arg ...+ . rest-id)
     
arg = arg-id
  | [arg-id default-expr]

An argument of the form [arg-id default-expr] is +optional. When the argument is not supplied in an application, +default-expr produces the default value. The +default-expr can refer to any preceding arg-id, +and every following arg-id must have a default as well.

Examples:
(define greet
  (lambda (given [surname "Smith"])
    (string-append "Hello, " given " " surname)))
> (greet "John")

"Hello, John Smith"

> (greet "John" "Doe")

"Hello, John Doe"

(define greet
  (lambda (given [surname (if (equal? given "John")
                              "Doe"
                              "Smith")])
    (string-append "Hello, " given " " surname)))

 

> (greet "John")

"Hello, John Doe"

> (greet "Adam")

"Hello, Adam Smith"

4.4.3 Declaring Keyword Arguments

A lambda form can declare an argument to be passed by +keyword, instead of position. Keyword arguments can be mixed with +by-position arguments, and default-value expressions can be supplied +for either kind of argument:

+Keyword Arguments introduces function +calls with keywords.

(lambda gen-formals
  body ...+)
 
gen-formals = (arg ...)
  | rest-id
  | (arg ...+ . rest-id)
     
arg = arg-id
  | [arg-id default-expr]
  | arg-keyword arg-id
  | arg-keyword [arg-id default-expr]

An argument specified as arg-keyword arg-id is +supplied by an application using the same arg-keyword. The +position of the keyword–identifier pair in the argument list does not +matter for matching with arguments in an application, because it will +be matched to an argument value by keyword instead of by position.

(define greet
  (lambda (given #:last surname)
    (string-append "Hello, " given " " surname)))

 

> (greet "John" #:last "Smith")

"Hello, John Smith"

> (greet #:last "Doe" "John")

"Hello, John Doe"

An arg-keyword [arg-id default-expr] argument +specifies a keyword-based argument with a default value.

Examples:
(define greet
  (lambda (#:hi [hi "Hello"] given #:last [surname "Smith"])
    (string-append hi ", " given " " surname)))
> (greet "John")

"Hello, John Smith"

> (greet "Karl" #:last "Marx")

"Hello, Karl Marx"

> (greet "John" #:hi "Howdy")

"Howdy, John Smith"

> (greet "Karl" #:last "Marx" #:hi "Guten Tag")

"Guten Tag, Karl Marx"

The lambda form does not directly support the creation +of a function that accepts “rest” keywords. To construct a +function that accepts all keyword arguments, use +make-keyword-procedure. The function supplied to +make-keyword-procedure receives keyword arguments +through parallel lists in the first two (by-position) arguments, +and then all by-position arguments from an application as the +remaining by-position arguments.

+The apply Function introduces keyword-apply.

Examples:
(define (trace-wrap f)
  (make-keyword-procedure
   (lambda (kws kw-args . rest)
     (printf "Called with ~s ~s ~s\n" kws kw-args rest)
     (keyword-apply f kws kw-args rest))))
> ((trace-wrap greet) "John" #:hi "Howdy")

Called with (#:hi) ("Howdy") ("John")

"Howdy, John Smith"

+Procedure Expressions: lambda and case-lambda in The Racket Reference provides more on function expressions.

4.4.4 Arity-Sensitive Functions: case-lambda

The case-lambda form creates a function that can have +completely different behaviors depending on the number of arguments +that are supplied. A case-lambda expression has the form

(case-lambda
  [formals body ...+]
  ...)
 
formals = (arg-id ...)
  | rest-id
  | (arg-id ...+ . rest-id)

where each [formals body ...+] is analogous to (lambda formals body ...+). Applying a function produced by +case-lambda is like applying a lambda for the first +case that matches the number of given arguments.

Examples:
(define greet
  (case-lambda
    [(name) (string-append "Hello, " name)]
    [(given surname) (string-append "Hello, " given " " surname)]))
> (greet "John")

"Hello, John"

> (greet "John" "Smith")

"Hello, John Smith"

> (greet)

greet: arity mismatch;

 the expected number of arguments does not match the given

number

  given: 0

A case-lambda function cannot directly support optional or +keyword arguments.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/language-collection.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/language-collection.html new file mode 100644 index 00000000..b505a68f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/language-collection.html @@ -0,0 +1,21 @@ + +17.3.4 Installing a Language
17.3.4 Installing a Language

So far, we have used the reader meta-language to +access languages like "literal.rkt" and +"dollar-racket.rkt". If you want to use something like +#lang literal directly, then you must move +"literal.rkt" into a Racket collection named +"literal" (see also Adding Collections). +Specifically, move "literal.rkt" to a reader +submodule of "literal/main.rkt" for any directory name +"literal", like so:

"literal/main.rkt"

#lang racket
 
(module reader racket
  (require syntax/strip-context)
 
  (provide (rename-out [literal-read read]
                       [literal-read-syntax read-syntax]))
 
  (define (literal-read in)
    (syntax->datum
     (literal-read-syntax #f in)))
 
  (define (literal-read-syntax src in)
    (with-syntax ([str (port->string in)])
      (strip-context
       #'(module anything racket
           (provide data)
           (define data 'str))))))

Then, install the "literal" +directory as a package:

  cd /path/to/literal ; raco pkg install

After moving the file and installing the package, you can use +literal directly after #lang:

#lang literal
Technology!
System!
Perfect!

See raco: Racket Command-Line Tools +for more information on using raco.

You can also make your language available for others to install by +using the Racket package manager (see Package Management in Racket). After you create a "literal" +package and register it with the Racket package catalog (see +Package Catalogs), +others can install it using raco pkg:

  raco pkg install literal

Once installed, others can invoke the language the same way: by using +#lang literal at the top of a source file.

If you use a public source repository (e.g., GitHub), you can link +your package to the source. As you improve the package, others can +update their version using raco pkg:

  raco pkg update literal

See Package Management in Racket for more +information about the Racket package manager.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/language-get-info.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/language-get-info.html new file mode 100644 index 00000000..b2bd2d31 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/language-get-info.html @@ -0,0 +1,48 @@ + +17.3.5 Source-Handling Configuration
17.3.5 Source-Handling Configuration

The Racket distribution includes a Scribble language for writing prose +documents, where Scribble extends the normal Racket to better support +text. Here is an example Scribble document:

  #lang scribble/base

  

  @(define (get-name) "Self-Describing Document")

  

  @title[(get-name)]

  

  The title of this document is ``@(get-name).''

If you put that program in DrRacket’s definitions area and +click Run, then nothing much appears to happen. The +scribble/base language just binds and exports +doc as a description of a document, similar to the way +that "literal.rkt" exports a string as data.

Simply opening a module with the language +scribble/base in DrRacket, however, causes a +Scribble HTML button to appear. Furthermore, DrRacket knows +how to colorize Scribble syntax by coloring green those parts of the +document that correspond to literal text. The language name +scribble/base is not hard-wired into +DrRacket. Instead, the implementation of the +scribble/base language provides button and +syntax-coloring information in response to a query from DrRacket.

If you have installed the literal language as described in +Installing a Language, then you can adjust +"literal/main.rkt" so that DrRacket treats the content +of a module in the literal language as plain text instead of +(erroneously) as Racket syntax:

"literal/main.rkt"

#lang racket
 
(module reader racket
  (require syntax/strip-context)
 
  (provide (rename-out [literal-read read]
                       [literal-read-syntax read-syntax])
           get-info)
 
  (define (literal-read in)
    (syntax->datum
     (literal-read-syntax #f in)))
 
  (define (literal-read-syntax src in)
    (with-syntax ([str (port->string in)])
      (strip-context
       #'(module anything racket
           (provide data)
           (define data 'str)))))
 
  (define (get-info in mod line col pos)
    (lambda (key default)
      (case key
        [(color-lexer)
         (dynamic-require 'syntax-color/default-lexer
                          'default-lexer)]
        [else default]))))

This revised literal implementation provides a +get-info function. The get-info function +is called by read-language (which DrRacket calls) with the +source input stream and location information, +in case query results should depend on the content of the module after +the language name (which is not the case for literal). The +result of get-info is a function of two arguments. The +first argument is always a symbol, indicating the kind of information +that a tool requests from the language; the second argument is the +default result to be returned if the language does not recognize the +query or has no information for it.

After DrRacket obtains the result of get-info for a +language, it calls the function with a 'color-lexer query; +the result should be a function that implements syntax-coloring +parsing on an input stream. For literal, the +syntax-color/default-lexer module provides a +default-lexer syntax-coloring parser that is suitable for +plain text, so literal loads and returns that parser in +response to a 'color-lexer query.

The set of symbols that a programming tool uses for queries +is entirely between the tool and the languages that choose to +cooperate with it. For example, in addition to 'color-lexer, +DrRacket uses a 'drracket:toolbar-buttons query to determine +which buttons should be available in the toolbar to operate on modules +using the language.

The syntax/module-reader language lets you specify +get-info handling through a #:info optional +specification. The protocol for an #:info function is +slightly different from the raw get-info protocol; the +revised protocol allows syntax/module-reader the +possibility of handling future language-information queries +automatically.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/languages.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/languages.html new file mode 100644 index 00000000..a0871579 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/languages.html @@ -0,0 +1,14 @@ + +17 Creating Languages

17 Creating Languages

The macro facilities defined in the preceding chapter let a +programmer define syntactic extensions to a language, but a macro is +limited in two ways:

  • a macro cannot restrict the syntax available in its context or +change the meaning of surrounding forms; and

  • a macro can extend the syntax of a language only within the +parameters of the language’s lexical conventions, such as using +parentheses to group the macro name with its subforms and using +the core syntax of identifiers, keywords, and literals.

+The distinction between the reader and +expander layer is introduced in Lists and Racket Syntax.

That is, a macro can only extend a language, and it can do so only at +the expander layer. Racket offers additional facilities for +defining a starting point of the expander layer, for extending +the reader layer, for defining the starting point of the +reader layer, and for packaging a reader and +expander starting point into a conveniently named language.

    17.1 Module Languages

      17.1.1 Implicit Form Bindings

      17.1.2 Using #lang s-exp

    17.2 Reader Extensions

      17.2.1 Source Locations

      17.2.2 Readtables

    17.3 Defining new #lang Languages

      17.3.1 Designating a #lang Language

      17.3.2 Using #lang reader

      17.3.3 Using #lang s-exp syntax/module-reader

      17.3.4 Installing a Language

      17.3.5 Source-Handling Configuration

      17.3.6 Module-Handling Configuration

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/let.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/let.html new file mode 100644 index 00000000..52409850 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/let.html @@ -0,0 +1,43 @@ + +4.6 Local Binding

4.6 Local Binding

Although internal defines can be used for local binding, +Racket provides three forms that give the programmer more +control over bindings: let, let*, and +letrec.

4.6.1 Parallel Binding: let

+Local Binding: let, let*, letrec, ... in The Racket Reference also documents let.

A let form binds a set of identifiers, each to the result of +some expression, for use in the let body:

(let ([id expr] ...) body ...+)

The ids are bound “in parallel.” That is, no id +is bound in the right-hand side expr for any id, +but all are available in the body. The ids must be +different from each other.

Examples:
> (let ([me "Bob"])
    me)

"Bob"

> (let ([me "Bob"]
        [myself "Robert"]
        [I "Bobby"])
    (list me myself I))

'("Bob" "Robert" "Bobby")

> (let ([me "Bob"]
        [me "Robert"])
    me)

eval:3:0: let: duplicate identifier

  at: me

  in: (let ((me "Bob") (me "Robert")) me)

The fact that an id’s expr does not see its own +binding is often useful for wrappers that must refer back to the old +value:

> (let ([+ (lambda (x y)
             (if (string? x)
                 (string-append x y)
                 (+ x y)))]) ; use original +
    (list (+ 1 2)
          (+ "see" "saw")))

'(3 "seesaw")

Occasionally, the parallel nature of let bindings is +convenient for swapping or rearranging a set of bindings:

> (let ([me "Tarzan"]
        [you "Jane"])
    (let ([me you]
          [you me])
      (list me you)))

'("Jane" "Tarzan")

The characterization of let bindings as “parallel” is not +meant to imply concurrent evaluation. The exprs are +evaluated in order, even though the bindings are delayed until all +exprs are evaluated.

4.6.2 Sequential Binding: let*

+Local Binding: let, let*, letrec, ... in The Racket Reference also documents let*.

The syntax of let* is the same as let:

(let* ([id expr] ...) body ...+)

The difference is that each id is available for use in later +exprs, as well as in the body. Furthermore, the +ids need not be distinct, and the most recent binding is the +visible one.

Examples:
> (let* ([x (list "Burroughs")]
         [y (cons "Rice" x)]
         [z (cons "Edgar" y)])
    (list x y z))

'(("Burroughs") ("Rice" "Burroughs") ("Edgar" "Rice" "Burroughs"))

> (let* ([name (list "Burroughs")]
         [name (cons "Rice" name)]
         [name (cons "Edgar" name)])
    name)

'("Edgar" "Rice" "Burroughs")

In other words, a let* form is equivalent to nested +let forms, each with a single binding:

> (let ([name (list "Burroughs")])
    (let ([name (cons "Rice" name)])
      (let ([name (cons "Edgar" name)])
        name)))

'("Edgar" "Rice" "Burroughs")

4.6.3 Recursive Binding: letrec

+Local Binding: let, let*, letrec, ... in The Racket Reference also documents letrec.

The syntax of letrec is also the same as let:

(letrec ([id expr] ...) body ...+)

While let makes its bindings available only in the +bodys, and let* makes its bindings available to any +later binding expr, letrec makes its bindings +available to all other exprs—even earlier ones. In other +words, letrec bindings are recursive.

The exprs in a letrec form are most often +lambda forms for recursive and mutually recursive functions:

> (letrec ([swing
            (lambda (t)
              (if (eq? (car t) 'tarzan)
                  (cons 'vine
                        (cons 'tarzan (cddr t)))
                  (cons (car t)
                        (swing (cdr t)))))])
    (swing '(vine tarzan vine vine)))

'(vine vine tarzan vine)

> (letrec ([tarzan-near-top-of-tree?
            (lambda (name path depth)
              (or (equal? name "tarzan")
                  (and (directory-exists? path)
                       (tarzan-in-directory? path depth))))]
           [tarzan-in-directory?
            (lambda (dir depth)
              (cond
                [(zero? depth) #f]
                [else
                 (ormap
                  (λ (elem)
                    (tarzan-near-top-of-tree? (path-element->string elem)
                                              (build-path dir elem)
                                              (- depth 1)))
                  (directory-list dir))]))])
    (tarzan-near-top-of-tree? "tmp"
                              (find-system-path 'temp-dir)
                              4))

directory-list: could not open directory

  path: /var/tmp/systemd-private-65a36c3a15e6498f91655743df9

2abf8-chronyd.service-7kLgAJ

  system error: Permission denied; errno=13

While the exprs of a letrec form are typically +lambda expressions, they can be any expression. The +expressions are evaluated in order, and after each value is obtained, +it is immediately associated with its corresponding id. If +an id is referenced before its value is ready, an +error is raised, just as for internal definitions.

> (letrec ([quicksand quicksand])
    quicksand)

quicksand: undefined;

 cannot use before initialization

4.6.4 Named let

A named let is an iteration and recursion form. It uses the +same syntactic keyword let as for local binding, but an +identifier after the let (instead of an immediate open +parenthesis) triggers a different parsing.

(let proc-id ([arg-id init-expr] ...)
  body ...+)

A named let form is equivalent to

(letrec ([proc-id (lambda (arg-id ...)
                     body ...+)])
  (proc-id init-expr ...))

That is, a named let binds a function identifier that is +visible only in the function’s body, and it implicitly calls the +function with the values of some initial expressions.

Examples:
(define (duplicate pos lst)
  (let dup ([i 0]
            [lst lst])
   (cond
     [(= i pos) (cons (car lst) lst)]
     [else (cons (car lst) (dup (+ i 1) (cdr lst)))])))
> (duplicate 1 (list "apple" "cheese burger!" "banana"))

'("apple" "cheese burger!" "cheese burger!" "banana")

4.6.5 Multiple Values: let-values, let*-values, letrec-values

+Local Binding: let, let*, letrec, ... in The Racket Reference also documents multiple-value binding forms.

In the same way that define-values binds multiple +results in a definition (see Multiple Values and define-values), +let-values, let*-values, and +letrec-values bind multiple results locally.

(let-values ([(id ...) expr] ...)
  body ...+)
(let*-values ([(id ...) expr] ...)
  body ...+)
(letrec-values ([(id ...) expr] ...)
  body ...+)

Each expr must produce as many values as corresponding +ids. The binding rules are the same for the forms +without -values forms: the ids of +let-values are bound only in the bodys, the +ids of let*-valuess are bound in +exprs of later clauses, and the ids of +letrec-values are bound for all exprs.

Example:
> (let-values ([(q r) (quotient/remainder 14 3)])
    (list q r))

'(4 2)

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/load.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/load.html new file mode 100644 index 00000000..f3ccc3c3 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/load.html @@ -0,0 +1,40 @@ + +15.3 Scripting Evaluation and Using load

15.3 Scripting Evaluation and Using load

Historically, Lisp implementations did not offer module +systems. Instead, large programs were built by essentially scripting +the REPL to evaluate program fragments in a particular order. +While REPL scripting turns out to be a bad way to structure +programs and libraries, it is still sometimes a useful capability.

Describing a program via load interacts +especially badly with macro-defined language extensions +[Flatt02].

The load function runs a REPL script by +reading S-expressions from a file, one by one, and passing +them to eval. If a file "place.rkts" contains

(define city "Salt Lake City")
(define state "Utah")
(printf "~a, ~a\n" city state)

then it can be loaded in a REPL:

> (load "place.rkts")

Salt Lake City, Utah

> city

"Salt Lake City"

Since load uses eval, however, a module like the +following generally will not work—for the same reasons described in +Namespaces:

#lang racket
 
(define there "Utopia")
 
(load "here.rkts")

The current namespace for evaluating the content of +"here.rkts" is likely to be empty; in any case, you cannot get +there from "here.rkts". Also, any definitions in +"here.rkts" will not become visible for use within the module; +after all, the load happens dynamically, while references to +identifiers within the module are resolved lexically, and therefore +statically.

Unlike eval, load does not accept a namespace +argument. To supply a namespace to load, set the +current-namespace parameter. The following example evaluates +the expressions in "here.rkts" using the bindings of the +racket/base module:

#lang racket
 
(parameterize ([current-namespace (make-base-namespace)])
  (load "here.rkts"))

You can even use namespace-anchor->namespace to make the +bindings of the enclosing module accessible for dynamic evaluation. In +the following example, when "here.rkts" is loaded, it +can refer to there as well as the bindings of +racket:

#lang racket
 
(define there "Utopia")
 
(define-namespace-anchor a)
(parameterize ([current-namespace (namespace-anchor->namespace a)])
  (load "here.rkts"))

Still, if "here.rkts" defines any identifiers, the definitions +cannot be directly (i.e., statically) referenced by in the enclosing +module.

The racket/load module language is different from +racket or racket/base. A module using +racket/load treats all of its content as dynamic, +passing each form in the module body to eval (using a +namespace that is initialized with racket). As a +result, uses of eval and load in the module body see +the same dynamic namespace as immediate body forms. For example, if +"here.rkts" contains

(define here "Morporkia")
(define (go!) (set! here there))

then running

#lang racket/load
 
(define there "Utopia")
 
(load "here.rkts")
 
(go!)
(printf "~a\n" here)

prints “Utopia”.

Drawbacks of using racket/load include reduced +error checking, tool support, and performance. For example, with the +program

#lang racket/load
 
(define good 5)
(printf "running\n")
good
bad

DrRacket’s Check Syntax tool cannot tell that the second +good is a reference to the first, and the unbound reference +to bad is reported only at run time instead of rejected +syntactically.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/macro-module.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/macro-module.html new file mode 100644 index 00000000..2317186e --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/macro-module.html @@ -0,0 +1,136 @@ + +16.3 Module Instantiations and Visits
8.6

16.3 Module Instantiations and Visits

Modules often contain just function and structure-type definitions, in +which case the module itself behaves in a purely functional way, and +the time when the functions are created is not observable. If a +module’s top-level expressions include side effects, however, then the +timing of the effects can matter. The distinction between module +declaration and instantiation provides some control over that +timing. The concept of module visits further explains the +interaction of effects with macro implementations.

16.3.1 Declaration versus Instantiation

Declaring a module does not immediately evaluate expressions in the +module’s body. For example, evaluating

> (module number-n racket/base
    (provide n)
    (define n (random 10))
    (printf "picked ~a\n" n))

declares the module number-n, but it doesn’t immediately pick a +random number for n or display the number. A require +of number-n causes the module to be instantiated +(i.e., it triggers an instantiation), which implies that the +expressions in the body of the module are evaluated:

> (require 'number-n)

picked 5

> n

5

After a module is instantiated in a particular namespace, +further requires of the module use the same instance, as +opposed to instantiating the module again:

> (require 'number-n)
> n

5

> (module use-n racket/base
    (require 'number-n)
    (printf "still ~a\n" n))
> (require 'use-n)

still 5

The dynamic-require function, like require, triggers +instantiation of a module if it is not already instantiated, so +dynamic-require with #f as a second argument is +useful to just trigger the instantiation effects of a module:

> (module use-n-again racket/base
    (require 'number-n)
    (printf "also still ~a\n" n))
> (dynamic-require ''use-n-again #f)

also still 5

Instantiation of modules by require is transitive. That is, +if require of a module instantiates it, then any module +required by that one is also instantiated (if it’s not +instantiated already):

> (module number-m racket/base
    (provide m)
    (define m (random 10))
    (printf "picked ~a\n" m))
> (module use-m racket/base
    (require 'number-m)
    (printf "still ~a\n" m))
> (require 'use-m)

picked 0

still 0

16.3.2 Compile-Time Instantiation

In the same way that declaring a module does not by itself instantiate +a module, declaring a module that requires another module +does not by itself instantiate the required module, as +illustrated in the preceding example. However, declaring a module +does expand and compile the module. If a module imports another +with (require (for-syntax ....)), then module that is +imported for-syntax must be instantiated during expansion:

> (module number-p racket/base
    (provide p)
    (define p (random 10))
    (printf "picked ~a\n" p))
> (module use-p-at-compile-time racket/base
    (require (for-syntax racket/base
                         'number-p))
    (define-syntax (pm stx)
      #`#,p)
    (printf "was ~a at compile time\n" (pm)))

picked 1

Unlike run-time instantiation in a namespace, when a module is used +for-syntax for another module expansion in the same +namespace, the for-syntaxed module is instantiated separately +for each expansion. Continuing the previous example, if +number-p is used a second time for-syntax, then a +second random number is selected for a new p:

> (module use-p-again-at-compile-time racket/base
    (require (for-syntax racket/base
                         'number-p))
    (define-syntax (pm stx)
      #`#,p)
    (printf "was ~a at second compile time\n" (pm)))

picked 3

Separate compile-time instantiations of number-p helps +prevent accidental propagation of effects from one module’s +compilation to another module’s compilation. Preventing those effects +make compilation reliably separate and more deterministic.

The expanded forms of use-p-at-compile-time and +use-p-again-at-compile-time record the number that was +selected each time, so those two different numbers are printed when the +modules are instantiated:

> (dynamic-require ''use-p-at-compile-time #f)

was 1 at compile time

> (dynamic-require ''use-p-again-at-compile-time #f)

was 3 at second compile time

A namespace’s top level behaves like a separate module, where multiple +interactions in the top level conceptually extend a single expansion +of the module. So, when using (require (for-syntax ....)) +twice in the top level, the second use does not trigger a new +compile-time instance:

> (begin (require (for-syntax 'number-p)) 'done)

picked 4

'done

> (begin (require (for-syntax 'number-p)) 'done-again)

'done-again

However, a run-time instance of a module is kept separate from all +compile-time instances, including at the top level, so a +non-for-syntax use of number-p will pick another +random number:

> (require 'number-p)

picked 5

16.3.3 Visiting Modules

When a module provides a macro for use by other modules, the +other modules use the macro by directly requireing the macro +provider—i.e., without for-syntax. That’s because the macro +is being imported for use in a run-time position (even though the +macro’s implementation lives at compile time), while +for-syntax would import a binding for use in compile-time +position.

The module implementing a macro, meanwhile, might require +another module for-syntax to implement the macro. The +for-syntax module needs a compile-time instantiation during +any module expansion that might use the macro. That requirement sets +up a kind of transitivity through require that is similar to +instantiation transitivity, but “off by one” at the point where the +for-syntax shift occurs in the chain.

Here’s an example to make that scenario concrete:

> (module number-q racket/base
    (provide q)
    (define q (random 10))
    (printf "picked ~a\n" q))
> (module use-q-at-compile-time racket/base
    (require (for-syntax racket/base
                         'number-q))
    (provide qm)
    (define-syntax (qm stx)
      #`#,q)
    (printf "was ~a at compile time\n" (qm)))

picked 7

> (module use-qm racket/base
    (require 'use-q-at-compile-time)
    (printf "was ~a at second compile time\n" (qm)))

picked 4

> (dynamic-require ''use-qm #f)

was 7 at compile time

was 4 at second compile time

In this example, when use-q-at-compile-time is expanded and +compiled, number-q is instantiated once. In this case, that +instantiation is needed to expand the (qm) macro, but the module +system would proactively create a compile-time instantiation of +number-q even if the qm macro turned out not to be +used.

Then, as use-qm is expanded and compiled, a second +compile-time instantiation of number-q is created. That +compile-time instantiation is needed to expand the (qm) form +within use-qm.

Instantiating use-qm correctly reports the number that was +picked during that second module’s compilation. First, though, the +require of use-q-at-compile-time in use-qm +triggers a transitive instantiation of use-q-at-compile-time, +which correctly reports the number that was picked in its compilation.

Overall, the example illustrates a transitive effect of +require that we had already seen:

This rule does not explain the compile-time instantiations of +number-q, however. To explain that, we need a new word, +visit, for the concept that we saw in +Compile-Time Instantiation:

Note that when visiting one module causes a compile-time instantiation of +another module, the transitiveness of instantiation through +regular requires can trigger more compile-time instantiations. +Instantiation itself won’t trigger further visits, however, because +any instantiated module has already been expanded and compiled.

The compile-time expressions of a module that are evaluated by +visiting include both the right-hand sides of +define-syntax forms and the body of begin-for-syntax +forms. That’s why a randomly selected number is printed immediately in +the following example:

> (module compile-time-number racket/base
    (require (for-syntax racket/base))
    (begin-for-syntax
      (printf "picked ~a\n" (random)))
    (printf "running\n"))

picked 0.25549265186825576

Instantiating the module evaluates only the run-time expressions, +which prints “running” but not a new random number:

> (dynamic-require ''compile-time-number #f)

running

The description of instantiates and visit above is +phrased in terms of normal requires and for-syntax +requires, but a more precise specification is in terms of +module phases. For example, if module A has (require (for-syntax B)) and module B has (require (for-template C)), then module C is instantiated +when module A is instantiated, because the +for-syntax and for-template shifts cancel. We have +not yet specified what happens with for-meta 2 for when +for-syntaxes combine; we leave that to the next section, +Lazy Visits via Available Modules.

If you think of the top-level as a kind of module that is continuously +expanded, the above rules imply that require of another +module at the top level both instantiates and visits the other module +(if it is not already instantiated and visited). That’s roughly true, +but the visit is made lazy in a way that is also explained in the next +section, Lazy Visits via Available Modules.

Meanwhile, dynamic-require only instantiates a module; it +does not visit the module. That simplification is why some of the +preceding examples use dynamic-require instead of +require. The extra visits of a top-level require +would make the earlier examples less clear.

16.3.4 Lazy Visits via Available Modules

A top-level require of a module does not actually +visit the module. Instead, it makes the module +available. An available module will be visited +when a future expression needs to be expanded in the same context. The +next expression may or may not involve some imported macro that needs +its compile-time helpers evaluated by visiting, but the module +system proactively visits the module, just in case.

In the following example, a random number is picked as a result of +visiting a module’s own body while that module is being expanded. A +require of the module instantiates it, printing “running”, +and also makes the module available. Evaluating any other +expression implies expanding the expression, and that expansion +triggers a visit of the available module—which picks +another random number:

> (module another-compile-time-number racket/base
    (require (for-syntax racket/base))
    (begin-for-syntax
      (printf "picked ~a\n" (random)))
    (printf "running\n"))

picked 0.3634379786893492

> (require 'another-compile-time-number)

running

> 'next

picked 0.5057086679589476

'next

> 'another

'another

Beware that the expander flattens the content of a +top-level begin into the top level as soon as the +begin is discovered. So, (begin (require 'another-compile-time-number) 'next) would still have printed +“picked” before “next“.

The final evaluation of 'another also visits any available +modules, but no modules were made newly available by simply evaluating +'next.

When a module requires another module using for-meta n for some n greater than 1, the required module +is made available at phase n. A module that is +available at phase n is visited when some +expression at phase n-1 is expanded.

To help illustrate, the following examples use +(variable-reference->module-base-phase (#%variable-reference)), which returns a number for the phase at +which the enclosing module is instantiated:

> (module show-phase racket/base
    (printf "running at ~a\n"
            (variable-reference->module-base-phase (#%variable-reference))))
> (require 'show-phase)

running at 0

> (module use-at-phase-1 racket/base
    (require (for-syntax 'show-phase)))

running at 1

> (module unused-at-phase-2 racket/base
    (require (for-meta 2 'show-phase)))

For the last module above, show-phase is made +available at phase 2, but no expressions within the module are +ever expanded at phase 1, so there’s no phase-2 printout. The +following module includes a phase-1 expression after the phase-2 +require, so there’s a printout:

> (module use-at-phase-2 racket/base
    (require (for-meta 2 'show-phase)
             (for-syntax racket/base))
    (define-syntax x 'ok))

running at 2

If we require the module use-at-phase-1 at the top +level, then show-phase is made available at phase 1. +Evaluating another expression causes use-at-phase-1 to be +visited, which in turn instantiates show-phase:

> (require 'use-at-phase-1)
> 'next

running at 1

'next

A require of use-at-phase-2 is similar, except that +show-phase is made available at phase 2, so it is not +instantiated until some expression is expanded at phase 1:

> (require 'use-at-phase-2)
> 'next

'next

> (require (for-syntax racket/base))
> (begin-for-syntax 'compile-time-next)

running at 2

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/macro-transformers.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/macro-transformers.html new file mode 100644 index 00000000..5ef46318 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/macro-transformers.html @@ -0,0 +1,21 @@ + +16.2.2 Macro Transformer Procedures
16.2.2 Macro Transformer Procedures

Any procedure of one argument can be a macro transformer. As +it turns out, the syntax-rules form is a macro that expands +to a procedure form. For example, if you evaluate a +syntax-rules form directly (instead of placing on the +right-hand of a define-syntax form), the result is a +procedure:

> (syntax-rules () [(nothing) something])

#<procedure>

Instead of using syntax-rules, you can write your own macro +transformer procedure directly using lambda. The argument to +the procedure is a syntax object that represents the source form, and the +result of the procedure must be a syntax object that represents the +replacement form:

> (define-syntax self-as-string
    (lambda (stx)
      (datum->syntax stx
                     (format "~s" (syntax->datum stx)))))
> (self-as-string (+ 1 2))

"(self-as-string (+ 1 2))"

The source form passed to a macro transformer represents an +expression in which its identifier is used in an application position +(i.e., after a parenthesis that starts an expression), or it +represents the identifier by itself if it is used as an expression +position and not in an application position.The procedure produced by +syntax-rules raises a syntax error if its argument +corresponds to a use of the identifier by itself, which is why +syntax-rules does not implement an identifier macro.

> (self-as-string (+ 1 2))

"(self-as-string (+ 1 2))"

> self-as-string

"self-as-string"

The define-syntax form supports the same shortcut +syntax for functions as define, so that the following self-as-string +definition is equivalent to the one that uses lambda +explicitly:

> (define-syntax (self-as-string stx)
    (datum->syntax stx
                   (format "~s" (syntax->datum stx))))
> (self-as-string (+ 1 2))

"(self-as-string (+ 1 2))"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/macros.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/macros.html new file mode 100644 index 00000000..7972ab85 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/macros.html @@ -0,0 +1,19 @@ + +16 Macros

16 Macros

A macro is a syntactic form with an associated +transformer that expands the original form +into existing forms. To put it another way, a macro is an +extension to the Racket compiler. Most of the syntactic forms of +racket/base and racket are +actually macros that expand into a small set of core constructs.

Like many languages, Racket provides pattern-based macros that +make simple transformations easy to implement and reliable to +use. Racket also supports arbitrary macro transformers that are +implemented in Racket—or in a macro-extended variant of Racket.

This chapter provides an introduction to Racket macros, but see +Fear of +Macros for an introduction from a different perspective.

Racket includes additional support for macro development: +A macro +debugger to make it easier for experienced programmers +to debug their macros and for novices to study their behavior, +and of macros. And the syntax/parse +library for writing macros and specifying syntax that +automatically validates macro uses and reports syntax +errors.

    16.1 Pattern-Based Macros

      16.1.1 define-syntax-rule

      16.1.2 Lexical Scope

      16.1.3 define-syntax and syntax-rules

      16.1.4 Matching Sequences

      16.1.5 Identifier Macros

      16.1.6 set! Transformers

      16.1.7 Macro-Generating Macros

      16.1.8 Extended Example: Call-by-Reference Functions

    16.2 General Macro Transformers

      16.2.1 Syntax Objects

      16.2.2 Macro Transformer Procedures

      16.2.3 Mixing Patterns and Expressions: syntax-case

      16.2.4 with-syntax and generate-temporaries

      16.2.5 Compile and Run-Time Phases

      16.2.6 General Phase Levels

        16.2.6.1 Phases and Bindings

        16.2.6.2 Phases and Modules

      16.2.7 Tainted Syntax

    16.3 Module Instantiations and Visits

      16.3.1 Declaration versus Instantiation

      16.3.2 Compile-Time Instantiation

      16.3.3 Visiting Modules

      16.3.4 Lazy Visits via Available Modules

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/magnify.png b/clones/download.racket-lang.org/releases/8.6/doc/guide/magnify.png new file mode 100644 index 0000000000000000000000000000000000000000..8556e407323719a5099dd6518622cfeb86a2bf4f GIT binary patch literal 323 zcmV-J0lfZ+P)*&n3&CLE8Ne1^0)+#CL^Wwri-Lq8NEXq%q-k0@ zJAi1yKN&H1&zy6UxwEW0jm&dx^iafpgj>AK3pX>&2e`ow-qFH7F0hTe49_plQKGZp zTL +12 Pattern Matching

12 Pattern Matching

The match form supports pattern matching on arbitrary Racket +values, as opposed to functions like regexp-match that +compare regular expressions to byte and character sequences (see +Regular Expressions).

(match target-expr
  [pattern expr ...+] ...)

The match form takes the result of target-expr and +tries to match each pattern in order. As soon as it finds a +match, it evaluates the corresponding expr sequence to +obtain the result for the match form. If pattern +includes pattern variables, they are treated like wildcards, +and each variable is bound in the expr to the input +fragments that it matched.

Most Racket literal expressions can be used as patterns:

> (match 2
    [1 'one]
    [2 'two]
    [3 'three])

'two

> (match #f
    [#t 'yes]
    [#f 'no])

'no

> (match "apple"
    ['apple 'symbol]
    ["apple" 'string]
    [#f 'boolean])

'string

Constructors like cons, list, and vector +can be used to create patterns that match pairs, lists, and vectors:

> (match '(1 2)
    [(list 0 1) 'one]
    [(list 1 2) 'two])

'two

> (match '(1 . 2)
    [(list 1 2) 'list]
    [(cons 1 2) 'pair])

'pair

> (match #(1 2)
    [(list 1 2) 'list]
    [(vector 1 2) 'vector])

'vector

A constructor bound with struct also can be used as a pattern +constructor:

> (struct shoe (size color))
> (struct hat (size style))
> (match (hat 23 'bowler)
   [(shoe 10 'white) "bottom"]
   [(hat 23 'bowler) "top"])

"top"

Unquoted, non-constructor identifiers in a pattern are pattern +variables that are bound in the result expressions, except _, +which does not bind (and thus is usually used as a catch-all):

> (match '(1)
    [(list x) (+ x 1)]
    [(list x y) (+ x y)])

2

> (match '(1 2)
    [(list x) (+ x 1)]
    [(list x y) (+ x y)])

3

> (match (hat 23 'bowler)
    [(shoe sz col) sz]
    [(hat sz stl) sz])

23

> (match (hat 11 'cowboy)
    [(shoe sz 'black) 'a-good-shoe]
    [(hat sz 'bowler) 'a-good-hat]
    [_ 'something-else])

'something-else

Note that the identifier else is not a reserved catch-all (like _). +If else appears in a pattern then its binding from +racket/base may be shadowed, and this can cause problems with +cond and case.

> (match 1
    [else
     (case 2
       [(a 1 b) 3]
       [else 4])])

eval:15:0: case: bad syntax (not a datum sequence)

  expected: a datum sequence or the binding 'else' from

racket/base

  given: a locally bound identifier

  at: else

  in: (case 2 ((a 1 b) 3) (else 4))

> (match #f
    [else
     (cond
       [#f 'not-evaluated]
       [else 'also-not-evaluated])])

To match against a value bound to an identifier, use ==.

> (define val 42)
> (match (list 42)
    [(list (== val)) 'matched])

'matched

> (match (list 43)
    [(list (== val)) 'not-matched]
    [_ 'this-branch-is-evaluated])

'this-branch-is-evaluated

> (match (list 43)
    [(list val)
     ; without ==, val is a pattern variable
     (format "match binds val to ~a" val)])

"match binds val to 43"

An ellipsis, written ..., acts like a Kleene star within a +list or vector pattern: the preceding sub-pattern can be used to match +any number of times for any number of consecutive elements of the list +or vector. If a sub-pattern followed by an ellipsis includes a pattern +variable, the variable matches multiple times, and it is bound in the +result expression to a list of matches:

> (match '(1 1 1)
    [(list 1 ...) 'ones]
    [_ 'other])

'ones

> (match '(1 1 2)
    [(list 1 ...) 'ones]
    [_ 'other])

'other

> (match '(1 2 3 4)
    [(list 1 x ... 4) x])

'(2 3)

> (match (list (hat 23 'bowler) (hat 22 'pork-pie))
    [(list (hat sz styl) ...) (apply + sz)])

45

Ellipses can be nested to match nested repetitions, and in that case, +pattern variables can be bound to lists of lists of matches:

> (match '((! 1) (! 2 2) (! 3 3 3))
    [(list (list '! x ...) ...) x])

'((1) (2 2) (3 3 3))

The quasiquote form (see Quasiquoting: quasiquote and for more about it) can also be used to build patterns. +While unquoted portions of a normal quasiquoted form mean regular racket evaluation, here unquoted +portions mean go back to regular pattern matching.

So, in the example below, the with expression is the pattern and it gets rewritten into the +application expression, using quasiquote as a pattern in the first instance and quasiquote +to build an expression in the second.

> (match `{with {x 1} {+ x 1}}
    [`{with {,id ,rhs} ,body}
     `{{lambda {,id} ,body} ,rhs}])

'((lambda (x) (+ x 1)) 1)

For information on many more pattern forms, see racket/match.

Forms like match-let and match-lambda support +patterns in positions that otherwise must be identifiers. For example, +match-let generalizes let to a destructing +bind:

> (match-let ([(list x y z) '(1 2 3)])
    (list z y x))

'(3 2 1)

For information on these additional forms, see racket/match.

+Pattern Matching in The Racket Reference provides more on pattern matching.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/mk-namespace.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/mk-namespace.html new file mode 100644 index 00000000..e068f81b --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/mk-namespace.html @@ -0,0 +1,77 @@ + +15.2 Manipulating Namespaces

15.2 Manipulating Namespaces

A namespace encapsulates two pieces of information:

  • A mapping from identifiers to bindings. For example, a +namespace might map the identifier lambda to the +lambda form. An “empty” namespace is one that maps +every identifier to an uninitialized top-level variable.

  • A mapping from module names to module declarations and +instances. (The distinction between declaration and instance is +discussed in Module Instantiations and Visits.)

The first mapping is used for evaluating expressions in a top-level +context, as in (eval '(lambda (x) (+ x 1))). The second +mapping is used, for example, by dynamic-require to locate a +module. The call (eval '(require racket/base)) normally uses +both pieces: the identifier mapping determines the binding of +require; if it turns out to mean require, then +the module mapping is used to locate the racket/base +module.

From the perspective of the core Racket run-time system, all +evaluation is reflective. Execution starts with an initial namespace +that contains a few primitive modules, and that is further populated +by loading files and modules as specified on the command line or as +supplied in the REPL. Top-level require and +define forms adjusts the identifier mapping, and module +declarations (typically loaded on demand for a require form) +adjust the module mapping.

15.2.1 Creating and Installing Namespaces

The function make-empty-namespace creates a new, empty +namespace. Since the namespace is truly empty, it cannot at +first be used to evaluate any top-level expression—not even +(require racket). In particular,

(parameterize ([current-namespace (make-empty-namespace)])
  (namespace-require 'racket))

fails, because the namespace does not include the primitive modules on +which racket is built.

To make a namespace useful, some modules must be attached +from an existing namespace. Attaching a module adjusts the mapping of +module names to instances by transitively copying entries (the module +and all its imports) from an existing namespace’s mapping. Normally, +instead of just attaching the primitive modules—whose names and +organization are subject to change—a higher-level module is +attached, such as racket or +racket/base.

The make-base-empty-namespace function provides a namespace +that is empty, except that racket/base is +attached. The resulting namespace is still “empty” in the sense that +the identifiers-to-bindings part of the namespace has no mappings; +only the module mapping has been populated. Nevertheless, with an +initial module mapping, further modules can be loaded.

A namespace created with make-base-empty-namespace is +suitable for many basic dynamic tasks. For example, suppose that a +my-dsl library implements a domain-specific language +in which you want to execute commands from a user-specified file. A +namespace created with make-base-empty-namespace is enough to +get started:

(define (run-dsl file)
  (parameterize ([current-namespace (make-base-empty-namespace)])
    (namespace-require 'my-dsl)
    (load file)))

Note that the parameterize of current-namespace does +not affect the meaning of identifiers like namespace-require +within the parameterize body. Those identifiers obtain their +meaning from the enclosing context (probably a module). Only +expressions that are dynamic with respect to this code, such as the +content of loaded files, are affected by the +parameterize.

Another subtle point in the above example is the use of +(namespace-require 'my-dsl) instead of (eval '(require my-dsl)). The latter would not work, because eval +needs to obtain a meaning for require in the namespace, and +the namespace’s identifier mapping is initially empty. The +namespace-require function, in contrast, directly imports the +given module into the current namespace. Starting with +(namespace-require 'racket/base) would introduce a binding +for require and make a subsequent (eval '(require my-dsl)) work. The above is better, not only because it is +more compact, but also because it avoids introducing bindings that are +not part of the domain-specific languages.

15.2.2 Sharing Data and Code Across Namespaces

Modules not attached to a new namespace will be loaded and +instantiated afresh if they are demanded by evaluation. For example, +racket/base does not include +racket/class, and loading racket/class +again will create a distinct class datatype:

> (require racket/class)
> (class? object%)

#t

> (class?
   (parameterize ([current-namespace (make-base-empty-namespace)])
     (namespace-require 'racket/class) ; loads again
     (eval 'object%)))

#f

For cases when dynamically loaded code needs to share more code and +data with its context, use the namespace-attach-module +function. The first argument to namespace-attach-module is a +source namespace from which to draw a module instance; in some cases, +the current namespace is known to include the module that needs to be +shared:

> (require racket/class)
> (class?
   (let ([ns (make-base-empty-namespace)])
     (namespace-attach-module (current-namespace)
                              'racket/class
                              ns)
     (parameterize ([current-namespace ns])
       (namespace-require 'racket/class) ; uses attached
       (eval 'object%))))

#t

Within a module, however, the combination of +define-namespace-anchor and +namespace-anchor->empty-namespace offers a more reliable +method for obtaining a source namespace:

#lang racket/base
 
(require racket/class)
 
(define-namespace-anchor a)
 
(define (load-plug-in file)
  (let ([ns (make-base-empty-namespace)])
    (namespace-attach-module (namespace-anchor->empty-namespace a)
                             'racket/class
                              ns)
    (parameterize ([current-namespace ns])
      (dynamic-require file 'plug-in%))))

The anchor bound by namespace-attach-module connects the +run time of a module with the namespace in which a module is loaded +(which might differ from the current namespace). In the above +example, since the enclosing module requires +racket/class, the namespace produced by +namespace-anchor->empty-namespace certainly contains an +instance of racket/class. Moreover, that instance is +the same as the one imported into the module, so the class datatype is +shared.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-basics.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-basics.html new file mode 100644 index 00000000..9f3bde4f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-basics.html @@ -0,0 +1,186 @@ + +6.1 Module Basics

6.1 Module Basics

Each Racket module typically resides in its own file. For example, +suppose the file "cake.rkt" contains the following module:

"cake.rkt"

#lang racket
 
(provide print-cake)
 
; draws a cake with n candles
(define (print-cake n)
  (show "   ~a   " n #\.)
  (show " .-~a-. " n #\|)
  (show " | ~a | " n #\space)
  (show "---~a---" n #\-))
 
(define (show fmt n ch)
  (printf fmt (make-string n ch))
  (newline))

Then, other modules can import "cake.rkt" to use the +print-cake function, since the provide line in +"cake.rkt" explicitly exports the definition +print-cake. The show function is private to +"cake.rkt" (i.e., it cannot be used from other modules), +since show is not exported.

The following "random-cake.rkt" module imports +"cake.rkt":

"random-cake.rkt"

#lang racket
 
(require "cake.rkt")
 
(print-cake (random 30))

The relative reference "cake.rkt" in the import +(require "cake.rkt") works if the "cake.rkt" and +"random-cake.rkt" modules are in the same +directory. Unix-style relative paths are used for relative module +references on all platforms, much like relative URLs in HTML pages.

6.1.1 Organizing Modules

The "cake.rkt" and "random-cake.rkt" example +demonstrates the most common way to organize a program into modules: +put all module files in a single directory (perhaps with +subdirectories), and then have the modules reference each other +through relative paths. A directory of modules can act as a +project, since it can be moved around on the filesystem or copied to +other machines, and relative paths preserve the connections among +modules.

As another example, if you are building a candy-sorting program, you +might have a main "sort.rkt" module that uses other modules +to access a candy database and a control sorting machine. If the +candy-database module itself is organized into sub-modules that handle +barcode and manufacturer information, then the database module could +be "db/lookup.rkt" that uses helper modules +"db/barcodes.rkt" and "db/makers.rkt". Similarly, +the sorting-machine driver "machine/control.rkt" might use +helper modules "machine/sensors.rkt" and +"machine/actuators.rkt".

image

The "sort.rkt" module uses the relative paths +"db/lookup.rkt" and "machine/control.rkt" to import +from the database and machine-control libraries:

"sort.rkt"

#lang racket
(require "db/lookup.rkt" "machine/control.rkt")
....

The "db/lookup.rkt" module similarly uses paths relative to +its own source to access the "db/barcodes.rkt" and +"db/makers.rkt" modules:

"db/lookup.rkt"

#lang racket
(require "barcode.rkt" "makers.rkt")
....

Ditto for "machine/control.rkt":

"machine/control.rkt"

#lang racket
(require "sensors.rkt" "actuators.rkt")
....

Racket tools all work automatically with relative paths. For example,

  racket sort.rkt

on the command line runs the "sort.rkt" program and +automatically loads and compiles required modules. With a large enough +program, compilation from source can take too long, so use

  raco make sort.rkt

See raco make: Compiling Source to Bytecode for more information on raco make.

to compile "sort.rkt" and all its dependencies to bytecode +files. Running racket sort.rkt will automatically use bytecode +files when they are present.

6.1.2 Library Collections

A collection is a hierarchical grouping of installed library modules. A +module in a collection is referenced through an unquoted, +suffixless path. For example, the following module refers to the +"date.rkt" library that is part of the "racket" +collection:

#lang racket
 
(require racket/date)
 
(printf "Today is ~s\n"
        (date->string (seconds->date (current-seconds))))

When you search the online Racket documentation, the search results +indicate the module that provides each binding. Alternatively, if you +reach a binding’s documentation by clicking on hyperlinks, you can +hover over the binding name to find out which modules provide +it.

A module reference like racket/date looks like an +identifier, but it is not treated in the same way as printf +or date->string. Instead, when require sees a module +reference that is unquoted, it converts the reference to a +collection-based module path:

  • First, if the unquoted path contains no /, then +require automatically adds a "/main" to the +reference. For example, (require slideshow) is equivalent to (require slideshow/main).

  • Second, require implicitly adds a ".rkt" +suffix to the path.

  • Finally, require resolves the path by searching among +installed collections, instead of treating the path as relative to +the enclosing module’s path.

To a first approximation, a collection is implemented as a +filesystem directory. For example, the "racket" collection is +mostly located in a "racket" directory within the Racket +installation’s "collects" directory, as reported by

#lang racket
 
(require setup/dirs)
 
(build-path (find-collects-dir) ; main collection directory
            "racket")

The Racket installation’s "collects" directory, however, is +only one place that require looks for collection directories. +Other places include the user-specific directory reported by +(find-user-collects-dir) and directories configured through +the PLTCOLLECTS search path. Finally, and most typically, +collections are found through installed packages.

6.1.3 Packages and Collections

A package is a set of libraries that are installed through +the Racket package manager (or included as pre-installed in a Racket +distribution). For example, the racket/gui library is +provided by the "gui" package, while +parser-tools/lex is provided by the +"parser-tools" library.

More precisely, +racket/gui is provided by "gui-lib", +parser-tools/lex is provided by +"parser-tools-lib", and the "gui" and +"parser-tools" packages extend "gui-lib" and +"parser-tools-lib" with documentation.

Racket programs do not refer to packages directly. Instead, +programs refer to libraries via collections, and adding or +removing a package changes the set of collection-based +libraries that are available. A single package can supply +libraries in multiple collections, and two different packages can +supply libraries in the same collection (but not the same libraries, +and the package manager ensures that installed packages do not +conflict at that level).

For more information about packages, see Package Management in Racket.

6.1.4 Adding Collections

Looking back at the candy-sorting example of Organizing Modules, +suppose that modules in "db/" and "machine/" need a +common set of helper functions. Helper functions could be put in a +"utils/" directory, and modules in "db/" or +"machine/" could access utility modules with relative paths +that start "../utils/". As long as a set of modules work +together in a single project, it’s best to stick with relative paths. +A programmer can follow relative-path references without knowing about +your Racket configuration.

Some libraries are meant to be used across multiple projects, so that +keeping the library source in a directory with its uses does not make +sense. In that case, the best option is add a new +collection. After the library is in a collection, it can be +referenced with an unquoted path, just like libraries that are +included with the Racket distribution.

You could add a new collection by placing files in the Racket +installation or one of the directories reported by +(get-collects-search-dirs). Alternatively, you could add to +the list of searched directories by setting the PLTCOLLECTS +environment variable.If you set PLTCOLLECTS, +include an empty path in by starting the value with a colon (Unix and +Mac OS) or semicolon (Windows) so that the original search paths are +preserved. The best option, however, is to add a package.

Creating a package does not mean that you have to register with +a package server or perform a bundling step that copies your source +code into an archive format. Creating a package can simply mean using +the package manager to make your libraries locally accessible as a +collection from their current source locations.

For example, suppose you have a directory "/usr/molly/bakery" +that contains the "cake.rkt" module (from the +beginning of this section) and other +related modules. To make the modules available as a "bakery" +collection, either

  • Use the raco pkg command-line tool:

      raco pkg install --link /usr/molly/bakery

    where the --link flag is not actually needed when the +provided path includes a directory separator.

  • Use DrRacket’s Package Manager item from the +File menu. In the Do What I Mean panel, +click Browse..., choose the +"/usr/molly/bakery" directory, and click +Install.

Afterward, (require bakery/cake) from any module will import +the print-cake function from +"/usr/molly/bakery/cake.rkt".

By default, the name of the directory that you install is used both as +the package name and as the collection that is provided +by the package. Also, the package manager normally defaults to +installation only for the current user, as opposed to all users of a +Racket installation. See Package Management in Racket for more information.

If you intend to distribute your libraries to others, choose +collection and package names carefully. The collection namespace is +hierarchical, but top-level collection names are global, and the +package namespace is flat. Consider putting one-off libraries under +some top-level name like "molly" that identifies the +producer. Use a collection name like "bakery" when producing +the definitive collection of baked-goods libraries.

After your libraries are put in a collection you can still +use raco make to compile the library sources, but it’s better +and more convenient to use raco setup. The raco setup +command takes a collection name (as opposed to a file name) and +compiles all libraries within the collection. In addition, raco setup can +build documentation for the collection and add it to the documentation +index, as specified by a "info.rkt" module in the collection. +See raco setup: Installation Management for +more information on raco setup.

6.1.5 Module References Within a Collection

When a module within a collection references another module within the +same collection, either a relative path or a collection path could +work. For example, a "sort.rkt" module that references +"db/lookup.rkt" and "machine/control.rkt" modules within +the same collection could be written with relative paths as in +Organizing Modules:

"sort.rkt"

#lang racket
(require "db/lookup.rkt" "machine/control.rkt")
....

Alternatively, if the collection is named "candy", then +"sort.rkt" could use collection paths to import the two +modules:

"sort.rkt"

#lang racket
(require candy/db/lookup candy/machine/control)
....

For most purposes, these choices will work the same, but there are +exceptions. When writing documentation with Scribble, you must use +a collection path with defmodule and similar forms; that’s +partly because documentation is meant to be read by client +programmers, and so the collection-based name should appear. +Meanwhile, for require, using relative paths for references +within a collection tends to be the most flexible approach, but with +caveats.

Relative-path references work much like relative URL references: the +reference is expanded based on the way the enclosing module is +accessed. If the enclosing module is accessed through a filesystem +path, then a relative path in require is combined with that +filesystem path to form a new filesystem path. If the enclosing module +is accessed through a collection path, then a relative path in +require is combined with that collection path to form a new +collection path. A collection path is, in turn, converted to a +filesystem path, and so the difference between starting with a +filesystem or collection path does not usually matter. Unfortunately, +inherent complexities of path resolution can create differences in +some situations:

  • Through soft links, multiple mount points, or case-insensitive +filesystems (on an operating system that does not implicitly +case-normalize paths), there may be multiple filesystem paths +that refer to the same module file.

    For example, when the current directory is the "candy" +collection’s directory, the current-directory path that +racket receives on startup may cause racket +sort.rkt to use a different filesystem path than racket +-l candy/sort finds through the library-collection search +path. In that case, if "sort.rkt" leads to some +modules through both relative-path references and +collection-based references, it’s possible that those resolve +to difference instances of the same source module, creating +confusion through multiple instantiations.

  • When raco exec plus +raco distribute are +used to create an executable to run on a different machine, the +paths of the current machine are likely unrelated to paths on +the target machine. The raco exe tool treats modules +that are referenced via filesystem paths differently than +modules reference via collection paths, because only the latter +make sense to access through reflective operations at run +time.

    For example, if raco exe sort.rkt creates an executable +that uses (dynamic-require 'candy/db/lookup #f) at run +time, then that dynamic-require will fail in the case +that "db/lookup.rkt" is resolved relative to the +filesystem path "sort.rkt" at executable-creation time.

Using only collection-based paths (including using shell commands like +racket -l candy/sort and not like racket sort.rkt) can +avoid all problems, but then you must only develop modules within an +installed collection, which is often inconvenient. Using relative-path +references consistently tends to be the most convenient while still +working in most circumstances.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-languages.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-languages.html new file mode 100644 index 00000000..80240af6 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-languages.html @@ -0,0 +1,49 @@ + +17.1 Module Languages

17.1 Module Languages

When using the longhand module form for writing modules, the +module path that is specified after the new module’s name provides the +initial imports for the module. Since the initial-import module +determines even the most basic bindings that are available in a +module’s body, such as require, the initial import can be +called a module language.

The most common module languages are racket or +racket/base, but you can define your own +module language by defining a suitable module. For example, +using provide subforms like all-from-out, +except-out, and rename-out, you can add, remove, or +rename bindings from racket to produce a module +language that is a variant of racket:

+The module Form introduces the longhand +module form.

> (module raquet racket
    (provide (except-out (all-from-out racket) lambda)
             (rename-out [lambda function])))
> (module score 'raquet
    (map (function (points) (case points
                             [(0) "love"] [(1) "fifteen"]
                             [(2) "thirty"] [(3) "forty"]))
         (list 0 2)))
> (require 'score)

'("love" "thirty")

17.1.1 Implicit Form Bindings

If you try to remove too much from racket in defining +your own module language, then the resulting module +will no longer work right as a module language:

> (module just-lambda racket
    (provide lambda))
> (module identity 'just-lambda
    (lambda (x) x))

eval:2:0: module: no #%module-begin binding in the module's

language

  in: (module identity (quote just-lambda) (lambda (x) x))

The #%module-begin form is an implicit form that wraps the +body of a module. It must be provided by a module that is to be used +as module language:

> (module just-lambda racket
    (provide lambda #%module-begin))
> (module identity 'just-lambda
    (lambda (x) x))
> (require 'identity)

#<procedure>

The other implicit forms provided by racket/base are +#%app for function calls, #%datum for literals, and +#%top for identifiers that have no binding:

> (module just-lambda racket
    (provide lambda #%module-begin
             ; ten needs these, too:
             #%app #%datum))
> (module ten 'just-lambda
    ((lambda (x) x) 10))
> (require 'ten)

10

Implicit forms such as #%app can be used explicitly in a module, +but they exist mainly to allow a module language to restrict or change +the meaning of implicit uses. For example, a lambda-calculus +module language might restrict functions to a single argument, +restrict function calls to supply a single argument, restrict the +module body to a single expression, disallow literals, and treat +unbound identifiers as uninterpreted symbols:

> (module lambda-calculus racket
    (provide (rename-out [1-arg-lambda lambda]
                         [1-arg-app #%app]
                         [1-form-module-begin #%module-begin]
                         [no-literals #%datum]
                         [unbound-as-quoted #%top]))
    (define-syntax-rule (1-arg-lambda (x) expr)
      (lambda (x) expr))
    (define-syntax-rule (1-arg-app e1 e2)
      (#%app e1 e2))
    (define-syntax-rule (1-form-module-begin e)
      (#%module-begin e))
    (define-syntax (no-literals stx)
      (raise-syntax-error #f "no" stx))
    (define-syntax-rule (unbound-as-quoted . id)
      'id))
> (module ok 'lambda-calculus
    ((lambda (x) (x z))
     (lambda (y) y)))
> (require 'ok)

'z

> (module not-ok 'lambda-calculus
    (lambda (x y) x))

eval:4:0: lambda: use does not match pattern: (lambda (x)

expr)

  in: (lambda (x y) x)

> (module not-ok 'lambda-calculus
    (lambda (x) x)
    (lambda (y) (y y)))

eval:5:0: #%module-begin: use does not match pattern:

(#%module-begin e)

  in: (#%module-begin (lambda (x) x) (lambda (y) (y y)))

> (module not-ok 'lambda-calculus
    (lambda (x) (x x x)))

eval:6:0: #%app: use does not match pattern: (#%app e1 e2)

  in: (#%app x x x)

> (module not-ok 'lambda-calculus
    10)

eval:7:0: #%datum: no

  in: (#%datum . 10)

Module languages rarely redefine #%app, #%datum, and +#%top, but redefining #%module-begin is more +frequently useful. For example, when using modules to construct +descriptions of HTML pages where a description is exported from the +module as page, an alternate #%module-begin +can help eliminate provide and quasiquoting +boilerplate, as in "html.rkt":

"html.rkt"

#lang racket
(require racket/date)
 
(provide (except-out (all-from-out racket)
                     #%module-begin)
         (rename-out [module-begin #%module-begin])
         now)
 
(define-syntax-rule (module-begin expr ...)
  (#%module-begin
   (define page `(html expr ...))
   (provide page)))
 
(define (now)
  (parameterize ([date-display-format 'iso-8601])
    (date->string (seconds->date (current-seconds)))))

Using the "html.rkt" module language, a simple web page +can be described without having to explicitly define or export +page and starting in quasiquoted mode instead +of expression mode:

> (module lady-with-the-spinning-head "html.rkt"
    (title "Queen of Diamonds")
    (p "Updated: " ,(now)))
> (require 'lady-with-the-spinning-head)
> page

'(html (title "Queen of Diamonds") (p "Updated: " "2022-08-04"))

17.1.2 Using #lang s-exp

Implementing a language at the level of #lang is more complex +than declaring a single module, because #lang lets programmers +control several different facets of a language. The +s-exp language, however, acts as a kind of +meta-language for using a module language with the +#lang shorthand:

#lang s-exp module-name
form ...

is the same as

(module name module-name
  form ...)

where name is derived from the source file containing the +#lang program. The name s-exp is short for +“S-expression,” which is a traditional name for +Racket’s reader-level lexical conventions: parentheses, +identifiers, numbers, double-quoted strings with certain backslash +escapes, and so on.

Using #lang s-exp, the +lady-with-the-spinning-head example from before can be +written more compactly as:

#lang s-exp "html.rkt"
 
(title "Queen of Diamonds")
(p "Updated: " ,(now))

Later in this guide, Defining new #lang Languages explains how to define +your own #lang language, but first we explain how you can write +reader-level extensions to Racket.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-macro.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-macro.html new file mode 100644 index 00000000..c6318c61 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-macro.html @@ -0,0 +1,23 @@ + +6.7 Modules and Macros

6.7 Modules and Macros

Racket’s module system cooperates closely with Racket’s macro +system for adding new syntactic forms to Racket. For example, in the +same way that importing racket/base introduces syntax +for require and lambda, importing other modules can +introduce new syntactic forms (in addition to more traditional kinds +of imports, such as functions or constants).

We introduce macros in more detail later, in Macros, but +here’s a simple example of a module that defines a pattern-based +macro:

(module noisy racket
  (provide define-noisy)
 
  (define-syntax-rule (define-noisy (id arg ...) body)
    (define (id arg ...)
      (show-arguments 'id  (list arg ...))
      body))
 
  (define (show-arguments name args)
    (printf "calling ~s with arguments ~e" name args)))

The define-noisy binding provided by this module is a +macro that acts like define for a function, but it +causes each call to the function to print the arguments that are +provided to the function:

> (require 'noisy)
> (define-noisy (f x y)
    (+ x y))
> (f 1 2)

calling f with arguments '(1 2)

3

Roughly, the define-noisy form works by replacing

(define-noisy (f x y)
  (+ x y))

with

(define (f x y)
  (show-arguments 'f (list x y))
  (+ x y))

Since show-arguments isn’t provided by the noisy +module, however, this literal textual replacement is not quite right. +The actual replacement correctly tracks the origin of identifiers like +show-arguments, so they can refer to other definitions in the +place where the macro is defined—even if those identifiers are not +available at the place where the macro is used.

There’s more to the macro and module interaction than identifier +binding. The define-syntax-rule form is itself a macro, and +it expands to compile-time code that implements the transformation +from define-noisy into define. The module system +keeps track of which code needs to run at compile and which needs to +run normally, as explained more in Compile and Run-Time Phases and +Module Instantiations and Visits.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-paths.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-paths.html new file mode 100644 index 00000000..9e64405b --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-paths.html @@ -0,0 +1,83 @@ + +6.3 Module Paths

6.3 Module Paths

A module path is a reference to a module, as used with +require or as the initial-module-path in a +module form. It can be any of several forms:

(quote id)

A module path that is a quoted identifier refers to a non-file +module declaration using the identifier. This form of module +reference makes the most sense in a REPL.

Examples:
> (module m racket
    (provide color)
    (define color "blue"))
> (module n racket
    (require 'm)
    (printf "my favorite color is ~a\n" color))
> (require 'n)

my favorite color is blue

rel-string

A string module path is a relative path using Unix-style +conventions: / is the path separator, .. refers to +the parent directory, and . refers to the same +directory. The rel-string must not start or end with a path +separator.

The path is relative to the enclosing file, if any, or it is relative +to the current directory. (More precisely, the path is relative to the +value of (current-load-relative-directory), which is set +while loading a file.)

Module Basics shows examples using relative paths.

If a relative path ends with a ".ss" suffix, it is converted +to ".rkt". If the file that implements the referenced module +actually ends in ".ss", the suffix will be changed back when +attempting to load the file (but a ".rkt" suffix takes +precedence). This two-way conversion provides compatibility with older +versions of Racket.

id

A module path that is an unquoted identifier refers to an +installed library. The id is constrained to contain only +ASCII letters, ASCII numbers, +, -, _, +and /, where / separates path elements within the +identifier. The elements refer to collections and +sub-collections, instead of directories and sub-directories.

An example of this form is racket/date. It refers to the +module whose source is the "date.rkt" file in the +"racket" collection, which is installed as part of +Racket. The ".rkt" suffix is added automatically.

Another example of this form is racket, which is commonly +used at the initial import. The path racket is shorthand for +racket/main; when an id has no /, then +/main is automatically added to the end. Thus, +racket or racket/main refers to the module whose +source is the "main.rkt" file in the "racket" +collection.

Examples:
> (module m racket
    (require racket/date)
  
    (printf "Today is ~s\n"
            (date->string (seconds->date (current-seconds)))))
> (require 'm)

Today is "Thursday, August 4th, 2022"

When the full path of a module ends with ".rkt", if no such +file exists but one does exist with the ".ss" suffix, then +the ".ss" suffix is substituted automatically. This +transformation provides compatibility with older versions of Racket.

(lib rel-string)

Like an unquoted-identifier path, but expressed as a string instead of +an identifier. Also, the rel-string can end with a file +suffix, in which case ".rkt" is not automatically added.

Example of this form include (lib "racket/date.rkt") and +(lib "racket/date"), which are equivalent to +racket/date. Other examples include (lib "racket"), +(lib "racket/main"), and (lib "racket/main.rkt"), +which are all equivalent to racket.

Examples:
> (module m (lib "racket")
    (require (lib "racket/date.rkt"))
  
    (printf "Today is ~s\n"
            (date->string (seconds->date (current-seconds)))))
> (require 'm)

Today is "Thursday, August 4th, 2022"

(planet id)

Accesses a third-party library that is distributed through the +PLaneT server. The library is downloaded the first time that it is +needed, and then the local copy is used afterward.

The id encodes several pieces of information separated by a +/: the package owner, then package name with optional +version information, and an optional path to a specific library with +the package. Like id as shorthand for a lib path, a +".rkt" suffix is added automatically, and /main +is used as the path if no sub-path element is supplied.

Examples:
> (module m (lib "racket")
    ; Use "schematics"'s "random.plt" 1.0, file "random.rkt":
    (require (planet schematics/random:1/random))
    (display (random-gaussian)))
> (require 'm)

0.9050686838895684

As with other forms, an implementation file ending with ".ss" +can be substituted automatically if no implementation file ending with +".rkt" exists.

(planet package-string)

Like the symbol form of a planet, but using a string instead +of an identifier. Also, the package-string can end with a +file suffix, in which case ".rkt" is not added.

As with other forms, an ".ss" extension is converted to +".rkt", while an implementation file ending with +".ss" can be substituted automatically if no implementation +file ending with ".rkt" exists.

(planet rel-string (user-string pkg-string vers ...))
 
vers = nat
  | (nat nat)
  | (= nat)
  | (+ nat)
  | (- nat)

A more general form to access a library from the PLaneT server. In +this general form, a PLaneT reference starts like a lib +reference with a relative path, but the path is followed by +information about the producer, package, and version of the +library. The specified package is downloaded and installed on demand.

The verses specify a constraint on the acceptable version of +the package, where a version number is a sequence of non-negative +integers, and the constraints determine the allowable values for each +element in the sequence. If no constraint is provided for a particular +element, then any version is allowed; in particular, omitting all +verses means that any version is acceptable. Specifying at +least one vers is strongly recommended.

For a version constraint, a plain nat is the same as +(+ nat), which matches nat or higher for the +corresponding element of the version number. A (start-nat end-nat) matches any number in the range start-nat to +end-nat, inclusive. A (= nat) matches only exactly +nat. A (- nat) matches nat or lower.

Examples:
> (module m (lib "racket")
    (require (planet "random.rkt" ("schematics" "random.plt" 1 0)))
    (display (random-gaussian)))
> (require 'm)

0.9050686838895684

The automatic ".ss" and ".rkt" conversions apply as +with other forms.

(file string)

Refers to a file, where string is a relative or absolute path +using the current platform’s conventions. This form is not portable, +and it should not be used when a plain, portable +rel-string suffices.

The automatic ".ss" and ".rkt" conversions apply as +with other forms.

(submod base element ...+)
 
base = module-path
  | "."
  | ".."
     
element = id
  | ".."

Refers to a submodule of base. The sequence of +elements within submod specify a path of submodule +names to reach the final submodule.

Examples:
> (module zoo racket
    (module monkey-house racket
      (provide monkey)
      (define monkey "Curious George")))
> (require (submod 'zoo monkey-house))
> monkey

"Curious George"

Using "." as base within submod stands for +the enclosing module. Using ".." as base is +equivalent to using "." followed by an extra +"..". When a path of the form (quote id) +refers to a submodule, it is equivalent to (submod "." id).

Using ".." as an element cancels one submodule step, effectively +referring to the enclosing module. For example, (submod "..") +refers to the enclosing module of the submodule in which the path +appears.

Examples:
> (module zoo racket
    (module monkey-house racket
      (provide monkey)
      (define monkey "Curious George"))
    (module crocodile-house racket
      (require (submod ".." monkey-house))
      (provide dinner)
      (define dinner monkey)))
> (require (submod 'zoo crocodile-house))
> dinner

"Curious George"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-provide.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-provide.html new file mode 100644 index 00000000..9b4650cb --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-provide.html @@ -0,0 +1,31 @@ + +6.5 Exports: provide

6.5 Exports: provide

By default, all of a module’s definitions are private to the +module. The provide form specifies definitions to be made +available where the module is required.

(provide provide-spec ...)

A provide form can only appear at module level (i.e., in the +immediate body of a module). Specifying multiple +provide-specs in a single provide is exactly the +same as using multiple provides each with a single +provide-spec.

Each identifier can be exported at most once from a module across all +provides within the module. More precisely, the external name +for each export must be distinct; the same internal binding can be +exported multiple times with different external names.

The allowed shape of a provide-spec is defined recursively:

identifier

In its simplest form, a provide-spec indicates a binding +within its module to be exported. The binding can be from either a +local definition, or from an import.

(rename-out [orig-id export-id] ...)

A rename-out form is similar to just specifying an identifier, +but the exported binding orig-id is given a different name, +export-id, to importing modules.

(struct-out struct-id)

A struct-out form exports the bindings created by +(struct struct-id ....).

+See Programmer-Defined Datatypes for information on +define-struct.

(all-defined-out)

The all-defined-out shorthand exports all bindings that are +defined within the exporting module (as opposed to imported).

Use of the all-defined-out shorthand is generally +discouraged, because it makes less clear the actual exports for a +module, and because Racket programmers get into the habit of +thinking that definitions can be added freely to a module without +affecting its public interface (which is not the case when +all-defined-out is used).

(all-from-out module-path)

The all-from-out shorthand exports all bindings in the module +that were imported using a require-spec that is based on +module-path.

Although different module-paths could refer to the same +file-based module, re-exporting with all-from-out is based +specifically on the module-path reference, and not the module +that is actually referenced.

(except-out provide-spec id ...)

Like provide-spec, but omitting the export of each +id, where id is the external name of the binding to +omit.

(prefix-out prefix-id provide-spec)

Like provide-spec, but adding prefix-id to the +beginning of the external name for each exported binding.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-require.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-require.html new file mode 100644 index 00000000..33bb74cc --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-require.html @@ -0,0 +1,32 @@ + +6.4 Imports: require

6.4 Imports: require

The require form imports from another module. A +require form can appear within a module, in which case it +introduces bindings from the specified module into the importing module. +A require form can also appear at the top level, in which case +it both imports bindings and instantiates the specified +module; that is, it evaluates the body definitions and expressions of +the specified module, if they have not been evaluated already.

A single require can specify multiple imports at once:

(require require-spec ...)

Specifying multiple require-specs in a single +require is essentially the same as using multiple +requires, each with a single require-spec. The +difference is minor, and confined to the top-level: a single +require can import a given identifier at most once, whereas a +separate require can replace the bindings of a previous +require (both only at the top level, outside of a module).

The allowed shape of a require-spec is defined recursively:

module-path

In its simplest form, a require-spec is a +module-path (as defined in the previous section, +Module Paths). In this case, the bindings introduced +by require are determined by provide declarations +within each module referenced by each module-path.

Examples:
> (module m racket
    (provide color)
    (define color "blue"))
> (module n racket
    (provide size)
    (define size 17))
> (require 'm 'n)
> (list color size)

'("blue" 17)

(only-in require-spec id-maybe-renamed ...)
 
id-maybe-renamed = id
  | [orig-id bind-id]

An only-in form limits the set of bindings that would be introduced +by a base require-spec. Also, only-in optionally +renames each binding that is preserved: in a [orig-id bind-id] form, the orig-id refers to a binding implied by +require-spec, and bind-id is the name that will be +bound in the importing context instead of orig-id.

Examples:
> (module m (lib "racket")
    (provide tastes-great?
             less-filling?)
    (define tastes-great? #t)
    (define less-filling? #t))
> (require (only-in 'm tastes-great?))
> tastes-great?

#t

> less-filling?

less-filling?: undefined;

 cannot reference an identifier before its definition

  in module: top-level

> (require (only-in 'm [less-filling? lite?]))
> lite?

#t

(except-in require-spec id ...)

This form is the complement of only-in: it excludes specific +bindings from the set specified by require-spec.

(rename-in require-spec [orig-id bind-id] ...)

This form supports renaming like only-in, but leaving alone +identifiers from require-spec that are not mentioned as an +orig-id.

(prefix-in prefix-id require-spec)

This is a shorthand for renaming, where prefix-id is added to +the front of each identifier specified by require-spec.

The only-in, except-in, rename-in, and +prefix-in forms can be nested to implement more complex +manipulations of imported bindings. For example,

(require (prefix-in m: (except-in 'm ghost)))

imports all bindings that m +exports, except for the ghost binding, and with local names +that are prefixed with m:.

Equivalently, the prefix-in could be applied before +except-in, as long as the omission with except-in is +specified using the m: prefix:

(require (except-in (prefix-in m: 'm) m:ghost))

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-runtime-config.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-runtime-config.html new file mode 100644 index 00000000..d605a8d3 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-runtime-config.html @@ -0,0 +1,63 @@ + +17.3.6 Module-Handling Configuration
17.3.6 Module-Handling Configuration

Suppose that the file "death-list-5.rkt" contains

"death-list-5.rkt"

#lang racket
(list "O-Ren Ishii"
      "Vernita Green"
      "Budd"
      "Elle Driver"
      "Bill")

If you require "death-list-5.rkt" directly, then it +prints the list in the usual Racket result format:

> (require "death-list-5.rkt")

'("O-Ren Ishii" "Vernita Green" "Budd" "Elle Driver" "Bill")

However, if "death-list-5.rkt" is required by a +"kiddo.rkt" that is implemented with scheme +instead of racket:

"kiddo.rkt"

#lang scheme
(require "death-list-5.rkt")

then, if you run "kiddo.rkt" file in DrRacket or if you run it +directly with racket, "kiddo.rkt" causes +"death-list-5.rkt" to print its list in traditional Scheme +format, without the leading quote:

("O-Ren Ishii" "Vernita Green" "Budd" "Elle Driver" "Bill")

The "kiddo.rkt" example illustrates how the format for +printing a result value can depend on the main module of a program +instead of the language that is used to implement it.

More broadly, certain features of a language are only invoked when +a module written in that language is run directly with racket +(as opposed to being imported into another module). One example is +result-printing style (as shown above). Another example is REPL +behavior. These features are part of what’s called the +run-time configuration of a language.

Unlike the syntax-coloring property of a language (as described in +Source-Handling Configuration), the run-time configuration is a +property of a module per se as opposed to a property of +the source text representing the module. +For that reason, the run-time configuration for a +module needs to be available even if the module is compiled +to bytecode form and the source is unavailable. Therefore, +run-time configuration cannot be handled by the +get-info function we’re exporting from the language’s +parser module.

Instead, it will be handled by a new +configure-runtime submodule that we’ll add inside +the parsed module form. When a module is run directly +with racket, racket looks for a +configure-runtime submodule. If it exists, racket +runs it. But if the module is imported into another module, +the 'configure-runtime submodule is ignored. (And if the +configure-runtime submodule doesn’t exist, racket +just evaluates the module as usual.) That means that the +configure-runtime submodule can be used for any special +setup tasks that need to happen when the module is run directly.

Going back to the literal language (see +Source-Handling Configuration), we can adjust the language so that +directly running a literal module causes it to print out its +string, while using a literal module in a larger program +simply provides data without printing. To make this +work, we will need an extra module. (For clarity here, we will implement +this module as a separate file. But it could equally well be +a submodule of an existing file.)

.... (the main installation or the user’s space)
|- "literal"
   |- "main.rkt"            (with reader submodule)
   |- "show.rkt"            (new)
  • The "literal/show.rkt" module will provide a +show function to be applied to the string +content of a literal module, and also provide a +show-enabled parameter that controls whether +show actually prints the result.

  • The new configure-runtime submodule in +"literal/main.rkt" will set the +show-enabled parameter to #t. The +net effect is that show will print the strings +that it’s given, but only when a module using the literal +language is run directly (because only then will the +configure-runtime submodule be invoked).

These changes are implemented in the following revised +"literal/main.rkt":

"literal/main.rkt"

#lang racket
 
(module reader racket
  (require syntax/strip-context)
 
  (provide (rename-out [literal-read read]
                       [literal-read-syntax read-syntax])
           get-info)
 
  (define (literal-read in)
    (syntax->datum
     (literal-read-syntax #f in)))
 
  (define (literal-read-syntax src in)
    (with-syntax ([str (port->string in)])
      (strip-context
       #'(module anything racket
           (module configure-runtime racket
             (require literal/show)
             (show-enabled #t))
           (require literal/show)
           (provide data)
           (define data 'str)
           (show data)))))
 
  (define (get-info in mod line col pos)
    (lambda (key default)
      (case key
        [(color-lexer)
         (dynamic-require 'syntax-color/default-lexer
                          'default-lexer)]
        [else default]))))

Then the "literal/show.rkt" module must provide +the show-enabled parameter and show +function:

"literal/show.rkt"

#lang racket
 
(provide show show-enabled)
 
(define show-enabled (make-parameter #f))
 
(define (show v)
  (when (show-enabled)
    (display v)))

With all of the pieces for literal in place, try running the +following variant of "tuvalu.rkt" directly and through a +require from another module:

"tuvalu.rkt"

#lang literal
Technology!
System!
Perfect!

When run directly, we’ll see the result printed like so, because +our configure-runtime submodule will have set the +show-enabled parameter to #t:

Technology! +
System! +
Perfect!

But when imported into another module, printing will be suppressed, +because the configure-runtime submodule will not be invoked, +and therefore the show-enabled parameter will remain +at its default value of #f.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/module-set.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-set.html new file mode 100644 index 00000000..86a9e23f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/module-set.html @@ -0,0 +1,25 @@ + +6.6 Assignment and Redefinition

6.6 Assignment and Redefinition

The use of set! on variables defined within a module is +limited to the body of the defining module. That is, a module is +allowed to change the value of its own definitions, and such changes +are visible to importing modules. However, an importing context is not +allowed to change the value of an imported binding.

Examples:
> (module m racket
    (provide counter increment!)
    (define counter 0)
    (define (increment!)
      (set! counter (add1 counter))))
> (require 'm)
> counter

0

> (increment!)
> counter

1

> (set! counter -1)

set!: cannot mutate module-required identifier

  at: counter

  in: (set! counter -1)

As the above example illustrates, a module can always grant others the +ability to change its exports by providing a mutator function, such as +increment!.

The prohibition on assignment of imported variables helps support +modular reasoning about programs. For example, in the module,

(module m racket
  (provide rx:fish fishy-string?)
  (define rx:fish #rx"fish")
  (define (fishy-string? s)
    (regexp-match? rx:fish s)))

the function fishy-string? will always match strings that +contain “fish”, no matter how other modules use the rx:fish +binding. For essentially the same reason that it helps programmers, +the prohibition on assignment to imports also allows many programs to +be executed more efficiently.

Along the same lines, when a module contains no set! of a +particular identifier that is defined within the module, then the +identifier is considered a constant that cannot be +changed—not even by re-declaring the module.

Consequently, re-declaration of a module is not generally allowed. +For file-based modules, simply changing the file does not lead to a +re-declaration in any case, because file-based modules are loaded on +demand, and the previously loaded declarations satisfy future +requests. It is possible to use Racket’s reflection support to +re-declare a module, however, and non-file modules can be re-declared +in the REPL; in such cases, the re-declaration may fail if it +involves the re-definition of a previously constant binding.

> (module m racket
    (define pie 3.141597))
> (require 'm)
> (module m racket
    (define pie 3))

define-values: assignment disallowed;

 cannot re-define a constant

  constant: pie

  in module:'m

For exploration and debugging purposes, the Racket reflective layer +provides a compile-enforce-module-constants parameter +to disable the enforcement of constants.

> (compile-enforce-module-constants #f)
> (module m2 racket
    (provide pie)
    (define pie 3.141597))
> (require 'm2)
> (module m2 racket
    (provide pie)
    (define pie 3))
> (compile-enforce-module-constants #t)
> pie

3

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/modules.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/modules.html new file mode 100644 index 00000000..8847fd81 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/modules.html @@ -0,0 +1,3 @@ + +6 Modules
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/more-hash-lang.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/more-hash-lang.html new file mode 100644 index 00000000..83eaee73 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/more-hash-lang.html @@ -0,0 +1,30 @@ + +23.1 More Rackets

23.1 More Rackets

“Racket” is more of an idea about programming languages than a +language in the usual sense. Macros can extend a base language (as +described in Macros), and alternate parsers can +construct an entirely new language from the ground up (as described in +Creating Languages).

The #lang line that starts a Racket module declares the +base language of the module. By “Racket,” we usually mean +#lang followed by the base language racket or +racket/base (of which racket is an +extension). The Racket distribution provides additional languages, +including the following:

Each of these languages is used by starting module with the language +name after #lang. For example, this source of this +document starts with #lang scribble/base.

Furthermore, Racket users can define their own languages, as discussed +in Creating Languages. Typically, a language name maps to its +implementation through a module path by adding +/lang/reader; for example, the language name +scribble/base is expanded to +scribble/base/lang/reader, which is the module that +implements the surface-syntax parser. Some language names act as +language loaders; for example, #lang planet planet-path downloads, installs, and uses a +language via PLaneT.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/numbers.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/numbers.html new file mode 100644 index 00000000..13b2db6f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/numbers.html @@ -0,0 +1,49 @@ + +3.2 Numbers

3.2 Numbers

A Racket number is either exact or inexact:

  • An exact number is either

    • an arbitrarily large or small integer, such as 5, +99999999999999999, or -17;

    • a rational that is exactly the ratio of two arbitrarily +small or large integers, such as 1/2, +99999999999999999/2, or -3/4; or

    • a complex number with exact real and imaginary parts +(where the imaginary part is not zero), such as 1+2i or +1/2+3/4i.

  • An inexact number is either

    • an IEEE floating-point representation of a number, such +as 2.0 or 3.14e+87, where the IEEE +infinities and not-a-number are written ++inf.0, -inf.0, and +nan.0 +(or -nan.0); or

    • a complex number with real and imaginary parts that are +IEEE floating-point representations, such as +2.0+3.0i or -inf.0+nan.0i; as a +special case, an inexact complex number can have an +exact zero real part with an inexact imaginary part.

Inexact numbers print with a decimal point or exponent specifier, and +exact numbers print as integers and fractions. The same conventions +apply for reading number constants, but #e or +#i can prefix a number to force its parsing as an exact +or inexact number. The prefixes #b, #o, and +#x specify binary, octal, and hexadecimal +interpretation of digits.

+Reading Numbers in The Racket Reference documents the fine points of the syntax of numbers.

Examples:
> 0.5

0.5

> #e0.5

1/2

> #x03BB

955

Computations that involve an inexact number produce inexact results, +so that inexactness acts as a kind of taint on numbers. Beware, +however, that Racket offers no “inexact booleans,” so computations +that branch on the comparison of inexact numbers can nevertheless +produce exact results. The procedures exact->inexact and +inexact->exact convert between the two +types of numbers.

Examples:
> (/ 1 2)

1/2

> (/ 1 2.0)

0.5

> (if (= 3.0 2.999) 1 2)

2

> (inexact->exact 0.1)

3602879701896397/36028797018963968

Inexact results are also produced by procedures such as sqrt, +log, and sin when an exact result would require +representing real numbers that are not rational. Racket can represent +only rational numbers and complex numbers with rational parts.

Examples:
> (sin 0)   ; rational...

0

> (sin 1/2) ; not rational...

0.479425538604203

In terms of performance, computations with small integers are +typically the fastest, where “small” means that the number fits into +one bit less than the machine’s word-sized representation for signed +numbers. Computation with very large exact integers or with +non-integer exact numbers can be much more expensive than computation +with inexact numbers.

(define (sigma f a b)
  (if (= a b)
      0
      (+ (f a) (sigma f (+ a 1) b))))

 

> (time (round (sigma (lambda (x) (/ 1 x)) 1 2000)))

cpu time: 21 real time: 11 gc time: 0

8

> (time (round (sigma (lambda (x) (/ 1.0 x)) 1 2000)))

cpu time: 0 real time: 0 gc time: 0

8.0

The number categories integer, rational, +real (always rational), and complex are defined in +the usual way, and are recognized by the procedures integer?, +rational?, real?, and complex?, in addition +to the generic number?. A few mathematical procedures accept +only real numbers, but most implement standard extensions to complex +numbers.

Examples:
> (integer? 5)

#t

> (complex? 5)

#t

> (integer? 5.0)

#t

> (integer? 1+2i)

#f

> (complex? 1+2i)

#t

> (complex? 1.0+2.0i)

#t

> (abs -5)

5

> (abs -5+2i)

abs: contract violation

  expected: real?

  given: -5+2i

> (sin -5+2i)

3.6076607742131563+1.0288031496599335i

The = procedure compares numbers for numerical equality. If +it is given both inexact and exact numbers to compare, it essentially +converts the inexact numbers to exact before comparing. The +eqv? (and therefore equal?) procedure, in contrast, +compares numbers considering both exactness and numerical equality.

Examples:
> (= 1 1.0)

#t

> (eqv? 1 1.0)

#f

Beware of comparisons involving inexact numbers, which by their nature +can have surprising behavior. Even apparently simple inexact numbers +may not mean what you think they mean; for example, while a base-2 +IEEE floating-point number can represent 1/2 exactly, it +can only approximate 1/10:

Examples:
> (= 1/2 0.5)

#t

> (= 1/10 0.1)

#f

> (inexact->exact 0.1)

3602879701896397/36028797018963968

+Numbers in The Racket Reference provides more on numbers and number procedures.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/other-editors.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/other-editors.html new file mode 100644 index 00000000..96ee6f57 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/other-editors.html @@ -0,0 +1,6 @@ + +24 Command-Line Tools and Your Editor of Choice
8.6

24 Command-Line Tools and Your Editor of Choice

Although DrRacket is the easiest way for most people to start with +Racket, many Racketeers prefer command-line tools and other text +editors. The Racket distribution includes several command-line tools, +and popular editors include or support packages to make them work well +with Racket.

    24.1 Command-Line Tools

      24.1.1 Compilation and Configuration: raco

      24.1.2 Interactive evaluation

      24.1.3 Shell completion

    24.2 Emacs

      24.2.1 Major Modes

      24.2.2 Minor Modes

      24.2.3 Packages specific to Evil Mode

    24.3 Vim

      24.3.1 Plugins

      24.3.2 Indentation

      24.3.3 Highlighting

      24.3.4 Structured Editing

      24.3.5 REPLs

      24.3.6 Scribble

      24.3.7 Miscellaneous

    24.4 Sublime Text

    24.5 Visual Studio Code

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/pairs.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/pairs.html new file mode 100644 index 00000000..fd7235a9 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/pairs.html @@ -0,0 +1,28 @@ + +3.8 Pairs and Lists

3.8 Pairs and Lists

A pair joins two arbitrary values. The cons +procedure constructs pairs, and the car and cdr +procedures extract the first and second elements of the pair, +respectively. The pair? predicate recognizes pairs.

Some pairs print by wrapping parentheses around the printed forms of +the two pair elements, putting a ' at the beginning and a +. between the elements.

Examples:
> (cons 1 2)

'(1 . 2)

> (cons (cons 1 2) 3)

'((1 . 2) . 3)

> (car (cons 1 2))

1

> (cdr (cons 1 2))

2

> (pair? (cons 1 2))

#t

A list is a combination of pairs that creates a linked +list. More precisely, a list is either the empty list null, +or it is a pair whose first element is a list element and whose second +element is a list. The list? predicate recognizes lists. The +null? predicate recognizes the empty list.

A list normally prints as a ' followed by a pair of parentheses +wrapped around the list elements.

Examples:
> null

'()

> (cons 0 (cons 1 (cons 2 null)))

'(0 1 2)

> (list? null)

#t

> (list? (cons 1 (cons 2 null)))

#t

> (list? (cons 1 2))

#f

A list or pair prints using list or cons +when one of its elements cannot be written as a quoted +value. For example, a value constructed with srcloc cannot be +written using quote, and it prints using srcloc:

> (srcloc "file.rkt" 1 0 1 (+ 4 4))

(srcloc "file.rkt" 1 0 1 8)

> (list 'here (srcloc "file.rkt" 1 0 1 8) 'there)

(list 'here (srcloc "file.rkt" 1 0 1 8) 'there)

> (cons 1 (srcloc "file.rkt" 1 0 1 8))

(cons 1 (srcloc "file.rkt" 1 0 1 8))

> (cons 1 (cons 2 (srcloc "file.rkt" 1 0 1 8)))

(list* 1 2 (srcloc "file.rkt" 1 0 1 8))

See also list*.

As shown in the last example, list* is used to +abbreviate a series of conses that cannot be +abbreviated using list.

The write and display functions print a pair or list +without a leading ', cons, +list, or list*. There is no difference +between write and display for a pair or list, except +as they apply to elements of the list:

Examples:
> (write (cons 1 2))

(1 . 2)

> (display (cons 1 2))

(1 . 2)

> (write null)

()

> (display null)

()

> (write (list 1 2 "3"))

(1 2 "3")

> (display (list 1 2 "3"))

(1 2 3)

Among the most important predefined procedures on lists are those that +iterate through the list’s elements:

> (map (lambda (i) (/ 1 i))
       '(1 2 3))

'(1 1/2 1/3)

> (andmap (lambda (i) (i . < . 3))
         '(1 2 3))

#f

> (ormap (lambda (i) (i . < . 3))
         '(1 2 3))

#t

> (filter (lambda (i) (i . < . 3))
          '(1 2 3))

'(1 2)

> (foldl (lambda (v i) (+ v i))
         10
         '(1 2 3))

16

> (for-each (lambda (i) (display i))
            '(1 2 3))

123

> (member "Keys"
          '("Florida" "Keys" "U.S.A."))

'("Keys" "U.S.A.")

> (assoc 'where
         '((when "3:30") (where "Florida") (who "Mickey")))

'(where "Florida")

+Pairs and Lists in The Racket Reference provides more on pairs and lists.

Pairs are immutable (contrary to Lisp tradition), and pair? +and list? recognize immutable pairs and lists, only. The +mcons procedure creates a mutable pair, which works +with set-mcar! and set-mcdr!, as well as +mcar and mcdr. A mutable pair prints using +mcons, while write and display print +mutable pairs with { and }:

Examples:
> (define p (mcons 1 2))
> p

(mcons 1 2)

> (pair? p)

#f

> (mpair? p)

#t

> (set-mcar! p 0)
> p

(mcons 0 2)

> (write p)

{0 . 2}

+Mutable Pairs and Lists in The Racket Reference provides more on mutable pairs.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/parallelism.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/parallelism.html new file mode 100644 index 00000000..e3397f59 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/parallelism.html @@ -0,0 +1,162 @@ + +20 Parallelism

20 Parallelism

Racket provides two forms of parallelism: futures and +places. On a platform that provides multiple processors, +parallelism can improve the run-time performance of a program.

See also Performance for information on sequential +performance in Racket. Racket also provides threads for +concurrency, but threads do not provide parallelism; see +Concurrency and Synchronization for more information.

20.1 Parallelism with Futures

The racket/future library provides support for +performance improvement through parallelism with futures and the future +and touch functions. The level of parallelism available from +those constructs, however, is limited by several factors, and the +current implementation is best suited to numerical tasks. The caveats +in Performance in DrRacket also apply to futures; notably, +the debugging instrumentation currently defeats futures.

Other functions, such as thread, support the +creation of reliably concurrent tasks. However, threads never run truly +in parallel, even if the hardware and operating system support +parallelism.

As a starting example, the any-double? function below takes a +list of numbers and determines whether any number in the list has a +double that is also in the list:

(define (any-double? l)
  (for/or ([i (in-list l)])
    (for/or ([i2 (in-list l)])
      (= i2 (* 2 i)))))

This function runs in quadratic time, so it can take a long time (on +the order of a second) on large lists like l1 and +l2:

(define l1 (for/list ([i (in-range 5000)])
             (+ (* 2 i) 1)))
(define l2 (for/list ([i (in-range 5000)])
             (- (* 2 i) 1)))
(or (any-double? l1)
    (any-double? l2))

The best way to speed up any-double? is to use a different +algorithm. However, on a machine that offers at least two processing +units, the example above can run in about half the time using +future and touch:

(let ([f (future (lambda () (any-double? l2)))])
  (or (any-double? l1)
      (touch f)))

The future f runs (any-double? l2) in parallel to +(any-double? l1), and the result for (any-double? l2) becomes available about the same time that it is demanded by +(touch f).

Futures run in parallel as long as they can do so safely, but the +notion of “future safe” is inherently tied to the +implementation. The distinction between “future safe” and “future unsafe” +operations may be far from apparent at the level of a Racket program. +The remainder of this section works through an example to illustrate +this distinction and to show how to use the future visualizer +can help shed light on it.

Consider the following core of a Mandelbrot-set computation:

(define (mandelbrot iterations x y n)
  (let ([ci (- (/ (* 2.0 y) n) 1.0)]
        [cr (- (/ (* 2.0 x) n) 1.5)])
    (let loop ([i 0] [zr 0.0] [zi 0.0])
      (if (> i iterations)
          i
          (let ([zrq (* zr zr)]
                [ziq (* zi zi)])
            (cond
              [(> (+ zrq ziq) 4) i]
              [else (loop (add1 i)
                          (+ (- zrq ziq) cr)
                          (+ (* 2 zr zi) ci))]))))))

The expressions (mandelbrot 10000000 62 500 1000) and +(mandelbrot 10000000 62 501 1000) each take a while to +produce an answer. Computing them both, of course, takes twice as +long:

(list (mandelbrot 10000000 62 500 1000)
      (mandelbrot 10000000 62 501 1000))

Unfortunately, attempting to run the two computations in parallel with +future does not improve performance:

(let ([f (future (lambda () (mandelbrot 10000000 62 501 1000)))])
  (list (mandelbrot 10000000 62 500 1000)
        (touch f)))

To see why, use the future-visualizer, like this:

(require future-visualizer)
(visualize-futures
 (let ([f (future (lambda () (mandelbrot 10000000 62 501 1000)))])
   (list (mandelbrot 10000000 62 500 1000)
         (touch f))))

This opens a window showing a graphical view of a trace of the computation. +The upper-left portion of the window contains an execution timeline:

image

Each horizontal row represents an OS-level thread, and the colored +dots represent important events in the execution of the program (they are +color-coded to distinguish one event type from another). The upper-left blue +dot in the timeline represents the future’s creation. The future +executes for a brief period (represented by a green bar in the second line) on thread +1, and then pauses to allow the runtime thread to perform a future-unsafe operation.

In the Racket implementation, future-unsafe operations fall into one of two categories. +A blocking operation halts the evaluation of the future, and will not allow +it to continue until it is touched. After the operation completes within touch, +the remainder of the future’s work will be evaluated sequentially by the runtime +thread. A synchronized operation also halts the future, but the runtime thread +may perform the operation at any time and, once completed, the future may continue +running in parallel. Memory allocation and JIT compilation are two common examples +of synchronized operations.

In the timeline, we see an orange dot just to the right of the green bar on thread 1 – +this dot represents a synchronized operation (memory allocation). The first orange +dot on thread 0 shows that the runtime thread performed the allocation shortly after +the future paused. A short time later, the future halts on a blocking operation +(the first red dot) and must wait until the touch for it to be evaluated +(slightly after the 1049ms mark).

When you move your mouse over an event, the visualizer shows you +detailed information about the event and draws arrows +connecting all of the events in the corresponding future. +This image shows those connections for our future.

image

The dotted orange line connects the first event in the future to +the future that created it, and the purple lines connect adjacent +events within the future.

The reason that we see no parallelism is that the < and * operations +in the lower portion of the loop in mandelbrot involve a mixture of +floating-point and fixed (integer) values. Such mixtures typically trigger a slow +path in execution, and the general slow path will usually be blocking.

Changing constants to be floating-points numbers in mandelbrot addresses that +first problem:

(define (mandelbrot iterations x y n)
  (let ([ci (- (/ (* 2.0 y) n) 1.0)]
        [cr (- (/ (* 2.0 x) n) 1.5)])
    (let loop ([i 0] [zr 0.0] [zi 0.0])
      (if (> i iterations)
          i
          (let ([zrq (* zr zr)]
                [ziq (* zi zi)])
            (cond
              [(> (+ zrq ziq) 4.0) i]
              [else (loop (add1 i)
                          (+ (- zrq ziq) cr)
                          (+ (* 2.0 zr zi) ci))]))))))

With that change, mandelbrot computations can run in +parallel. Nevertheless, we still see a special type of +slow-path operation limiting our parallelism (orange dots):

image

The problem is that most every arithmetic operation in this example +produces an inexact number whose storage must be allocated. While some allocation +can safely be performed exclusively without the aid of the runtime thread, especially +frequent allocation requires synchronized operations which defeat any performance +improvement.

By using flonum-specific operations (see +Fixnum and Flonum Optimizations), we can re-write mandelbrot to use +much less allocation:

(define (mandelbrot iterations x y n)
  (let ([ci (fl- (fl/ (* 2.0 (->fl y)) (->fl n)) 1.0)]
        [cr (fl- (fl/ (* 2.0 (->fl x)) (->fl n)) 1.5)])
    (let loop ([i 0] [zr 0.0] [zi 0.0])
      (if (> i iterations)
          i
          (let ([zrq (fl* zr zr)]
                [ziq (fl* zi zi)])
            (cond
              [(fl> (fl+ zrq ziq) 4.0) i]
              [else (loop (add1 i)
                          (fl+ (fl- zrq ziq) cr)
                          (fl+ (fl* 2.0 (fl* zr zi)) ci))]))))))

This conversion can speed mandelbrot by a factor of 8, even +in sequential mode, but avoiding allocation also allows +mandelbrot to run usefully faster in parallel. +Executing this program yields the following in the visualizer:

image

Notice that only one green bar is shown here because one of the +mandelbrot computations is not being evaluated by a future (on +the runtime thread).

As a general guideline, any operation that is inlined by the +JIT compiler runs safely in parallel, while other operations +that are not inlined (including all operations if the JIT compiler is +disabled) are considered unsafe. The raco decompile tool +annotates operations that can be inlined by the compiler (see +raco decompile: Decompiling Bytecode), so the +decompiler can be used to help predict parallel performance.

20.2 Parallelism with Places

The racket/place library provides support for +performance improvement through parallelism with the place +form. The place form creates a place, which is +effectively a new Racket instance that can run in parallel to other +places, including the initial place. The full power of the Racket +language is available at each place, but places can communicate only +through message passing—using the place-channel-put and +place-channel-get functions on a limited set of +values—which helps ensure the safety and independence of parallel +computations.

As a starting example, the racket program below uses a place to +determine whether any number in the list has a double that is also in +the list:

#lang racket
 
(provide main)
 
(define (any-double? l)
  (for/or ([i (in-list l)])
    (for/or ([i2 (in-list l)])
      (= i2 (* 2 i)))))
 
(define (main)
  (define p
    (place ch
      (define l (place-channel-get ch))
      (define l-double? (any-double? l))
      (place-channel-put ch l-double?)))
 
  (place-channel-put p (list 1 2 4 8))
 
  (place-channel-get p))

The identifier ch after place is bound to a place +channel. The remaining body expressions within the place form +are evaluated in a new place, and the body expressions use ch +to communicate with the place that spawned the new place.

In the body of the place form above, the new place receives a +list of numbers over ch and binds the list to l. It +then calls any-double? on the list and binds the result to +l-double?. The final body expression sends the +l-double? result back to the original place over ch.

In DrRacket, after saving and running the above program, evaluate +(main) in the interactions window to create the new +place. When using places inside DrRacket, the +module containing place code must be saved to a file before it will +execute. Alternatively, save the program as "double.rkt" +and run from a command line with

  racket -tm double.rkt

where the -t flag tells racket to load the +double.rkt module, the -m flag calls the exported +main function, and -tm combines the two flags.

The place form has two subtle features. First, it lifts the +place body to an anonymous, module-level function. This +lifting means that any binding referenced by the place body +must be available in the module’s top level. Second, the +place form dynamic-requires the enclosing module in +a newly created place. As part of the dynamic-require, the +current module body is evaluated in the new place. The consequence of +this second feature is that place should not appear immediately +in a module or in a function that is called in a module’s top level; +otherwise, invoking the module will invoke the same module in a new +place, and so on, triggering a cascade of place creations that will +soon exhaust memory.

#lang racket
 
(provide main)
 
; Don't do this!
(define p (place ch (place-channel-get ch)))
 
(define (indirect-place-invocation)
  (define p2 (place ch (place-channel-get ch))))
 
; Don't do this, either!
(indirect-place-invocation)

20.3 Distributed Places

The racket/place/distributed library provides support for +distributed programming.

The example below demonstrates how to launch a remote racket node instance, +launch remote places on the new remote node instance, and start an +event loop that monitors the remote node instance.

The example code can also be found in +"racket/distributed/examples/named/master.rkt".

#lang racket/base
(require racket/place/distributed
         racket/class
         racket/place
         racket/runtime-path
         "bank.rkt"
         "tuple.rkt")
(define-runtime-path bank-path "bank.rkt")
(define-runtime-path tuple-path "tuple.rkt")
 
(provide main)
 
(define (main)
  (define remote-node (spawn-remote-racket-node 
                        "localhost" 
                        #:listen-port 6344))
  (define tuple-place (supervise-place-at 
                        remote-node 
                        #:named 'tuple-server 
                        tuple-path 
                        'make-tuple-server))
  (define bank-place  (supervise-place-at 
                        remote-node bank-path 
                        'make-bank))
 
  (message-router
    remote-node
    (after-seconds 4
      (displayln (bank-new-account bank-place 'user0))
      (displayln (bank-add bank-place 'user0 10))
      (displayln (bank-removeM bank-place 'user0 5)))
 
    (after-seconds 2
      (define c (connect-to-named-place remote-node 
                                        'tuple-server))
      (define d (connect-to-named-place remote-node 
                                        'tuple-server))
      (tuple-server-hello c)
      (tuple-server-hello d)
      (displayln (tuple-server-set c "user0" 100))
      (displayln (tuple-server-set d "user2" 200))
      (displayln (tuple-server-get c "user0"))
      (displayln (tuple-server-get d "user2"))
      (displayln (tuple-server-get d "user0"))
      (displayln (tuple-server-get c "user2"))
      )
    (after-seconds 8
      (node-send-exit remote-node))
    (after-seconds 10
      (exit 0))))
 

Figure 1: examples/named/master.rkt

The spawn-remote-racket-node primitive connects to +"localhost" and starts a racloud node there that listens on port +6344 for further instructions. The handle to the new racloud node is +assigned to the remote-node variable. Localhost is used so that +the example can be run using only a single machine. However localhost +can be replaced by any host with ssh publickey access and racket. The +supervise-place-at creates a new place on the +remote-node. The new place will be identified in the future by +its name symbol 'tuple-server. A place descriptor is +expected to be returned by invoking dynamic-place with the +tuple-path module path and the 'make-tuple-server +symbol.

The code for the tuple-server place exists in the file +"tuple.rkt". The "tuple.rkt" file contains the use of +define-named-remote-server form, which defines a RPC server +suitable for invocation by supervise-place-at.

#lang racket/base
(require racket/match
         racket/place/define-remote-server)
 
(define-named-remote-server tuple-server
  (define-state h (make-hash))
  (define-rpc (set k v)
    (hash-set! h k v)
    v)
  (define-rpc (get k)
    (hash-ref h k #f))
  (define-cast (hello)
    (printf "Hello from define-cast\n")
    (flush-output)))
 

Figure 2: examples/named/tuple.rkt

The define-named-remote-server form takes an identifier and a +list of custom expressions as its arguments. From the identifier a +place-thunk function is created by prepending the make- prefix. +In this case make-tuple-server. The +make-tuple-server identifier is the +place-function-name given to the +supervise-named-dynamic-place-at form above. The +define-state custom form translates into a simple +define form, which is closed over by the define-rpc +form.

The define-rpc form is expanded into two parts. The first +part is the client stubs that call the rpc functions. The client +function name is formed by concatenating the +define-named-remote-server identifier, tuple-server, +with the RPC function name set to form tuple-server-set. +The RPC client functions take a destination argument which is a +remote-connection% descriptor and then the RPC function +arguments. The RPC client function sends the RPC function name, +set, and the RPC arguments to the destination by calling an +internal function named-place-channel-put. The RPC client +then calls named-place-channel-get to wait for the RPC +response.

The second expansion part of define-rpc is the server +implementation of the RPC call. The server is implemented by a match +expression inside the make-tuple-server function. The match +clause for tuple-server-set matches on messages beginning +with the 'set symbol. The server executes the RPC call with +the communicated arguments and sends the result back to the RPC +client.

The define-cast form is similar to the define-rpc form +except there is no reply message from the server to client

(module tuple racket/base
  (require racket/place
           racket/match)
  (define/provide
   (tuple-server-set dest k v)
   (named-place-channel-put dest (list 'set k v))
   (named-place-channel-get dest))
  (define/provide
   (tuple-server-get dest k)
   (named-place-channel-put dest (list 'get k))
   (named-place-channel-get dest))
  (define/provide
   (tuple-server-hello dest)
   (named-place-channel-put dest (list 'hello)))
  (define/provide
   (make-tuple-server ch)
    (let ()
      (define h (make-hash))
      (let loop ()
        (define msg (place-channel-get ch))
        (define (log-to-parent-real
                  msg
                  #:severity (severity 'info))
          (place-channel-put
            ch
            (log-message severity msg)))
        (syntax-parameterize
         ((log-to-parent (make-rename-transformer
                           #'log-to-parent-real)))
         (match
          msg
          ((list (list 'set k v) src)
           (define result (let () (hash-set! h k v) v))
           (place-channel-put src result)
           (loop))
          ((list (list 'get k) src)
           (define result (let () (hash-ref h k #f)))
           (place-channel-put src result)
           (loop))
          ((list (list 'hello) src)
           (define result
             (let ()
               (printf "Hello from define-cast\n")
               (flush-output)))
           (loop))))
        loop))))

Figure 3: Expansion of define-named-remote-server

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/parameterize.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/parameterize.html new file mode 100644 index 00000000..fbeed1e3 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/parameterize.html @@ -0,0 +1,44 @@ + +4.13 Dynamic Binding: parameterize

4.13 Dynamic Binding: parameterize

+Parameters in The Racket Reference also documents parameterize.

The parameterize form associates a new value with a +parameter during the evaluation of body +expressions:

(parameterize ([parameter-expr value-expr] ...)
  body ...+)

The term “parameter” is sometimes used to refer to the +arguments of a function, but “parameter” in Racket +has the more specific meaning described here.

For example, the error-print-width parameter controls how +many characters of a value are printed in an error message:

> (parameterize ([error-print-width 5])
    (car (expt 10 1024)))

car: contract violation

  expected: pair?

  given: 10...

> (parameterize ([error-print-width 10])
    (car (expt 10 1024)))

car: contract violation

  expected: pair?

  given: 1000000...

More generally, parameters implement a kind of dynamic binding. The +make-parameter function takes any value and returns a new +parameter that is initialized to the given value. Applying the +parameter as a function returns its current value:

> (define location (make-parameter "here"))
> (location)

"here"

In a parameterize form, each parameter-expr must +produce a parameter. During the evaluation of the bodys, each +specified parameter is given the result of the corresponding +value-expr. When control leaves the parameterize +form—either through a normal return, an exception, or some other +escape—the parameter reverts to its earlier value:

> (parameterize ([location "there"])
    (location))

"there"

> (location)

"here"

> (parameterize ([location "in a house"])
    (list (location)
          (parameterize ([location "with a mouse"])
            (location))
          (location)))

'("in a house" "with a mouse" "in a house")

> (parameterize ([location "in a box"])
    (car (location)))

car: contract violation

  expected: pair?

  given: "in a box"

> (location)

"here"

The parameterize form is not a binding form like +let; each use of location above refers directly to +the original definition. A parameterize form adjusts the +value of a parameter during the whole time that the +parameterize body is evaluated, even for uses of the +parameter that are textually outside of the parameterize +body:

> (define (would-you-could-you?)
    (and (not (equal? (location) "here"))
         (not (equal? (location) "there"))))
> (would-you-could-you?)

#f

> (parameterize ([location "on a bus"])
    (would-you-could-you?))

#t

If a use of a parameter is textually inside the body of a +parameterize but not evaluated before the +parameterize form produces a value, then the use does not see +the value installed by the parameterize form:

> (let ([get (parameterize ([location "with a fox"])
               (lambda () (location)))])
    (get))

"here"

The current binding of a parameter can be adjusted imperatively by +calling the parameter as a function with a value. If a +parameterize has adjusted the value of the parameter, then +directly applying the parameter procedure affects only the value +associated with the active parameterize:

> (define (try-again! where)
    (location where))
> (location)

"here"

> (parameterize ([location "on a train"])
    (list (location)
          (begin (try-again! "in a boat")
                 (location))))

'("on a train" "in a boat")

> (location)

"here"

Using parameterize is generally preferable to updating a +parameter value imperatively—for much the same reasons that binding +a fresh variable with let is preferable to using +set! (see Assignment: set!).

It may seem that variables and set! can solve many of the +same problems that parameters solve. For example, lokation +could be defined as a string, and set! could be used +to adjust its value:

> (define lokation "here")
> (define (would-ya-could-ya?)
    (and (not (equal? lokation "here"))
         (not (equal? lokation "there"))))
> (set! lokation "on a bus")
> (would-ya-could-ya?)

#t

Parameters, however, offer several crucial advantages over +set!:

  • The parameterize form helps automatically reset the +value of a parameter when control escapes due to an exception. +Adding exception handlers and other forms to rewind a +set! is relatively tedious.

  • Parameters work nicely with tail calls (see +Tail Recursion). The last body in a +parameterize form is in tail position with +respect to the parameterize form.

  • Parameters work properly with threads (see +Threads). The parameterize form adjusts +the value of a parameter only for evaluation in the current +thread, which avoids race conditions with other threads.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/pattern-macros.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/pattern-macros.html new file mode 100644 index 00000000..b73066c6 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/pattern-macros.html @@ -0,0 +1,127 @@ + +16.1 Pattern-Based Macros

16.1 Pattern-Based Macros

A pattern-based macro replaces any code that matches a +pattern to an expansion that uses parts of the original syntax that +match parts of the pattern.

16.1.1 define-syntax-rule

The simplest way to create a macro is to use +define-syntax-rule:

(define-syntax-rule pattern template)

As a running example, consider the swap macro, which swaps +the values stored in two variables. It can be implemented using +define-syntax-rule as follows:

The macro is “un-Rackety” in the sense that it +involves side effects on variables—but the point of macros is to let +you add syntactic forms that some other language designer might not +approve.

(define-syntax-rule (swap x y)
  (let ([tmp x])
    (set! x y)
    (set! y tmp)))

The define-syntax-rule form binds a macro that matches a +single pattern. The pattern must always start with an open parenthesis +followed by an identifier, which is swap in this case. After +the initial identifier, other identifiers are macro pattern +variables that can match anything in a use of the macro. Thus, this +macro matches the form (swap form1 form2) for any +form1 and form2.

Macro pattern variables are similar to pattern variables for +match. See Pattern Matching.

After the pattern in define-syntax-rule is the +template. The template is used in place of a form that +matches the pattern, except that each instance of a pattern variable +in the template is replaced with the part of the macro use the pattern +variable matched. For example, in

(swap first last)

the pattern variable x matches first and y +matches last, so that the expansion is

(let ([tmp first])
  (set! first last)
  (set! last tmp))
16.1.2 Lexical Scope

Suppose that we use the swap macro to swap variables named +tmp and other:

(let ([tmp 5]
      [other 6])
  (swap tmp other)
  (list tmp other))

The result of the above expression should be (6 5). The +naive expansion of this use of swap, however, is

(let ([tmp 5]
      [other 6])
  (let ([tmp tmp])
    (set! tmp other)
    (set! other tmp))
  (list tmp other))

whose result is (5 6). The problem is that the naive +expansion confuses the tmp in the context where swap +is used with the tmp that is in the macro template.

Racket doesn’t produce the naive expansion for the above use of +swap. Instead, it produces

(let ([tmp 5]
      [other 6])
  (let ([tmp_1 tmp])
    (set! tmp other)
    (set! other tmp_1))
  (list tmp other))

with the correct result in (6 5). Similarly, in the +example

(let ([set! 5]
      [other 6])
  (swap set! other)
  (list set! other))

the expansion is

(let ([set!_1 5]
      [other 6])
  (let ([tmp set!_1])
    (set! set!_1 other)
    (set! other tmp))
  (list set!_1 other))

so that the local set! binding doesn’t interfere with the +assignments introduced by the macro template.

In other words, Racket’s pattern-based macros automatically maintain +lexical scope, so macro implementors can reason about variable +reference in macros and macro uses in the same way as for functions +and function calls.

16.1.3 define-syntax and syntax-rules

The define-syntax-rule form binds a macro that matches a +single pattern, but Racket’s macro system supports transformers that +match multiple patterns starting with the same identifier. To write +such macros, the programmer must use the more general +define-syntax form along with the syntax-rules +transformer form:

(define-syntax id
  (syntax-rules (literal-id ...)
    [pattern template]
    ...))

The define-syntax-rule form is itself a macro +that expands into define-syntax with a syntax-rules +form that contains only one pattern and template.

For example, suppose we would like a rotate macro that +generalizes swap to work on either two or three identifiers, +so that

(let ([red 1] [green 2] [blue 3])
  (rotate red green)      ; swaps
  (rotate red green blue) ; rotates left
  (list red green blue))

produces (1 3 2). We can implement rotate +using syntax-rules:

(define-syntax rotate
  (syntax-rules ()
    [(rotate a b) (swap a b)]
    [(rotate a b c) (begin
                     (swap a b)
                     (swap b c))]))

The expression (rotate red green) matches the first pattern +in the syntax-rules form, so it expands to (swap red green). The expression (rotate red green blue) matches the second +pattern, so it expands to (begin (swap red green) (swap green blue)).

16.1.4 Matching Sequences

A better rotate macro would allow any number of identifiers, +instead of just two or three. To match a use of rotate with +any number of identifiers, we need a pattern form that has something +like a Kleene star. In a Racket macro pattern, a star is written as +....

To implement rotate with ..., we need a base case to +handle a single identifier, and an inductive case to handle more than +one identifier:

(define-syntax rotate
  (syntax-rules ()
    [(rotate a) (void)]
    [(rotate a b c ...) (begin
                          (swap a b)
                          (rotate b c ...))]))

When a pattern variable like c is followed by ... in +a pattern, then it must be followed by ... in a template, +too. The pattern variable effectively matches a sequence of zero or +more forms, and it is replaced in the template by the same sequence.

Both versions of rotate so far are a bit inefficient, since +pairwise swapping keeps moving the value from the first variable into +every variable in the sequence until it arrives at the last one. A +more efficient rotate would move the first value directly to +the last variable. We can use ... patterns to implement the +more efficient variant using a helper macro:

(define-syntax rotate
  (syntax-rules ()
    [(rotate a c ...)
     (shift-to (c ... a) (a c ...))]))
 
(define-syntax shift-to
  (syntax-rules ()
    [(shift-to (from0 from ...) (to0 to ...))
     (let ([tmp from0])
       (set! to from) ...
       (set! to0 tmp))]))

In the shift-to macro, ... in the template follows +(set! to from), which causes the (set! to from) +expression to be duplicated as many times as necessary to use each +identifier matched in the to and from +sequences. (The number of to and from matches must +be the same, otherwise the macro expansion fails with an error.)

16.1.5 Identifier Macros

Given our macro definitions, the swap or rotate +identifiers must be used after an open parenthesis, otherwise a syntax +error is reported:

> (+ swap 3)

eval:2:0: swap: bad syntax

  in: swap

An identifier macro is a pattern-matching macro that +works when used by itself without parentheses. For example, we +can define val as an identifier macro that expands to +(get-val), so (+ val 3) would expand to +(+ (get-val) 3).

> (define-syntax val
    (lambda (stx)
      (syntax-case stx ()
        [val (identifier? (syntax val)) (syntax (get-val))])))
> (define-values (get-val put-val!)
    (let ([private-val 0])
      (values (lambda () private-val)
              (lambda (v) (set! private-val v)))))
> val

0

> (+ val 3)

3

The val macro uses syntax-case, which enables defining more +powerful macros and will be explained in the Mixing Patterns and Expressions: syntax-case section. +For now it is sufficient to know that to define a macro, syntax-case +is used in a lambda, and its templates must be wrapped with an explicit +syntax constructor. Finally, syntax-case clauses +may specify additional guard conditions after the pattern.

Our val macro uses an identifier? condition to ensure that +val must not be used with parentheses. Instead, the macro raises +a syntax error:

> (val)

eval:8:0: val: bad syntax

  in: (val)

16.1.6 set! Transformers

With the above val macro, we still must call put-val! to +change the stored value. It would be more convenient, however, to use +set! directly on val. To invoke the macro when val is +used with set!, we create an +assignment transformer +with make-set!-transformer. +We must also declare set! as a literal in the syntax-case +literal list.

> (define-syntax val2
    (make-set!-transformer
     (lambda (stx)
       (syntax-case stx (set!)
         [val2 (identifier? (syntax val2)) (syntax (get-val))]
         [(set! val2 e) (syntax (put-val! e))]))))
> val2

0

> (+ val2 3)

3

> (set! val2 10)
> val2

10

16.1.7 Macro-Generating Macros

Suppose that we have many identifiers like val and val2 +that we’d like to redirect to accessor and mutator functions like +get-val and put-val!. We’d like to be able to +just write:

(define-get/put-id val get-val put-val!)

Naturally, we can implement define-get/put-id as a macro:

> (define-syntax-rule (define-get/put-id id get put!)
    (define-syntax id
      (make-set!-transformer
       (lambda (stx)
         (syntax-case stx (set!)
           [id (identifier? (syntax id)) (syntax (get))]
           [(set! id e) (syntax (put! e))])))))
> (define-get/put-id val3 get-val put-val!)
> (set! val3 11)
> val3

11

The define-get/put-id macro is a macro-generating +macro.

16.1.8 Extended Example: Call-by-Reference Functions

We can use pattern-matching macros to add a form to Racket +for defining first-order call-by-reference functions. When a +call-by-reference function body mutates its formal argument, the +mutation applies to variables that are supplied as actual arguments in +a call to the function.

For example, if define-cbr is like define except +that it defines a call-by-reference function, then

(define-cbr (f a b)
  (swap a b))
 
(let ([x 1] [y 2])
  (f x y)
  (list x y))

produces (2 1).

We will implement call-by-reference functions by having function calls +supply accessor and mutators for the arguments, instead of supplying +argument values directly. In particular, for the function f +above, we’ll generate

(define (do-f get-a get-b put-a! put-b!)
  (define-get/put-id a get-a put-a!)
  (define-get/put-id b get-b put-b!)
  (swap a b))

and redirect a function call (f x y) to

(do-f (lambda () x)
      (lambda () y)
      (lambda (v) (set! x v))
      (lambda (v) (set! y v)))

Clearly, then define-cbr is a macro-generating macro, which +binds f to a macro that expands to a call of do-f. +That is, (define-cbr (f a b) (swap a b)) needs to generate the +definition

(define-syntax f
  (syntax-rules ()
    [(id actual ...)
     (do-f (lambda () actual)
           ...
           (lambda (v)
             (set! actual v))
           ...)]))

At the same time, define-cbr needs to define do-f +using the body of f, this second part is slightly more +complex, so we defer most of it to a define-for-cbr helper +module, which lets us write define-cbr easily enough:

(define-syntax-rule (define-cbr (id arg ...) body)
  (begin
    (define-syntax id
      (syntax-rules ()
        [(id actual (... ...))
         (do-f (lambda () actual)
               (... ...)
               (lambda (v)
                 (set! actual v))
               (... ...))]))
    (define-for-cbr do-f (arg ...)
      () ; explained below...
      body)))

Our remaining task is to define define-for-cbr so that it +converts

(define-for-cbr do-f (a b) () (swap a b))

to the function definition do-f above. Most of the work is +generating a define-get/put-id declaration for each argument, +a and b, and putting them before the body. Normally, +that’s an easy task for ... in a pattern and template, but +this time there’s a catch: we need to generate the names +get-a and put-a! as well as get-b and +put-b!, and the pattern language provides no way to +synthesize identifiers based on existing identifiers.

As it turns out, lexical scope gives us a way around this problem. The +trick is to iterate expansions of define-for-cbr once for +each argument in the function, and that’s why define-for-cbr +starts with an apparently useless () after the argument +list. We need to keep track of all the arguments seen so far and the +get and put names generated for each, in addition to +the arguments left to process. After we’ve processed all the +identifiers, then we have all the names we need.

Here is the definition of define-for-cbr:

(define-syntax define-for-cbr
  (syntax-rules ()
    [(define-for-cbr do-f (id0 id ...)
       (gens ...) body)
     (define-for-cbr do-f (id ...)
       (gens ... (id0 get put)) body)]
    [(define-for-cbr do-f ()
       ((id get put) ...) body)
     (define (do-f get ... put ...)
       (define-get/put-id id get put) ...
       body)]))

Step-by-step, expansion proceeds as follows:

(define-for-cbr do-f (a b)
  () (swap a b))
=> (define-for-cbr do-f (b)
     ([a get_1 put_1]) (swap a b))
=> (define-for-cbr do-f ()
     ([a get_1 put_1] [b get_2 put_2]) (swap a b))
=> (define (do-f get_1 get_2 put_1 put_2)
     (define-get/put-id a get_1 put_1)
     (define-get/put-id b get_2 put_2)
     (swap a b))

The “subscripts” on get_1, get_2, +put_1, and put_2 are inserted by the macro +expander to preserve lexical scope, since the get +generated by each iteration of define-for-cbr should not +bind the get generated by a different iteration. In +other words, we are essentially tricking the macro expander into +generating fresh names for us, but the technique illustrates some +of the surprising power of pattern-based macros with automatic +lexical scope.

The last expression eventually expands to just

(define (do-f get_1 get_2 put_1 put_2)
  (let ([tmp (get_1)])
    (put_1 (get_2))
    (put_2 tmp)))

which implements the call-by-name function f.

To summarize, then, we can add call-by-reference functions to +Racket with just three small pattern-based macros: +define-cbr, define-for-cbr, and +define-get/put-id.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/performance.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/performance.html new file mode 100644 index 00000000..59382496 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/performance.html @@ -0,0 +1,348 @@ + +19 Performance

19 Performance

Alan Perlis famously quipped “Lisp programmers know the value of +everything and the cost of nothing.” A Racket programmer knows, for +example, that a lambda anywhere in a program produces a value +that is closed over its lexical environment—but how much does +allocating that value cost? While most programmers have a reasonable +grasp of the cost of various operations and data structures at the +machine level, the gap between the Racket language model and the +underlying computing machinery can be quite large.

In this chapter, we narrow the gap by explaining details of the +Racket compiler and runtime system and how they affect the runtime +and memory performance of Racket code.

19.1 Performance in DrRacket

By default, DrRacket instruments programs for debugging, and +debugging instrumentation (provided by the +Errortrace: Debugging and Profiling +library) can significantly degrade performance for +some programs. Even when debugging is disabled through the +Choose Language... dialog’s Show Details panel, +the Preserve stacktrace checkbox is clicked by default, +which also affects performance. Disabling debugging and stacktrace +preservation provides performance results that are more consistent +with running in plain racket.

Even so, DrRacket and programs developed within DrRacket use the same +Racket virtual machine, so garbage collection times (see +Memory Management) may be longer in DrRacket than when a program is +run by itself, and DrRacket threads may impede execution of program +threads. For the most reliable timing results for a program, run in +plain racket instead of in the DrRacket development environment. +Non-interactive mode should be used instead of the +REPL to benefit from the module system. See +Modules and Performance for details.

19.2 Racket Virtual Machine Implementations

Racket is available in two implementations, CS and +BC:

  • CS is the current default implementation. It is +a newer implementation that builds on +Chez Scheme as its core +virtual machine. This implementation performs better than +the BC implementation for most programs.

    For this implementation, (system-type 'vm) reports +'chez-scheme and (system-type 'gc) reports +'cs.

  • BC is an older implementation, and was the default until version 8.0. +The implementation features a compiler and runtime written in C, +with a precise garbage collector and a just-in-time compiler (JIT) +on most platforms.

    For this implementation, (system-type 'vm) reports +'racket.

    The BC implementation itself has two variants, 3m and +CGC:

    • 3m is the normal BC variant with a precise + garbage collector.

      For this variant, (system-type 'gc) reports +'3m.

    • CGC is the oldest variant. It’s the same basic +implementation as 3m (i.e., the same virtual +machine), but compiled to rely on a “conservative” +garbage collector, which affects the way that Racket +interacts with C code. See CGC versus 3m in Inside: Racket C API for more +information.

      For this variant, (system-type 'gc) reports +'cgc.

In general, Racket programs should run the same in all variants. +Furthermore, the performance characteristics of Racket program should +be similar in the CS and BC implementations. The cases +where a program may depend on the implementation will typically +involve interactions with foreign libraries; in particular, the Racket +C API described in Inside: Racket C API is different for the +CS implementation versus the BC implementation.

19.3 Bytecode, Machine Code, and Just-in-Time (JIT) Compilers

Every definition or expression to be evaluated by Racket is compiled +to an internal bytecode format, although “bytecode” may actually be +native machine code. In interactive mode, this compilation occurs +automatically and on-the-fly. Tools like raco make and +raco setup marshal compiled bytecode to a file, so that you do +not have to compile from source every time that you run a program. +See Compilation and Configuration: raco for more information on generating +bytecode files.

The bytecode compiler applies all standard optimizations, such as +constant propagation, constant folding, inlining, and dead-code +elimination. For example, in an environment where + has its +usual binding, the expression (let ([x 1] [y (lambda () 4)]) (+ 1 (y))) is compiled the same as the constant 5.

For the CS implementation of Racket, the main bytecode format +is non-portable machine code. For the BC implementation of +Racket, bytecode is portable in the sense that it is +machine-independent. Setting current-compile-target-machine +to #f selects a separate machine-independent and +variant-independent format on all Racket implementations, but running +code in that format requires an additional internal conversion step to +the implementation’s main bytecode format.

Machine-independent bytecode for the BC implementation is further +compiled to native code via a just-in-time or JIT +compiler. The JIT compiler substantially speeds programs that +execute tight loops, arithmetic on small integers, and arithmetic on +inexact real numbers. Currently, JIT compilation is supported +for x86, x86_64 (a.k.a. AMD64), 32-bit ARM, and 32-bit PowerPC processors. +The JIT compiler can be disabled via the +eval-jit-enabled parameter or the --no-jit/-j +command-line flag for racket. Setting eval-jit-enabled +to #f has no effect on the CS implementation of Racket.

The JIT compiler works incrementally as functions are applied, +but the JIT compiler makes only limited use of run-time +information when compiling procedures, since the code for a given +module body or lambda abstraction is compiled only once. The +JIT’s granularity of compilation is a single procedure body, +not counting the bodies of any lexically nested procedures. The +overhead for JIT compilation is normally so small that it is +difficult to detect.

For information about viewing intermediate Racket code +representations, especially for the CS implementation, see +Inspecting Compiler Passes.

19.4 Modules and Performance

The module system aids optimization by helping to ensure that +identifiers have the usual bindings. That is, the + provided +by racket/base can be recognized by the compiler and +inlined. In contrast, in a traditional interactive Scheme system, the top-level ++ binding might be redefined, so the compiler cannot assume a +fixed + binding (unless special flags or declarations +are used to compensate for the lack of a module system).

Even in the top-level environment, importing with require +enables some inlining optimizations. Although a + definition +at the top level might shadow an imported +, the shadowing +definition applies only to expressions evaluated later.

Within a module, inlining and constant-propagation optimizations take +additional advantage of the fact that definitions within a module +cannot be mutated when no set! is visible at compile +time. Such optimizations are unavailable in the top-level +environment. Although this optimization within modules is important +for performance, it hinders some forms of interactive development and +exploration. The compile-enforce-module-constants parameter +disables the compiler’s assumptions about module +definitions when interactive exploration is more important. See +Assignment and Redefinition for more information.

The compiler may inline functions or propagate constants across module +boundaries. To avoid generating too much code in the case of function +inlining, the compiler is conservative when choosing candidates for +cross-module inlining; see Function-Call Optimizations for +information on providing inlining hints to the compiler.

The later section letrec Performance provides some +additional caveats concerning inlining of module bindings.

19.5 Function-Call Optimizations

When the compiler detects a function call to an immediately visible +function, it generates more efficient code than for a generic call, +especially for tail calls. For example, given the program

(letrec ([odd (lambda (x)
                (if (zero? x)
                    #f
                    (even (sub1 x))))]
         [even (lambda (x)
                 (if (zero? x)
                     #t
                     (odd (sub1 x))))])
  (odd 40000000))

the compiler can detect the oddeven loop and +produce code that runs much faster via loop unrolling and related +optimizations.

Within a module form, defined variables are lexically scoped +like letrec bindings, and definitions within a module +therefore permit call optimizations, so

(define (odd x) ....)
(define (even x) ....)

within a module would perform the same as the letrec version.

For direct calls to functions with keyword arguments, the compiler can +typically check keyword arguments statically and generate a direct +call to a non-keyword variant of the function, which reduces the +run-time overhead of keyword checking. This optimization applies only +for keyword-accepting procedures that are bound with define.

For immediate calls to functions that are small enough, the compiler +may inline the function call by replacing the call with the body of +the function. In addition to the size of the target function’s body, +the compiler’s heuristics take into account the amount of inlining +already performed at the call site and whether the called function +itself calls functions other than simple primitive operations. When a +module is compiled, some functions defined at the module level are +determined to be candidates for inlining into other modules; normally, +only trivial functions are considered candidates for cross-module +inlining, but a programmer can wrap a function definition with +begin-encourage-inline to encourage inlining +of the function.

Primitive operations like pair?, car, and +cdr are inlined at the machine-code level by the bytecode or JIT +compiler. See also the later section Fixnum and Flonum Optimizations for +information about inlined arithmetic operations.

19.6 Mutation and Performance

Using set! to mutate a variable can lead to bad +performance. For example, the microbenchmark

#lang racket/base
 
(define (subtract-one x)
  (set! x (sub1 x))
  x)
 
(time
  (let loop ([n 4000000])
    (if (zero? n)
        'done
        (loop (subtract-one n)))))

runs much more slowly than the equivalent

#lang racket/base
 
(define (subtract-one x)
  (sub1 x))
 
(time
  (let loop ([n 4000000])
    (if (zero? n)
        'done
        (loop (subtract-one n)))))

In the first variant, a new location is allocated for x on +every iteration, leading to poor performance. A more clever compiler +could unravel the use of set! in the first example, but since +mutation is discouraged (see Guidelines for Using Assignment), the compiler’s +effort is spent elsewhere.

More significantly, mutation can obscure bindings where inlining and +constant-propagation might otherwise apply. For example, in

(let ([minus1 #f])
  (set! minus1 sub1)
  (let loop ([n 4000000])
    (if (zero? n)
        'done
        (loop (minus1 n)))))

the set! obscures the fact that minus1 is just +another name for the built-in sub1.

19.7 letrec Performance

When letrec is used to bind only procedures and literals, +then the compiler can treat the bindings in an optimal manner, +compiling uses of the bindings efficiently. When other kinds of +bindings are mixed with procedures, the compiler may be less able to +determine the control flow.

For example,

(letrec ([loop (lambda (x)
                (if (zero? x)
                    'done
                    (loop (next x))))]
         [junk (display loop)]
         [next (lambda (x) (sub1 x))])
  (loop 40000000))

likely compiles to less efficient code than

(letrec ([loop (lambda (x)
                (if (zero? x)
                    'done
                    (loop (next x))))]
         [next (lambda (x) (sub1 x))])
  (loop 40000000))

In the first case, the compiler likely does not know that +display does not call loop. If it did, then +loop might refer to next before the binding is +available.

This caveat about letrec also applies to definitions of +functions and constants as internal definitions or in modules. A +definition sequence in a module body is analogous to a sequence of +letrec bindings, and non-constant expressions in a module +body can interfere with the optimization of references to later +bindings.

19.8 Fixnum and Flonum Optimizations

A fixnum is a small exact integer. In this case, “small” +depends on the platform. For a 32-bit machine, numbers that can be +expressed in 29-30 bits plus a sign bit are represented as fixnums. On +a 64-bit machine, 60-62 bits plus a sign bit are available.

A flonum is used to represent any inexact real number. They +correspond to 64-bit IEEE floating-point numbers on all platforms.

Inlined fixnum and flonum arithmetic operations are among the most +important advantages of the compiler. For example, when ++ is applied to two arguments, the generated machine code +tests whether the two arguments are fixnums, and if so, it uses the +machine’s instruction to add the numbers (and check for overflow). If +the two numbers are not fixnums, then it checks whether +both are flonums; in that case, the machine’s floating-point +operations are used directly. For functions that take any number of +arguments, such as +, inlining works for two or more +arguments (except for -, whose one-argument case is also +inlined) when the arguments are either all fixnums or all flonums.

Flonums are typically boxed, which means that memory is +allocated to hold every result of a flonum computation. Fortunately, +the generational garbage collector (described later in +Memory Management) makes allocation for short-lived results +reasonably cheap. Fixnums, in contrast are never boxed, so they are +typically cheap to use.

See Parallelism with Futures for an example use of +flonum-specific operations.

The racket/flonum library provides flonum-specific +operations, and combinations of flonum operations allow the compiler +to generate code that avoids boxing and unboxing intermediate +results. Besides results within immediate combinations, +flonum-specific results that are bound with let and consumed +by a later flonum-specific operation are unboxed within temporary +storage. Unboxing applies most reliably to uses of a +flonum-specific operation with two arguments. +Finally, the compiler can detect some flonum-valued loop +accumulators and avoid boxing of the accumulator. +Unboxing of local bindings and accumulators is not +supported by the BC implementation’s JIT for PowerPC.

For some loop patterns, the compiler may need hints to enable +unboxing. For example:

(define (flvector-sum vec init)
  (let loop ([i 0] [sum init])
    (if (fx= i (flvector-length vec))
        sum
        (loop (fx+ i 1) (fl+ sum (flvector-ref vec i))))))

The compiler may not be able to unbox sum in this example for +two reasons: it cannot determine locally that its initial value from +init will be a flonum, and it cannot tell locally that the +eq? identity of the result sum is irrelevant. +Changing the reference init to (fl+ init) and +changing the result sum to (fl+ sum) gives the +compiler hints and license to unbox sum.

The bytecode decompiler (see raco decompile: Decompiling Bytecode) for the BC implementation +annotates combinations where the JIT can avoid boxes with +#%flonum, #%as-flonum, and +#%from-flonum. For the CS variant, the +“bytecode” decompiler shows machine code, but install the +"disassemble" package to potentially see the machine code as +machine-specific assembly code. See also Inspecting Compiler Passes.

The racket/unsafe/ops library provides unchecked +fixnum- and flonum-specific operations. Unchecked flonum-specific +operations allow unboxing, and sometimes they allow the compiler to +reorder expressions to improve performance. See also +Unchecked, Unsafe Operations, especially the warnings about unsafety.

19.9 Unchecked, Unsafe Operations

The racket/unsafe/ops library provides functions that +are like other functions in racket/base, but they +assume (instead of checking) that provided arguments are of the right +type. For example, unsafe-vector-ref accesses an element from +a vector without checking that its first argument is actually a vector +and without checking that the given index is in bounds. For tight +loops that use these functions, avoiding checks can sometimes speed +the computation, though the benefits vary for different unchecked +functions and different contexts.

Beware that, as “unsafe” in the library and function names suggest, +misusing the exports of racket/unsafe/ops can lead to +crashes or memory corruption.

19.10 Foreign Pointers

The ffi/unsafe library provides functions for unsafely +reading and writing arbitrary pointer values. The compiler recognizes uses +of ptr-ref and ptr-set! where the second argument is +a direct reference to one of the following built-in C types: +_int8, _int16, _int32, _int64, +_double, _float, and _pointer. Then, if the +first argument to ptr-ref or ptr-set! is a C pointer +(not a byte string), then the pointer read or write is performed +inline in the generated code.

The bytecode compiler will optimize references to integer +abbreviations like _int to C types like +_int32where the representation sizes are constant across +platforms—so the compiler can specialize access with those C types. C +types such as _long or _intptr are not constant +across platforms, so their uses are not as consistently specialized.

Pointer reads and writes using _float or _double are +not currently subject to unboxing optimizations.

19.11 Regular Expression Performance

When a string or byte string is provided to a function like +regexp-match, then the string is internally compiled into +a regexp value. Instead of supplying a string or byte string +multiple times as a pattern for matching, compile the pattern once to +a regexp value using regexp, byte-regexp, +pregexp, or byte-pregexp. In place of a constant +string or byte string, write a constant regexp using an +#rx or #px prefix.

(define (slow-matcher str)
  (regexp-match? "[0-9]+" str))
 
(define (fast-matcher str)
  (regexp-match? #rx"[0-9]+" str))
 
(define (make-slow-matcher pattern-str)
  (lambda (str)
    (regexp-match? pattern-str str)))
 
(define (make-fast-matcher pattern-str)
  (define pattern-rx (regexp pattern-str))
  (lambda (str)
    (regexp-match? pattern-rx str)))

19.12 Memory Management

The CS (default) and BC Racket +virtual machines each use a modern, +generational garbage collector that makes allocation +relatively cheap for short-lived objects. The CGC variant of BC uses +a conservative garbage collector which facilitates +interaction with C code at the expense of both precision and speed for +Racket memory management.

Although memory allocation is reasonably cheap, avoiding allocation +altogether is often faster. One particular place where allocation +can be avoided sometimes is in closures, which are the +run-time representation of functions that contain free variables. +For example,

(let loop ([n 40000000] [prev-thunk (lambda () #f)])
  (if (zero? n)
      (prev-thunk)
      (loop (sub1 n)
            (lambda () n))))

allocates a closure on every iteration, since (lambda () n) +effectively saves n.

The compiler can eliminate many closures automatically. For example, +in

(let loop ([n 40000000] [prev-val #f])
  (let ([prev-thunk (lambda () n)])
    (if (zero? n)
        prev-val
        (loop (sub1 n) (prev-thunk)))))

no closure is ever allocated for prev-thunk, because its only +application is visible, and so it is inlined. Similarly, in

(let n-loop ([n 400000])
  (if (zero? n)
      'done
      (let m-loop ([m 100])
        (if (zero? m)
            (n-loop (sub1 n))
            (m-loop (sub1 m))))))

then the expansion of the let form to implement +m-loop involves a closure over n, but the compiler +automatically converts the closure to pass itself n as an +argument instead.

19.13 Reachability and Garbage Collection

In general, Racket re-uses the storage for a value when the garbage +collector can prove that the object is unreachable from any other +(reachable) value. Reachability is a low-level, abstraction-breaking +concept, and thus it requires detailed knowledge of the runtime system +to predict exactly when values are reachable from each other. But +generally one value is reachable from a second one when there is some +operation to recover the original value from the second one.

To help programmers understand when an object is no longer reachable and its +storage can be reused, +Racket provides make-weak-box and weak-box-value, +the creator and accessor for a one-record struct that the garbage +collector treats specially. An object inside a weak box does not count +as reachable, and so weak-box-value might return the object +inside the box, but it might also return #f to indicate +that the object was otherwise unreachable and garbage collected. +Note that unless a garbage collection actually occurs, the value will +remain inside the weak box, even if it is unreachable.

For example, consider this program: +
#lang racket
(struct fish (weight color) #:transparent)
(define f (fish 7 'blue))
(define b (make-weak-box f))
(printf "b has ~s\n" (weak-box-value b))
(collect-garbage)
(printf "b has ~s\n" (weak-box-value b))
It will print b has #(struct:fish 7 blue) twice because the +definition of f still holds onto the fish. If the program +were this, however: +
#lang racket
(struct fish (weight color) #:transparent)
(define f (fish 7 'blue))
(define b (make-weak-box f))
(printf "b has ~s\n" (weak-box-value b))
(set! f #f)
(collect-garbage)
(printf "b has ~s\n" (weak-box-value b))
the second printout will be b has #f because +no reference to the fish exists (other than the one in the box).

As a first approximation, all values in Racket must be allocated and will +demonstrate behavior similar to the fish above. +There are a number of exceptions, however: +
  • Small integers (recognizable with fixnum?) are +always available without explicit +allocation. From the perspective of the garbage collector +and weak boxes, their storage is never reclaimed. (Due to +clever representation techniques, however, their storage +does not count towards the space that Racket uses. +That is, they are effectively free.)

  • Procedures where +the compiler can see all of their call sites may never be +allocated at all (as discussed above). +Similar optimizations may also eliminate +the allocation for other kinds of values.

  • Interned symbols are allocated only once (per place). A table inside +Racket tracks this allocation so a symbol may not become garbage +because that table holds onto it.

  • Reachability is only approximate with the CGC collector (i.e., +a value may appear reachable to that collector when there is, +in fact, no way to reach it anymore).

19.14 Weak Boxes and Testing

One important use of weak boxes is in testing that some abstraction properly +releases storage for data it no longer needs, but there is a gotcha that +can easily cause such test cases to pass improperly.

Imagine you’re designing a data structure that needs to +hold onto some value temporarily but then should clear a field or +somehow break a link to avoid referencing that value so it can be +collected. Weak boxes are a good way to test that your data structure +properly clears the value. That is, you might write a test case +that builds a value, extracts some other value from it +(that you hope becomes unreachable), puts the extracted value into a weak-box, +and then checks to see if the value disappears from the box.

This code is one attempt to follow that pattern, but it has a subtle bug: +
#lang racket
(let* ([fishes (list (fish 8 'red)
                     (fish 7 'blue))]
       [wb (make-weak-box (list-ref fishes 0))])
  (collect-garbage)
  (printf "still there? ~s\n" (weak-box-value wb)))
Specifically, it will show that the weak box is empty, but not +because fishes no longer holds onto the value, but +because fishes itself is not reachable anymore!

Change the program to this one: +
#lang racket
(let* ([fishes (list (fish 8 'red)
                     (fish 7 'blue))]
       [wb (make-weak-box (list-ref fishes 0))])
  (collect-garbage)
  (printf "still there? ~s\n" (weak-box-value wb))
  (printf "fishes is ~s\n" fishes))
and now we see the expected result. The difference is that last +occurrence of the variable fishes. That constitutes +a reference to the list, ensuring that the list is not itself +garbage collected, and thus the red fish is not either.

19.15 Reducing Garbage Collection Pauses

By default, Racket’s generational garbage collector creates +brief pauses for frequent minor collections, which inspect +only the most recently allocated objects, and long pauses for infrequent +major collections, which re-inspect all memory.

For some applications, such as animations and games, +long pauses due to a major collection can interfere +unacceptably with a program’s operation. To reduce major-collection +pauses, the 3m garbage collector supports incremental +garbage-collection mode, and the CS garbage collector supports +a useful approximation:

  • In 3m’s incremental mode, minor collections create longer +(but still relatively short) pauses by performing extra work +toward the next major collection. If all goes well, most of a +major collection’s work has been performed by minor collections +the time that a major collection is needed, so the major +collection’s pause is as short as a minor collection’s pause. +Incremental mode tends to run more slowly overall, but it can +provide much more consistent real-time behavior.

  • In CS’s incremental mode, objects are never promoted out +of the category of “recently allocated,” although there are +degrees of “recently” so that most minor collections can still +skip recent-but-not-too-recent objects. In the common case that +most of the memory use for animation or game is allocated on +startup (including its code and the code of the Racket runtime +system), a major collection may never become necessary.

If the PLT_INCREMENTAL_GC environment variable is set to a +value that starts with 0, n, or N when +Racket starts, incremental mode is permanently disabled. For +3m, if the PLT_INCREMENTAL_GC environment variable is +set to a value that starts with 1, y, or +Y when Racket starts, incremental mode is permanently +enabled. Since incremental mode is only useful for certain parts of +some programs, however, and since the need for incremental mode is a +property of a program rather than its environment, the preferred way +to enable incremental mode is with (collect-garbage 'incremental).

Calling (collect-garbage 'incremental) does not perform an +immediate garbage collection, but instead requests that each minor +collection perform incremental work up to the next major collection +(unless incremental model is permanently disabled). The request +expires with the next major collection. Make a call to +(collect-garbage 'incremental) in any repeating task within +an application that needs to be responsive in real time. Force a full +collection with (collect-garbage) just before an initial +(collect-garbage 'incremental) to initiate incremental mode +from an optimal state.

To check whether incremental mode is in use and how it affects pause +times, enable debug-level logging output for the +GC topic. For example,

  racket -W "debug@GC error" main.rkt

runs "main.rkt" with garbage-collection logging to stderr +(while preserving error-level logging for all topics). Minor +collections are reported by min lines, increment-mode minor +collections on 3m are reported with mIn lines, and major +collections are reported with MAJ lines.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/phases.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/phases.html new file mode 100644 index 00000000..6418042a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/phases.html @@ -0,0 +1,133 @@ + +16.2.6 General Phase Levels
8.6
16.2.6 General Phase Levels

A phase can be thought of as a way to separate computations in +a pipeline of processes where one produces code that is used by the +next. (E.g., a pipeline that consists of a preprocessor process, a +compiler, and an assembler.)

Imagine starting two Racket processes for this purpose. If you ignore +inter-process communication channels like sockets and files, the +processes will have no way to share anything other than the text that is +piped from the standard output of one process into the standard input of +the other. Similarly, Racket effectively allows multiple invocations of +a module to exist in the same process but separated by phase. Racket +enforces separation of such phases, where different phases cannot +communicate in any way other than via the protocol of macro expansion, +where the output of one phase is the code used in the next.

16.2.6.1 Phases and Bindings

Every binding of an identifier exists in a particular phase. The link +between a binding and its phase is represented by an integer +phase level. Phase level 0 is the phase used for “plain” +(or “runtime”) definitions, so

(define age 5)

adds a binding for age into phase level 0. The identifier +age can be defined at a higher phase level using +begin-for-syntax:

(begin-for-syntax
  (define age 5))

With a single begin-for-syntax wrapper, age is +defined at phase level 1. We can easily mix these two definitions in +the same module or in a top-level namespace, and there is no clash +between the two ages that are defined at different phase +levels:

> (define age 3)
> (begin-for-syntax
    (define age 9))

The age binding at phase level 0 has a value of 3, and the +age binding at phase level 1 has a value of 9.

Syntax objects capture binding information as a first-class value. +Thus,

#'age

is a syntax object that represents the age binding—but +since there are two ages (one at phase level 0 and one at +phase level 1), which one does it capture? In fact, Racket imbues +#'age with lexical information for all phase levels, so the +answer is that #'age captures both.

The relevant binding of age captured by #'age is +determined when #'age is eventually used. As an example, we +bind #'age to a pattern variable so we can use it in a +template, and then we evaluate the template: We +use eval here to demonstrate phases, but see +Reflection and Dynamic Evaluation for caveats about eval.

> (eval (with-syntax ([age #'age])
          #'(displayln age)))

3

The result is 3 because age is used at phase 0 level. +We can try again with the use of age inside +begin-for-syntax:

> (eval (with-syntax ([age #'age])
          #'(begin-for-syntax
              (displayln age))))

9

In this case, the answer is 9, because we are using +age at phase level 1 instead of 0 (i.e., +begin-for-syntax evaluates its expressions at phase level 1). +So, you can see that we started with the same syntax object, +#'age, and we were able to use it in two different ways: at +phase level 0 and at phase level 1.

A syntax object has a lexical context from the moment it first exists. +A syntax object that is provided from a module retains its lexical +context, and so it references bindings in the context of its source +module, not the context of its use. The following example defines +button at phase level 0 and binds it to 0, while +see-button binds the syntax object for button in +module a:

> (module a racket
    (define button 0)
    (provide (for-syntax see-button))
    ; Why not (define see-button #'button)? We explain later.
    (define-for-syntax see-button #'button))
> (module b racket
    (require 'a)
    (define button 8)
    (define-syntax (m stx)
      see-button)
    (m))
> (require 'b)

0

The result of the m macro is the value of see-button, +which is #'button with the lexical context of the a +module. Even though there is another button in b, the +second button will not confuse Racket, because the lexical +context of #'button (the value bound to see-button) is +a.

Note that see-button is bound at phase level 1 by virtue of +defining it with define-for-syntax. Phase level 1 is needed +because m is a macro, so its body executes at one phase higher +than the context of its definition. Since m is defined at +phase level 0, its body is at phase level 1, so any bindings referenced +by the body must be at phase level 1.

16.2.6.2 Phases and Modules

A phase level is a module-relative concept. When importing from +another module via require, Racket lets us shift imported +bindings to a phase level that is different from the original one:

(require "a.rkt")                ; import with no phase shift
(require (for-syntax "a.rkt"))   ; shift phase by +1
(require (for-template "a.rkt")) ; shift phase by -1
(require (for-meta 5 "a.rkt"))   ; shift phase by +5

That is, using for-syntax in require means that all of +the bindings from that module will have their phase levels increased by +one. A binding that is defined at phase level 0 and imported +with for-syntax becomes a phase-level 1 binding:

> (module c racket
    (define x 0) ; defined at phase level 0
    (provide x))
> (module d racket
    (require (for-syntax 'c))
    ; has a binding at phase level 1, not 0:
    #'x)

Let’s see what happens if we try to create a binding for the +#'button syntax object at phase level 0:

> (define button 0)
> (define see-button #'button)

Now both button and see-button are defined at phase +0. The lexical context of #'button will know that there is a +binding for button at phase 0. In fact, it seems like things +are working just fine if we try to eval see-button:

> (eval see-button)

0

Now, let’s use see-button in a macro:

> (define-syntax (m stx)
    see-button)
> (m)

see-button: undefined;

 cannot reference an identifier before its definition

  in module: top-level

Clearly, see-button is not defined at phase level 1, so we +cannot refer to it inside the macro body. Let’s try to use +see-button in another module by putting the button definitions +in a module and importing it at phase level 1. Then, we will get +see-button at phase level 1:

> (module a racket
    (define button 0)
    (define see-button #'button)
    (provide see-button))
> (module b racket
    (require (for-syntax 'a)) ; gets see-button at phase level 1
    (define-syntax (m stx)
      see-button)
    (m))

eval:1:0: button: unbound identifier;

 also, no #%top syntax transformer is bound

  in: button

Racket says that button is unbound now! When a is +imported at phase level 1, we have the following bindings:

button     at phase level 1
see-button at phase level 1

So the macro m can see a binding for see-button at +phase level 1 and will return the #'button syntax object, which +refers to button binding at phase level 1. But the use of +m is at phase level 0, and there is no button at phase +level 0 in b. That is why see-button needs to be +bound at phase level 1, as in the original a. In the original +b, then, we have the following bindings:

button     at phase level 0
see-button at phase level 1

In this scenario, we can use see-button in the macro, since +see-button is bound at phase level 1. When the macro expands, +it will refer to a button binding at phase level 0.

Defining see-button with (define see-button #'button) isn’t inherently wrong; it depends on how we intend to use +see-button. For example, we can arrange for m to +sensibly use see-button because it puts it in a phase level 1 +context using begin-for-syntax:

> (module a racket
    (define button 0)
    (define see-button #'button)
    (provide see-button))
> (module b racket
    (require (for-syntax 'a))
    (define-syntax (m stx)
      (with-syntax ([x see-button])
        #'(begin-for-syntax
            (displayln x))))
    (m))

0

In this case, module b has both button and +see-button bound at phase level 1. The expansion of the macro +is

(begin-for-syntax
  (displayln button))

which works, because button is bound at phase level 1.

Now, you might try to cheat the phase system by importing a at +both phase level 0 and phase level 1. Then you would have the following +bindings

button     at phase level 0
see-button at phase level 0
button     at phase level 1
see-button at phase level 1

You might expect now that see-button in a macro would work, but +it doesn’t:

> (module a racket
    (define button 0)
    (define see-button #'button)
    (provide see-button))
> (module b racket
    (require 'a
             (for-syntax 'a))
    (define-syntax (m stx)
      see-button)
    (m))

eval:1:0: button: unbound identifier;

 also, no #%top syntax transformer is bound

  in: button

In the definition of module a, the variable +see-button is at phase 0, and its value is the syntax object +for button, which shows the only visible button +binding is at the same phase. (That is the key detail.) +As discussed, the for-syntax import shifts the phase level of both +up one, so the phase 1 binding of see-button used in module +b is the binding from the module a that is shifted +into phase 1, which refers to button in a at phase +1. +The fact that in module b there is also a phase 0 variable +button from a different instantiation of module a +does not matter, because there is no way to reach it +from the (shifted) see-button from a.

This kind of phase-level mismatch between instantiations can be repaired +with syntax-shift-phase-level. Recall that a syntax object like +#'button captures lexical information at all phase levels. +The problem here is that see-button is +invoked at phase 1, but needs to return a syntax object that can be +evaluated at phase 0. By default, see-button is bound to +#'button at the same phase level. But with +syntax-shift-phase-level, we can make see-button +refer to #'button at a different relative phase level. +In this case, we use a phase shift of -1 to make see-button +at phase 1 refer to #'button at phase 0. (Because the phase shift +happens at every level, it will also make see-button at phase 0 +refer to #'button at phase -1.)

Note that syntax-shift-phase-level merely creates a reference +across phases. To make that reference work, we still need to instantiate our +module at both phases so the reference and its target have their bindings +available. Thus, in module 'b, +we still import module 'a at both phase 0 and phase +1—using (require 'a (for-syntax 'a))so we have a phase-1 +binding for see-button and a phase-0 binding for button. +Now macro m will work.

> (module a racket
    (define button 0)
    (define see-button (syntax-shift-phase-level #'button -1))
    (provide see-button))
> (module b racket
    (require 'a (for-syntax 'a))
    (define-syntax (m stx)
      see-button)
    (m))
> (require 'b)

0

By the way, what happens to the see-button that’s bound at phase 0? +Its #'button binding has likewise been shifted, but to phase -1. Since +button itself isn’t bound at phase -1, if we try to evaluate +see-button at phase 0, we get an error. In other words, we haven’t permanently +cured our mismatch problem—we’ve just shifted it to a less bothersome location.

> (module a racket
    (define button 0)
    (define see-button (syntax-shift-phase-level #'button -1))
    (provide see-button))
> (module b racket
    (require 'a (for-syntax 'a))
    (define-syntax (m stx)
      see-button)
    (m))
> (module b2 racket
    (require 'a)
    (eval see-button))
> (require 'b2)

button: undefined;

 cannot reference an identifier before its definition

  in module: top-level

Mismatches like the one above can also arise when a macro tries to match +literal bindings—using syntax-case or syntax-parse.

> (module x racket
    (require (for-syntax syntax/parse)
             (for-template racket/base))
  
    (provide (all-defined-out))
  
    (define button 0)
    (define (make) #'button)
    (define-syntax (process stx)
      (define-literal-set locals (button))
      (syntax-parse stx
        [(_ (n (~literal button))) #'#''ok])))
> (module y racket
    (require (for-meta 1 'x)
             (for-meta 2 'x racket/base))
  
    (begin-for-syntax
      (define-syntax (m stx)
        (with-syntax ([out (make)])
          #'(process (0 out)))))
  
    (define-syntax (p stx)
      (m))
  
    (p))

eval:2:0: process: expected the identifier `button'

  at: button

  in: (process (0 button))

In this example, make is being used in y at phase +level 2, and it returns the #'button syntax object—which +refers to button bound at phase level 0 inside x and +at phase level 2 in y from (for-meta 2 'x). The +process macro is imported at phase level 1 from +(for-meta 1 'x), and it knows that button should be +bound at phase level 1. When the syntax-parse is executed +inside process, it is looking for button bound at +phase level 1 but it sees only a phase level 2 binding and doesn’t +match.

To fix the example, we can provide make at phase level 1 +relative to x, and then we import it at phase level 1 in +y:

> (module x racket
    (require (for-syntax syntax/parse)
             (for-template racket/base))
  
    (provide (all-defined-out))
  
    (define button 0)
  
    (provide (for-syntax make))
    (define-for-syntax (make) #'button)
    (define-syntax (process stx)
      (define-literal-set locals (button))
      (syntax-parse stx
        [(_ (n (~literal button))) #'#''ok])))
> (module y racket
    (require (for-meta 1 'x)
             (for-meta 2 racket/base))
  
    (begin-for-syntax
      (define-syntax (m stx)
        (with-syntax ([out (make)])
          #'(process (0 out)))))
  
    (define-syntax (p stx)
      (m))
  
    (p))
> (require 'y)

'ok

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/pict.png b/clones/download.racket-lang.org/releases/8.6/doc/guide/pict.png new file mode 100644 index 0000000000000000000000000000000000000000..142e906bf45519b2d76bb1b07dac96eaa50d28a0 GIT binary patch literal 23264 zcmeFZcUY6#_a~ZARRoMEC{+W9bRp70(?ci$0V&d(AT4xhfl!Y}i6S6KG1Q|Fn$m;- zQlnBtLO6!rBPfv$MrtVYa?bbno4GUhd1mf??%dzZ^UObpFM0P~d+${~>$BF*(IV=vE~M=spJuiQqa88(l9`)gsuyEYM(_2kL2p_F8Lt-;v2v#(^&NxjVV^m>X@ zAbq7X=9)bFHGL{}DA2ky^srZo^F}YlL~H?a{M=GHvE=U;tawe2pPN^7WpMpD z%=4aySdI@i07j}H_1q&+E)QlyVMd;}6CV>*9s(~|*Iv+{_!kDcK@%%`JXm`Qe_ATSaC%z_5z3RK;x|vrLZe9EW)5l5($U@Xn>MU z#o=M4orq^39AZJ{!Fk9CNM1Ux@L5irwfj5|{z0kIN;REal>-l5tl^%HJsM8w%U0Sg zNYQrMuZ<@h#Zbl80aBICJh9Qme!>fB!KdEw7 zS_GxJvhyASnL5-v6tA}SkdqNYRER>AM*|C!Vzk1RM=Pdx^S7TyEXXxqa~m+W4enEV ze3e0KMQ^xz^yT)f`8URk#2hgqdizwgYXZN1uY8wRXP^;bCPlD~*SxU)(n=d@qD zm8y_*GeUP|^L<7|!`r~Gzr_tG(lvpPDj_;*ON?{E=&2&RpB58DLeIH%C(8WK3vHao1inC|M6k`p#_SqRW7gku@>8xIQY6KTK7hPqZIEsDSG@6wrfygXvce5EpYA#Nom zd6C@;-6BW1;X;vK(z)A8SC1zbf$y)|)_V3&6F>Unzw34^^p8c+8^31Sa}_0Z{ZReN z;Y{`9bJ}6pAFU_wWsqM*66W>_^{gk}JTtJXv1p^`U4VIvw#e zXDC6OW-NaUlaKs@dR-7hUv{q~m*_zE+h zen&7c;$@>unTW3@@)1b;n6|a`Sw8x=T(z7m@@2w{i#Y-HV-9~3OoyG~jg_a;KTTGK za3S3Z-=91#YKuPngJ;xld+KHOz{)GES8uBmfBr)bzRLRHUkiA*(>=ckBOcQ&5f+BD zXLh7IrD2EK3a%PI<rR)nIExNPL=}ZxK~kP2$qU^`d(=BC8CvRBKSB1kYPyYB zR=)dzg+@$=-$1meLbXl{?hQAz9~9u}29!V>4LsNUb?K?g(5{M_F8=Py`f(JuX};oj znx}JMe8Gx&P9pYs_tT5?k1OG$Uxz$%qqhi**6*_HnPf5K$1nAwMM(bKk16mc?K9yb zC9#YNqY~RON!XfPo{^~MoUyW+|J3HN`p=H%rujR$eadc=ja!Fa1=sF=NQ<7{NDd`4 z-g67f=IKgZhB|57{qV=g;mXT|D<;|3y;CR=kCxPO0?51C2MfVhO!N19SUGrQr1DBW z%CZPERgy{Uh6$Gx+!m1vi`E3PPrD;}<cc~hcWe0=UI)zPkekY+S0N@p z7e>QM>RGXvk!IeRr~zZ^{-|%M)T+mYK>8)o((HAV}9X?o->^;Ol-pWk}yGsrJj{{{=a5yOuJ^gR4; z1J;^aJC1r?v$yz~5nkbX9Fo1&lFA}-3-lMSxpgIncG#YG`ya&@|I-5c|1iS&KN6T% z{O`2~|4|3}-4lp9u?mbC6K z$u^`XzvTK^Yb5th8y0XiuQ1Uucy4pVbi;rxDIJ%h_1Rcux)Hs)JeHM3esydoMan9E z<8^fTHtO#bg~7|2GPWOjB=S|+c5W`nOi95+E@;Q>JM!hl#w=W2JaZJfztQ5=EfkxB z6aM(OAq~#^w=ERA$!i?#dmhHjMB@ufnfJGQB>H21ebGPSaxjM*spM#4w)C|&Yf}1h zRKooiuA+jooT3!6oFf-zH$6ybqXn5oe*nFsf^oY$e{9U9X#b)^%!I>HrIO|Gfchd~Hmme`6_KBF116a2 z5aCc2z)yt6b&JIAH)>DCFftfzhnp$nQ0~W86d)|CelL3N(dKt_K$CN53|u4a8!g=W zJ%T3q!6*PX1Yz z4>gFp^(rLu{Sz$9i|_07gKVu(DG+W<`KW=v1$%)zD*9)-WI*H^V9F+fA@X6U4$+_;m>$|r^G~a{b#RyY{+$| z=KnG#$mBn8+gRp;Y?xD{iM?^0@j>o9WxBFV!Yuwp{02YHa##5|LKGlq@oKf|n6IiR zM{e*o$ok&={+Fn)VGgl_Ki;Ctv%>bN)o8Bd-gbpI<8+dlsDq$?pLrG%|p z^VrFX{f#lRFd9RWm9j#AChat%L?H@Spj*jUI&`)lQscgG3&^jed%+Te5XImu%EhAW zeStv3xh2myZ`N8ME#rKQ(GV{q9I!Q>*g11e6c%f(ngX{(XuJ-2jdo1t%XaAQCxCGP8w?X{w6buSP9>n*hV2WAI!K~tm@jX)Hm zS`)K+_00IxSx!(bGRbBQ+|?)#Cucae$-*Q5BBTMtVdQB>3r;DC3`)$n4u`s)cQN-M z%K(d!hURlFpUBOtJZHcU1tR>Je!yt?5gjp*Aa8`sQ|$IuXaOmTLMfvt(gSc2nRtsd zO9^g5MiGP;BF`2>+1c`@KK?yO?EJ85)7?H&OH~N3cQw>i-6h6j`VKr1{vctzoR2%> z*&_*PF{l81$d;RdOW{ivD|?0=6>Q8!eH%|wq<;aH>V&ujIxJi$r^D#;<`H&gh^Nf? zEN4|O!Q=&Z6e_jLV|h(CXW8{VvDm!$nxufWJ`%%denAXUb7kGbMV88ed)F8!ws{#^ z&t?@6#jx?1{?Zt8hstUkelSDIRTW7u3ZiYp8*E2^N2aK!*Y#Bzjf$DHQG?;3LInCCyR0#B78ZbGEf0uK0cfac}QyEv=N2PJj2m}Y|zTeBSs50(ob44^fY4x z2VVB}vI6H1{E99)lnw3ef0v835kSAHYURO2_#&dTUj(+1DT2_dA)YRoo9 zDQZRjZX1@pSS*rg6z9o2S4NgZgLa~0rS~8ZB1e2hd{0vMJ{(5-MSnpk-I@o>kVx$O z{d7ea4j17-3y;Hh3kpjh3;vnPsX0j%)Hi1o*&z8IJiUckW2T&#ZEW4=45zsE6x0?0 z?k-nH>C!+HRmGjh+a1x7Y)SJcv&U$qZ@VK}au?UUuLSDG7F=E_4YJu$F{J%KKooe< z66?*R7D8a|O&=Nk%>0r=)oWlh^ZJGLT9U)$3t^NxRg3zQt-*wB!nnKda(+FwT(cRsq%GLx`;N{VuS?oF(OUX5@w%pq8SeH9WxUYA%zfgu_t-(Q8F^WBYC*{lPW^ZgRFa z+uG!2E_|Kozx|U8qytAvj_u&UfC0Z0W_i@Zg4$oKqatYbYQqH?C$@uFiqV1 zK^If%lj0>guSimF=o25E-p`hPr$vF;5e3!J{hsV=TUuICY_hT*mLTvXA z`r`^C_Z@Qw<~G(qhm?NB*#P2eM#O;%DAw`4+ZtQg!kj{4_G+-$dZBPi4*T*{_uTY| zDS7+!I)$nbmT31ye5Puic}`gy(Tn7>5R_ z^+N3EUG&BvYa1fe=5WrEzFq%1+`{jZEy|RdsJU7ji|`%(bzoGw6;k=Bn5YYckbVK^ ztfOVgb&ZmdLaF}Zah~x4ojB%52NhP;Rt0xMA-02TNDbc*TXoy81!#+@G6lP-r{R9k zc0=jYG@KaD;c1q$e%qe#dtr84o8Zoc_3-ku1m?gqLso>N0o6(R>GI!C4hbjAgSpN8 z;vJiyO#z4&7_5Dye@R~UE;kdO(xGD(D*mr!8ER(Nh&}jdJY?drrM*U0Q(M7^K;`>+ zM-#*?RylXuyLl&Dq%b19!&2Hb>|?C8*}?LhfOVefrm%%TA{HR$0-6?YmKQP)zk)w; ztsW@yHQIF2%37?Q<4juWHuD>bT`~A}r@QIo&iNsTM667%yXslA__`hy+ZAe*BD`~E z2y*$hY*r3;MGK$m^TkgOFs1WRlftSG%RiYE!Nus+cy27#xJ+49UNb6GVO@ucDjyIE zW15CzN%Ei=lRI(Kzuo!cW%h@8CCk_Wqp8z^GdqzQ>tAka96fQOyOwhj1Kh?u|GHmw z5%L;5<2iPp=3g$^czE+psWy@j@54;>u?*H}NFwF(K>~{GJe!+Cgb9x+%?_<~)9!WL z87{jzzj52Wj~-s$ICw7;+xR)(xFLz%->+$h1&dl-Yrr&;CK{)AICOBZB#PJS^g3>d{DmQmaZ9$X`}`s6LIrh~V|6TINpS%>&+3GL*A#>mYi%3Z%=3|RZg@mG#T-a zwBi?%%}SqH^{RM%O1pBIAlm_4h|c&^8wiC z{JxM)%!`WAu& zWb8Aa;llMg79kt(^7iM1vgvTJM#F-FCO0O)>CsFsPJ8j`Peyj!9@}#l7z)cqx-B?qN6$2Z@8UNFOAW*zCNY(2orr_PW-Q2V`y)*kdDQg8fgsdugZqIpVE2$t`ot|dH zfsuhyu9XGs?3m5h-Rsq`YwFNp5=oGHck%QRFqb`@6Q`yEUA@~$vr<~xy-1-mHofH& z%!T};P6kGPl|hLZX{+SuS2$9-LwPb|Adm#Jyd{;;INEANn>$@`zbWI>s71f)c+1WD z%Ai|pjO@Nn#t`uXI6wTs*FVz6;{gwN9*F0GDV>^?&N+*>(|tr|-8B7uoIY(T`F(KH zY;(q^Fl2`OnR`wvt-UI)GEKtvh(d~4_u20(xBZ%;TH>t1<~XO5>GM8;^p zXf3Yz7E;cMURz(g`wh`C4GFr7@U?*(-E{-;)3&4YzGrotn&lns>X$3?aMiB@_FF*1GrCi>J-+WRBoV1#NS6q!uNp)=i~L9KAS;i< z0PPfkpZ#iQ`Dx{?4^Wn!^6vAjnrqK-;pVL(gVBfY-+mmZ_inokwZdm7-@R5}$bT`o z%nvi^-}A#YNm9||<=#F6;lX8jsY#dqvM9EXRJGmMI&$61c-3`GZM=E2=JXm%?A@`; zohcsk2}X}D8spwwf;#CbW$)Kp9*wkL%`vPX>iFGpKrByQ%|4QVW!;M)I(|b_N!ngffUIRn~}Z4jLVJ za+*dH%*4L9NuX*aqyBmrKObzd{jO|bDN7F#ysMG^otw7Q-<%~JDGa$eP{&P#{fZWT z*M#sO<0DO%b8rRnc_k087t}U7c>BsEY_HI2vXr7*&-cpLW@&XRLuzQ%XETRd;$0iC zqZL)^x*d-o8)IJ{UyoFzUoLmwCgZ#p&QXO;36JE#{ZFv9aXw{Ra<^V(b1ywK-uB5? zS=J~we;bnDHX!QCR~~FQ{oyAw-@Y{`4nrOa^G7)JynVHmNZP;2S*0$6dnX3vVvo@w zY#!(A1(X};yDAQ60a?GS5LBs{@gTp>;xI(xlb$DP~uF)e~C&=CP(+@a5_ z#tjE=%rpi&73n$5Gq0ESlTq;VaWv&F*B#*@h^8~s@G`ANf;pjfS>sccZbwe(Fu2RS z@BE%r`L2%q3jLzhZ-`~$+jq#9+k0!xm~$UzJmz~oMvV=W%`ZCSp!ECCLxQ;0G35iX z`MR4CwE{ywR|h^uwPp^e9^hr?8N)xS(dBo1Perv9OdJ_1{U!>+y}JtK0#z3ApA2Ve z?N^CkjCxMjQ}mkKTua3E#*HXd+C5y{AH;hw%UWxI73mF-4IS#AU3Ur|W9j^~hnp<{ z722MN7SJe=OD#p%duYA?sk3U-+e7k!&bm@LlU^6sF1LKwFH?4Ht*+|c3RD|G)by}}u%ThlsN)Fa;4o_+NY+b7SOHSzf7DrOAIrrP&=_)Y#dn}rLXyLk%NV|G( zz^{u)SR6CsU35v8ds&d>cl0O4U=u_O4mIU2b?2qlpFycjX+T1F-r>WOk}Vsi{nKc7 z4>_;4%dmiA_|v&^EnyW7RYlm0cG^u0nq%nhpGQW7&9`}E)7=ZbY+l(+x#RuO`unt} z*epbctmVM813zSf^VbD$RxXyvd73tQ*Wa7hL!tX@N z6|VXh<%`zZSs~sCK`>hyeTI4Rg5Hjrx|YEa?#X*M6alvuRcWkb{9%shhg0)8lQQ)T z^>YzGXtn`P@Ul8PQ$$pJ`M#E3=!KPTMLO# za&$T7I@|q-%R{FOjjAS%D#{f=BdJ6rE+XKos-G-0pJV@&O#!NCW9kW8+W23F=lb)? z$Wx9&J9j;V2WJk3)FwM+y%D+{#en5v8>OLpg3m-@1)oVXHgNn)pa!c*ziLFoqR-!1 zX!#u_C683 zfOuNM?=Zhda!~#2Kzwt4uaM0Zcq=B*OBFh+TK?W7=Cs4}m`?_2gBt*AbOWeJbaHcT zNCWh3Z0dLK!<)^WULzNS;+F+I2eKW%|xn5~{w-LT)ApjJSF!c2H zgeVj%7B%qNTB}9Ky(OO+Vk}Xn*#k1cD9w; zs7wE%SG;pyv~#Rqp-SL(CqASC9S;c?D>l2aFLH6FL%aOt2{g2!kPNgK9Lo~JDahJV zqA}FD7JM!_ityyCst^KXtq%!05vaEA?(+Ptx7ZL>!R0)4vg=0!N_5VU{n>SmB#76@XHr7sbS5rEzax_C zoERY~fLWe>KAnr=4|NrwUcVIQ2BQZ&6h-pi#qEw^4X7~UQap@9pJKQ!2<(7b{>o+O zFsqialKd1ukqfuWcv~jMc?Yp<7;3Z6Lkz=3n0__z6Ne7}DU}a|&2WH0Y3lQ;)Yj{0 z2W@-IKM!rs)Jw)_;I}rx)ENQiBVqKPF1*N(;p~BO>q17f&pxD}CR3m|w3vl!$RPij zLHlRhx6VM8nAwks%?hAwl~%O+{ofThoe$y`uNij`udYb{<9Kt^tV)0Fxw-8%9>gud z=py2ZrLoBP$3{if#uN{$nXXKM!UL zv-vY?v9>e?@*+_uAvLV)0#pLA_f&W4pq)Qhj&&GZ`4qc(ie|4C?fTR6Y8p1 z&AdKAaG7VLLd5 zll_!R=-MTbopm-BAp@4iGw#2BVjBJLWC*<8w1{ z9EP;ix~EGi{Mb&5)}8le1z5CFV8qpR?UH=T7jj*&RkzsPm#HsKm1GV8} zo1fLlr~GJQLW>4k0}N5f1*ERVZv^n7pizlfnSEooMQdXx$_whMQ7sX8=Gw_o6@bpl zF-#k`K-}shMF71y{JB=nu>gMwYG%@RpLYXzeNlZvh8|fZjw3EQ-Z8ER&_{E|V{A~; z%|GT59nyf9g9=-P<7$C^2+~!dVgXwXd}^>}Am{pJ>bvBkD@dLDazmd8^myBcwFZlV z3Ac^ky=7fr_+a~YM9ab_7?zeul$rF7g9CMNVo5EYaSN87(hjG5ot2Y|GKR|&#+eWu zS% zU5dd)WZ^9+hS}Wvr&PNrWA=y^;JIv`P8!rz-z5x@d;YkNx?p*1qo)`u<=(eJytnhP z;>eGgIC}g@Ci%+~=&T=cyY%z!qWgfs*%apB_y*7t;BJoj+2Z6mVbjp&*Kr~M5$5|0 z*Djx{p9Z%>v}B^{>NkiZfZmEJ(yJ_kt7o{EPror&HuL-`Xc}6Fwc#0MN2|i*CG+&t znj8_!Z2Kp6e)F)?5GOpv+Hl&)!j7EaMiM{)!A-Y=7FSrtw)G+d=L68pKnqi-I5**r z#6-rT#(ZyF!+A2a?4xc6yXb5qMNJHeI*v&8iP*=u-Cw8tb57qPle+cQGK=JRAOTEd z=6oire$qq06w>qz5G`kHRA4}p6F%=-Hyj5IA|GjE*QWm&QGy`QaP&SJsCGaEF(6-prPCQ+d-JS#dYx!uiJb}JjlR-_zp{xnxOb(;CvS+w>csJZ z3P_~gWB>FSFlhXB^2k2_HC_XkTGGBfpiaQHJ^J|m;ULP2ofk}F#@NDvZn>f@z{4dq zVbQ$TCO%e)5dbEQ8?CiIMgppEDPm>0T`nkRRvwZnB<6hfh0W}G^$ zJlEKF+{X}Ub@%y$8xBA~u}cXiA}v_)6e9&GXXN?H++)oD-%EL#`9VJ|qV zn)m*^ZJ(5l9Tj+S!T|_d#|9xS4UOT{Fjmt21jEzQ&qCx`{Mm#{_8j-?fi00LugPyl zdE_fl^P1B;EkvPEWi~FRFqY)|w=W?VeIYg4fwcwOX+`g=(Wp`AEP*I)Y4Im$ISWVQ zeR`~5We=Z93*8X5vU$$;by6iTtovs2#6>dXct%1 z8hKDPg$^!<_=+Q?*G$T1BY<#b3BQHpHRb#!3J}h2#H<0wZ)r_85Wc4zPDg=9TLN>T z(AhrAU^!D3e;GmjwDF;M;sVjqrTK&H6Tr4OzX@4NJ6ea*2f=AgHjVG;#1ObT&3_GaiVe z%ajN}#T1Be+-~54%->qmFE^z6blH@+({;z57tnZFahS6$T*n*tj-@)pFir1|&RR_0 ztL&|BH>nB4A;2#K3OFSSwJL$L|LVr=q8Btm>9;4ijtfr80+Cb&|+o`n09a8 z0#IV}1}wHPuIhGD6r+jM(%}0lQmx#N{R!4lbe4-6NzKKg?*fIuqG29Lf3cla6!&Pm zFF$e-?#a{uvIn(a&Bccaqb6`pI-6`USd{zh@GEcNOm#b~h|=*Eu;9B38ijZT^j}qR zNpUk~#v%aT5XbF$AzB1g&!d5Kv?-$Wc(Rj3db~X>I0#VZ!E&f8XL&`R0CTg)ywXF_ zq;hQI2^&z0G>ir`rXUv`c>9$BSy-nzmW`Ae=9^FHrxn$ohs=~@SM5Z)WOYUP0L9He zfMFTCoYz`6Hov9a6f0wXb5i4!pvywKSee%9hA#}DKwLDb`nU+4;~9ahLgtzr5Cijc z(~3MGLHyMxRH4Tj1_LJJJqrOZpK3X`W931X5=5pA&htMw5&e6)i-^5yvKSC33Z}T3 zmYA%W13r<|+$}g$2FmKNUGH+jEt0OGHP$m<#fu^RsuV^iQ{wuW^p%wZ4b$u#JmkPm ztdph$xAK+dcpADsnGD2Sea%Ccc2>8;jyP9&!GQ895$g#KU@=+C42FxkYEqBDGd-jU0F;RV4LP){SZrUM zXnX@xKPV@x*Dytl0D$ll4(u&wMkQeV^1z~sDgo$SI43~#;dgd6R)S}UdH*^l$yx*& zUjgVS?U5{WxSy0@NV_1z&c`oQz?=+rdWMtlCw1bPk>*(u%IoKbqVh~LxkQl^AU*j) zd;r<#47;dG*6~XyQ(&JI20WB0jJ|k`+cXg!sxCvMsFsjSIKZzFC5fJj^!8&}hoqrS z%nmHKKy5gj$W=k_8^BsmLu#bf+b!)WU@JU4-70PHH^pGcUuAgu3UR@*_g4>)M5O86 z^l%b}02<9CFO}zcO(y>%>=Ej6EZ@+%t0kF9z<&OAq({)uz5+9q5dt6+T#^0+AZe7) z-o1cjfDs+{Tn+%&4cMF5<~c|XNB|&h9~K&<)&0gLSH}dYxrvBkM_<_SK`h^fKNs_M zfz+T7Ewa!n8DvF%MY_{5rW&%u%HpoLVj5`P24}tHI$Q z6%gZk{XL_!K`Z!Mv~se~G_mQSx^kfQPT?92q;~!jVP2y7Q`W;3_o`BNV`Nd~}t@S!y>o4g} z%nSAd>b}e@c;XhT6KyvqZ7>fy%SqHF4iJ-p_JgkmAJ0PO;s;8T$9Ek)R&7*)proVQ zp-QzUUIxmK@917FtBqgKsgV1p)+@V4j##cR0U7S1N%Qr?gTUr2@*`8T46;Og3IL9f zi!R4>)3kAD-H*J&&8C&QZu*V#hd*_Rwty!-1|7fg>%ZSO@&Ni9dJVAH5oQrKt#q79 z7I0b=10US%*o#XTQ|hDReix0uo7+>(q5@xHFYp}uH>U5WsnW-A3P>!ipI|wcE-192 zH;VYLdd0fP1YQhu7z0EH98@&aHJVyQToZMDo*K0}+X;geu+)Q;Kan(H^hXq&7_y>J zq3;tp@0v3}Y+ZrI06p0mfb8ZXhbQ+RmlrsWTzw__Y8a4Zl92}qx`QA+!TK?poIMUT zVIpO)M6oizXqHAU)#8w6U%gJJg)0o9*(S~<1Hf56X+bKSIp*XW&RZg7v`P#-V;k)3 z6Q#-Lm6Qqudq1GRpajk;TJ|V9zz71d3@%P$*J97TqYOBO=w6ZbRac!=nEy@)uQZIc48xm9{;sNoH1J;kb zHmc7RmICnIRoQXJ?I6#!GSydHCv9vJd0$A`rxii!&kvpUtYY7CC@aLUHFv|nijQA* z0B)yxJQ_E!x(jT^r`wsK{>d4~!vFWLT>Qs3;{lgGE+zeeZDd2+E(o$to?gb`QZl&! zTZwXPX?cjkF&2+w!I?54T@S9Pl1spP$9a%ID+hCXs`|(ZQChZO@!U!q$$NX>Jhmw+ zf+LW5y_}S5564_cyjCA|l^2#YxAvDhA*DYGbaTV>=v?Trybfe>k=FLOWK= zUh`-dKsbOC*?Z^)SXEF=?0~UGs|$FkvO$=*O0!)HO zH#*<6b@78R%q6;i=qnpMxVMo$K4~{lVy^|99IL%Q;k;)-td>QI2`idC(Dkc<`2;Y6 z5b>uZlJW!ng-daLAdOY|j4nSaNvs{(6EM(83SuV%AQ=Is&N5E)5v@_CF)XMs3v! zhJ3mVdLExB>e>vjZka$+F8sxJi?pIWT^5Plkh1~f;m!a8F3|6wpXyGtdjh;1c>MCB zO4zcE$u2n@{aqLXdc(Z02vwF7G(ufW#WBxF9=GRhAt+}M2qw}$H#=ah*)5UyTR6ps zyL1}!z8oxEaN{=Rgx7y@gf_eGt99N3FVw^3h(Jw8NA_jW?~mTT0aAs*Vk_Iwp^O+( z=8%&qi0^m6>M5V)f*VFrukp_Q+Ov0yl)nQ>^dJ6HOzP*18pb_}WBXCaf7339X|DWU z`%uO0f9^He{oP6Te|L}RKi;VRj|Bg_^%(>1`oFyp_aAqR|5xklAO_r%m4F>!tc+0q zGPJp$Vc*}i+>zk_{Fbblzj$sWlj|>!{b(Q;`0%~^^TxKg62K#-4VwRZSi%C`pvUo4 zw)?+#4e-CWYLvqQXb}MZJkjk1nfK;H3-dfLL26*v>Ni$eaS^dS8WmkL0BOSWt__;O zgHv12`<>;J7|OJ${@2k&^Y)*%pZAD!Ga?BLFydP|ON*YypKNCWZro@QKa-J;FE!&S zv?q+kxz-tCD}BzRA`)L$LTx|3Ldag{H&li!=sU@(}KtR^f+(_rZL zuWJRU)5*8`HP&wRM`_=2T${-9+{5J`_5qjHGzTCX0@RzD9#hZF$72W#m;rFJY&cBM z)L63BC;I@W_Qyj%7w$N`J88i%TXFC+f|H?6As2d*b*4bT48i5(RY-f0_Nk;FHP&fW%?5S~CY!-aXfoSK>K?jDQhq$6=- zIA6GM?aaoLcQ&<>`0Igj>6h?#GeZMGCSY^V(d+keKE}TWB(GziKIyC3Q%~IUeP{7@ zft%U?)BF@za2&V2K0YVnj3Gr$_YflV2j@jjI#}j}sjSa3Rdrt+gID4W14n+1I!Pqg zM#Jg-Ya5LRkGM@S&Y>^*UaqK>tQ>^Dr~spd1EUMJzZ8J+jOP0lEe2E zQ6z^v^ziHsw70!53nMlp@iHO@`MuK`EMH+f0a2BPhVj3Ow$S-rhMYf=^vX?qAN6MI zr@6iH9oqer*n10!hd>#GHRfc?*`1H%UwnEU&PC~3T94~B_iA_>pW(&UrKz@(__Y-J zzSX)V)sjxy%k@yRky+C1WkzxASDz znnDK2MwC}rtUgHO?gC|`k0=ozThdfDXAz$@IDSh;-rR8*BYY?Rmm;;4{EOY<;A%fj zeeQY8jL3_UEBhKHFU{m0y`7RF0dSAbb zmkz+ggGYthSyij`okg7NXH>Jsos7dyo*BBhvf9FkbClSL%r&#$&Wa}x+=oFaLY|CY zHfu(xr76rfqgY4%Q9UiUetYJwG8^@Pu>Duorj17cb=|im$Z1*TxiboLzWR>mUOpir zU}1o!x5g-(FAFO0tY5B^BM3?Hg%>Afr1W)i;o0N~cLX%m8Ana&l!sHP>6B>V!r1-; zsB6_pLSL%_=FKMYizMDh56xwqi!*Q17C2%oA63M6^Eqt$SQze(nV1{qSQu(A*6v@g zPZ5)C(&%MlyiGv#KPk5jxc(nAtHj?Jg(EM3>Gni~I%FzGFQ zcY)N6QsXc+o+zw6!Z;4^wT`0?HM4@o=flW{GmjTJ82BL`-RS+74~H?qh6_!QiCbI5zsH_*5a>@VO6yMf_^k}7)$i?SeM0NFusyb7rb~3KbxNw6lTKJX&P;YVyDMc0r6jn|XOe&HLZR%RU~D zw|3p~WW-zkx|Ht$ZJQY5o13j^4l&M^fS{Endv}Nv@VOMG>0!^YeE9Z`VCO1xm&$Fu z=gg058dAi((USN+VwW$a+WP%1DS4BDYY`~({^0bv3?#~KFehaQ#hWj6*)($ksOehS zY>h7;>A+Qb$ln`ykv9&f5`Zblw}z_TANVP+1VCr0G3qH;Th!We@?JU+i14ATaU@@tbMw#>1BXG{3*xZ3$QRqJ~}$>z^+jYi?KooB17dXd29}unbs;RJag;YMe%jw zP!lG(mvB+^)j-Ad@Vwn{y^j9UG(jRV5A&FHJ^N;gbFE0AEh3j&&?Hp5zLLY-a1)^r z`k>yFdsF1rUKGNCWPWzv&TwHFnwL?u#W*p9>{*rY7I}i5E4#nUPrXL9B?^?TE}h^Z zCvv_SW*ipf)2?<)!`wQeeC39huZ9-zCUgpyPXDkd__{d$Hi0R;vO0=MYur;aY5eVe zn@!2!d|qDP1V{s#v%RIY)L5jf^+PM4Z#yEFlh|~=eo2?`otuA_@M%pbY~@*%bK%Os zT#%f@*U;Vdx^0VuF~RZt;PL6$gt3cpbMY9qZ;g>{7bQyOw-+^Pl-Krrrx{j1=%3aY zoOH`Mnk^>xWr{UwMelRBalTv0)F^P;%eP(s3C{RjrrZ-z3EyX4?g&ZZrQ=GNkA~g0 z{49~1Rad6MSOZ)a5;($&40#>bKyszBN21gW(aJf?KVwYm1>$KX=`q)4-74xc>P@Fk zT6XS*m&x79AFdKJG+!!8C$lEMg1@tEc({0fGSSD+@LQ+Zo6n3xmIB&ez&?469`DmF zY`LpY_3dXM^Pe0&Qqs^ZR$*>m_DMwO!17+o-mMnD2QgalizDCs!EKsenvfut^(0@) zdq7UnSr8ReE)X26jt`0LXMe_P@Hg(L8aoGJ-2UE3u*^z76vO{|4feB=1uX29hN*Yv z^`21Pe2UZ$YqZI0ZHkN!hU|?w0y4%TAds2c|4lcU@&5B&3$JAU!Fam6LZ(Q{E$@H( zXvf+=DU(O?!+*Y{;VK7^`T;!EfAga4KOcPZcKz?~j5zQ9_3!VDkox@LpPNeQ|Gy7F z*sN2(CJ&tzAVLOKyU#g*1#`@sLdS*7)Gw-cCC?8qbt_wL9OR}`ga%fzyuD1_d1?e! zDE>P7^fn9x~7=^JxqkNqk*MEE9 zh$4=r&X3T@>M4#Q`z}DG(^IeGw^$~*3=fmMXx@DO37xQ+DVHq%YhgvZn~kAMJ0!j~ z;yA$v>~u29<+Eeje70KXmMt0uJsnnd(M>- z4(YqZg_42YY#Kv!R(xRf`SpHMS#8e;3m(sEqrMC3l>NwsUT1R7%$9O#aw|C*>sB%$ z>fHv+20-E`*GBOkPldc=^7gw_?o*bWxvM$X-(gkn|4Zz88+7>vU6lKdvje$pe%fPzQ%@0S?JTeuQKM#b(*xg)}!Zdu{E59-P!wwq?7J&RafO#HaDH*%lp zYJ42D+$LEX_8cI)$R~Kk!~Ugs3iSyMS8FPMK5hPbF??===WnZ~kZS&yvEKi9|M7n$ z5c^-ii~oOi3R32V5BN@m>3IJ`2Nc(^~BTpgS*~koU#H!f-9yBX%&S%0i7^?Po1bOQ&odzRsJ!yoJ|Q;NBP) z8;K~Zu;hVs>vn98RWkr@UctK^>#cB+@%pv#M6+?U<2k=*V~<61dvCqv(;89&DkgOX zlSlZ@d&^ao%6@Cgo1tcPKb8LFZp_UpN|QxruLAMRny3q~1_1b1AQr}JmR07p@$7&D z-R-_|R6sV)l-II@w(;ryPqConA8#=KkQCA50jz?Cn{x*0%qn1Qwl)=)Rjn z@e{f*qD%;b!eoT{Px)EwSLP&bGsL_Z>45?{dW)u6c^LQN$qTUK=^5yQ<5 zw@)`8LiW^#eJFDqVc@XdD}J{mr^f#a5@aM|)iFHjZL8-UPy5xGi>=I~ya1J;9(dEx zI~bwCs(N8Za(yVBlBtz4bai!4!)j)vO#euKJVoLRE%+jHV&hSNVKKw=qs=(Lk^ub5 zKP*Z4cA~N6yS;hjw$jp?K}4-_jrKz0nnrO=`|m;bN3V9r8aIR^d^wkM`kIySbqbit z1W)?v4?d1Ujeg{cz-yr@zy5)|?%Wx)u_UM9C2<4q7w+8`OPz|+Ib%=k`}mFL5fdZp zqQwIp{l=np+KItdHrp4+-j0~B$c+3#=kj3cqL0~-%|jN|xBYN#_R7^S9z5$NE=$6G zVeD;A_J?v*8|o|H@psX~y9v?5xHx)zG;r+l#46yY?D{+tb1cH?yTg8Ll@#!YH7c=Ed$6?8ys;XBl+8&66eE>ol8zGch7a~PIeLB ztQ@`02%axHGT!c2a9ud`efK=xbY$Eg#Q@Y|nOPDingR+)-4Eomf|tF91C;^yLvL|xbHnyr~dUT#goCM^7B(jLVa z1GmIfs6H~$P2uXtpzq1!t?DT!<52U$B^#B}!AgF*T;6=8a6Pyj12bN68Yk4A5znRw9+8CMuH`LQ+vlo5aMlv|@lF z$!lVo5-8qKK@d2vo-^yL^ZA^$&iD7j`#yW`|MP!;&)yFlGsE`yqV5&y1rkGAznAUi zovcbcyVRa7yMyO;If+X*8b5I9_6dwRWqJgeFMudZ{oMe!^c^os+rQ*iy3@>MihZa3 zas357E!Xc_9O6~-Ni|gyp^0|acgtEs{oRoc=lWAU!`!OZTAvsC0QC=;X+G8Js_y$2 zNRH#MAMFbGcgJ)-Qb;aAWV#{ul?t?|6UQdd_f_kLkCwy%^JJe{pW6zP>?bE|$I+qo z?_BMsA$8vrm;r1H#@8XgRHN7f*|u;Xf3Ev_rT{)R(}@z#KMNR|EcdDB@0ohp3x27S zQ`k{ts)l?PqqNFhIGv~xc#E%7(91NFY5-j6z-ns&h-6ila7fMUYf)r|(XMD~#LJzh zPB)|k>&^yT5mm=0Bs{chi=@p;d-_|dyGEyUjKc|wg2t4tXi3wWRw9f3BS8wI2~THq zMM-?CUB;g`B3rEq&p^G5L+Yr$Wma2wU(52PjNth`G+nE)tzusHK#=V-bJ=Yi)kv{+I!HU|mWVs6ZVe#xHz7S{@WKL4FHFko$JY# zjk4!m$hy^9GUX&BsKwY$(vOFu$20KU=wXk(ikKL6#0m*h9)>TBZdd?^ycq~9fH&_y zt!mA7C=or^G~NbE2Sojm{KL&!D)47rh{YJE*?UJg)~5R|s_iq3%*xV9PGsw6qW;^W zh8&yZPRzPw8;0znoAVY~sF$#)n*U^W?fBX7yg{Rr@^7)oTt8+O9`kn~Ey6xjW4dT)=y}vN;uH*&v~y-71?&K{yXnka z8s?B)0VP;O<+&#M?hUhlb!ll~j&FEwDO@b#tRGHqoSl+tFTN#(J+Qe8KjnuMy1|x= zn3ppY8RPh42tH%ZoA#5N0VKjy`jDgh}MG+6Ivt<@d61QS2`_s_xPr%r*hTcAsXq$xFO7kSW zPL+S>n^oyJ*WUG}qtN|dc^>;|BS-%5mRyz#%nn`~#`r63lY06S(8j6Sx?7MX*K{(q&t1p?Ry#_jeW*_SX>fZ*yBCarS@I;*^dyNeLL3KNKi?q42oN%b7)k^L&(a3(1$uQc#?2-Bf&mG5e-v;s_ z4j`EY#l}V8dnfw=I|Lh#*CNzTRH1i`HnC;pWOhc}0dxJ-@)lpLbky|b(BqsntcIHk z!LG=vQ2&ZTVR1y7DAa6e1*>Pu+2+fJgh|heCRKY4d=oV3Gi~QP+ zYA7&927_SQ*sN&q^L9sSq>!5h9PuEG%ZSVhJo@m$zC`dX(apD*BS@nHaaF4&dK=Hi zY;haN@9dJ%`<~-oqs1nMU;o5&rDh|DDsQ|D0)w!m?XQ!a%gw(?VZKQ^Exx6YigFhYGp-iG2+&;ZFWnVV~ zr(sc_oFLEIIg&O^2xK&;8_ZZz6hDL)HY#E$G}dQDVyQmJ10EKG(PT34%Be{;ry=l~ z_Qe3VVo&5P@soA)3&8UY;={=HFJ;*>%NY}j{nIRX!f1IWUqfvduLvK01WNK1JXiik zd4sZM@|Q)@)Z+DfE3H6DTQ08Wr8sSKcqp2y53jAlVqAAxNAG>Z$cH=9e~B50Doe8e zI$_I3JLev~y+*2DjBCI&S*;Xb+(N3kfnuMb#ftnfbzZzU?zO^^L*%@^yt3xtXn&=@ zf0Y1wDZ+^aqSoY|2)Uc)b7Sfw_xy0`^yt!q{noEw>(4-W<3fZiTuLCNjj@ zzdpHhAwk!$Zut$>Q@m6HC#0qvLTJro>zfMN^-CwRyt~>jY_eqF1eGOmI5r8@a8QhE zh?_2Q8^lUhtW{Tzq(1UYw-QqX*)LXN8ZWV1<{3g2G}?0P-`sfBX1QOXeQdI;hq*_b z1}mOG_m9_`>EKqj#$hokpMJg)nX7OnOs&}MyzCRB$Zi9#^>D*V){5`qXZZ0*pN}9% z2bWu&gEcu?iDavE8{Uq)QoQJlmoStv@!CcRN#DpDGx%N_o4S^V`k<=upbwCT98{F9 z7MK>h#)p1Sv?P^R4qPiy8>JnXIf|AlH2uY7^~>o}lq2|CD(sO}+uF8+$Gr$ar_`I$ zwt7dT@$ZRPWyG!Ip|1>Y23y z3>tr$mrs_5R%y8pC~j>zUY}xP%Pshuc_apw_7;v7u+8Xs(0cQyqEso+{iR(JF&NNK;HOa znGii_*N5v0B|_>pkV-Ch+SRCVwAI91{RBz;7HG9_HexGi_B#r-?6c;z^j;EY?~mVt z0v%hsJJ2Inflk`_hhwRnqaG_`0~LW8K~ZTUO{rF-2uP7m5D*bUkzPZ_aX=9P0Ra&RBE5u2 z7f3)wK&3=V5?Y85Admo&5&{WHz8x6PIdf(_&-2&!z2Ezr`{y4axwG%R*IwmX*Ip|| zT{FD0bK9Y98#Zj%sjG9zWW$CZ&>J>)fgfdrLye?&zta;f^DN zg;Pa^&z8)Fl#~#G31&I(y$54UCi@Z!*)cD49_AcR_`Lt!O#83jUwyD4s_o}bl|gW2$}{5#h}zFU9!OGe+9@7G@blKpaI)B2lN9GbSTzlwbu zDYX9TaC0Kp`1i z#`)a#@*;%NF*W0@4hZ92?F#9?1xF^H!rs|4ad2>JisHH$UK{^!1ro7S?#boTsZU&= zB|$dd*xsX<>T+iD!VXCX#E8V&;MzxnPGUAp??`q&ad?+S$iZJ^o;sh|`o}x&{8PRW z3g~Nskq*ay{D;|J-+CszscqcH6^qaqsDh@fhBrEvJ>;8hLnl zxOsS7zj*Opm}cgXXU&oL2MCSOJRnh5SJ%R6+CZnRYzhRsO-%UUc#J*9M?!bZU0yMFkdN~4+b=iuh{L`OnV zOAFQ2WvmfAFA=A;G67efs10iO9a%sJ(jlAfy;;QGB9qBLx#CCXf<)o-9X$7T-?@Np zb&IC(H-@P$SGf_cXtK3hJL=@A@Uo3j&DU9F5^;BAUfD0`-*mlw*~+Iq1=g;Wyy zs1}*-mO-h?v}tc2zZYDpi93UpO@a2%JD@R-9__0dX;!z$bW5i^0Y*a|PqFW;D}}L_ zTpb-R*oUt;cL{H5_hl4L1dARx@SYVNMXV2`eHm$DjYi7>fo1ycOmjdK8|6+|4RG0; z)LaoF^&`#)B8P)1BAdSdPDV!NgQ9_fkx_9&17zdIjbP7vKO{;rTD7>w(b3VHsuDls z9Fvq(l9$h_tvxFvC)Wn_rLa)<{w@&{C#P(_RKS~1Kfg+M+FJo2h;F%ew-t+4R)VXl zt36i;A?l(y9PY%S7`LDx%f!S)u;v5;?YfIg{w`7Vg2>3t81`&Ei$jN_ZYw^ks;I2Y zxi27g3nncXJzkaUJ}@w_I9pHuI1?asco%IL6Z$M8Bgx@_+wI%eEG#VW@V?VEN!L3T zY^T@6W(dUg;id@zWlwrZA`tSy=s>Oa`#V7xew#nK8zOfGWB;;eqQ6WS61p^P3^spH)Nh)+)rG~_aEU!#LiS-< z0-DR`?w&gb#Jq_ourl73QW3s7)sufnR21J|;ezYyE4a5spj7xX(pD(^l!8Jws)41a zprBxFYikB%9llhN>9Im+A$zCh6>bp_Em4~Z2@A8`yLT^tGQbb)I(+82u!`r+8EF|A z4_4FlEMSnsAvBpgw-#%f$t_1jc-uTyaf} zMV_l*rS5BW3zS>BOI&OA-MioEb^}fI8~>QJ=me%0vNWB_pL`)uF|fP%&!2BVpn5XV~r;G8ai9_2SXW;^9#Bt!8Js%M3%0q^i=?TfqT&_ui0`QSE3RzWb@&>v zIaM{a>mYJ{Qf+ha^fVL~7r#6s3%s3_lvEvXBAuZ-9>v8$-Q4uLsk0$xXNdI{z$ZM^ z&Sp)ddCk|+y9ZE7PY3l1@xijr6Ut5M3fPE&k8~^sgYl^+>K#kG>@j*8+wPmCmqBT1 z(bg??3CvZl$Ln!6+&Z9**M}&-<$vR(Gh%RXu!m{>aVdH%NFC9zU&pOs+Z*svK=BxG zROv2P5F=ociJIf52s>3w#RBVzZeCtB<1OhY3Ta{X=<2{?fDMk^Y^oz$C+DWA zcnPiwCuW@V-*_&i7|re|^fCca`D5@2XXSPo(kc(-e(5lay2f9)I${ z4!3{+WjgsZHub4XsF_>i4av?5aTPRv*jARHQVD!UbMs}esZu}wqpx~od|{<`a8SyX zp^JJ~cOmOB_;>8sF~zfIPoN0J*N*3~SRt5&PBm7O8234F)D{qwMIe3ny2Kv7-GQ4y z9IAZz@;SYcr%5bEp$NdrfOaTpXk;`PX9E8NgJA+@29g-Z5}`*EbyM@K$^t2Uh9+vC zgo$S=^76FVOEabyFJ5d>>)ppT3;^ii&5di_)G1=5LqTz|KCpkET3cY2z01o%c&;I0 z(DrK26SLaDw0=XM4&M_BH3uhBgNIM9gu%m&fBNy7zJ7GhsI1FPL@EUdgc=tcTLfIF zhK2@kL-;zeA5Bzj!k4D4&I?1@6&BFf!4Ph@_C#IkMA@+|fBNx#Xj63XEkwXUX?0UKUj}|+X_hFJiOr9XkN2nNSd{t$6N0g4 zYU)Cno-8L7ui;)JILmZ}6P}?FYF=h}wUNi6D}?VQl1M0ExguxooC6Njh)2#xp^Q9h zY=F;ZtuA0I5UhrNYnir_)ME{Xd$&b&H%1LimZzNi>AA{qkT}^X+1WKH=+);?SDjQ+ zPQr&A&E?Pc7FEzyoccgIm5M7q2yayj_Vjf~w(w9~cRDT;!BS&v&dTLNQnEI{EnM$b zU;;J{6~PU`3wZ;BgCJJtF-dUy8ZQ!lbo2#4GAtGgXhpG(#EVAGjMpZS6uwyAYA>V@ zJVq84#$zdMA;~iX3Q5~)FY!Opugdr;F)4pmnzNPg>{9+P?0FwFo)g{}zDgEz36oB} zO8uB5RR`yVH{<#GAurKQjir71^qB7kft2hT!h(sspN24@7626(8yLj=`sR6Fe*RJ9 z>;?T|6?z-vqHCFp=!}HFzrSku>Z=?auZ+K$cx-el`H+|x;qBXB0sI2)xvs8m-;T|E zzm=DF%34WvRwt^>Vge_kK-V$imwulSV*;#zn#rtCc^$MQLABK*k zbxhPgNgdp=(5^lxL!x8lz-?0s4#1Uf8+c{lfJk+zA6LN61=$M8L3;0Q+_Lyl3N?8} zi)GwG26|iVRp_^ zIuC3T-%Eo%)IzBG2LZGiGCvjtpu~1aqQilyngC)H8iF#+P(2ECwYIi)@dQThkcbHG z)2B~$UJ`^-yB@H7KLE;r7pDQtBRe^;Ql-KwMj~+_a4N`R4jwwxUFOuv2XQl`Mtdfm zWRzK2mq<}g$xv@I316`N*zUn!)65e(lj07-Lyy*B^`I}$3&;vU3>n)}DO_&2h-R3j zY>NK&?c0GhKOxaA`1Uj1pZ)CFA=pBP%BIGPPTLl2RVRWMf+5z{-Q?CdTu)DSiha11 zudnZvirt-h;-LcvbV#8(tdTwM!%hL`Us&A(oOp)I70;mD$d+**fEd%^@`a6yy@ofl z%+1aDknd&~A7%1gF$hTsA8xjg$E__&0~2+KPd$T!&r-^=y9xm8R*3YweOm{FOmpC` z!sin+ZwCik0fPiVusc!GXntTku+~;>DZ~RrUDJHS6F>grwu8g@OgJ~VvvDwHHqo2X zDFVa?9H0@1tunWP<521D@9!^RrXD(v`7$IOmiQLUKYl2g4GvWSAa3=48;7nY0 zs>4`{oVcanuAif-VtpdjDDDwivr`AmKw1K#SZ-&hAz$(!8G&;bGNbF@QKkU$WvKe=fjrO}0>L*& z3+XpZz-HP@V8!^364;frn9d{m8r9VuLl;hlA@oygJJvLJdYQ{lr4B}B1*w;U`0;|k z2Q0ZK{SawsX+4eKVHw)MQno+K%(MXT1VH(Dgf|Fuve(NBiQs7&_Rtmyu+pM7^tGve< zV4D$|NBy${J9IRvm(mXSMmzq~U8cM(rDF>NT@H(i%CdT4QNhViDJJ_Auu%Ae{>hs0 z!q#oIE2qHLuHBdH?A#t;WE7W!J18}l@jcMX;9@gJzFzXNigcSE>5DXDR#$GI!Ufzz zy3x-OECdnGkjH}#CP4`1Pt(({dZG8Rm$D7X0riYdHF`mI_C-Fr44QLni47^+(ew#; zX9?u&Gog^8+tiv0J3G6BDl%6Ki;MYrZcclTZR%hK@=364z(jRjq-Rl&@iDu(3m55^@G>yxPj80eS?vs*5^)co;E!<`o}_pfrG9hp)8RQ&SpO z$LreMLH5lD`7XB5G{*yxA)%p+0Vqn>TI2d$v*{guD~sG|V!aB5RWu^d_Qrv2V|HT!2)uw46!T{oQHt~kMG~PV+S8wfi$cLY*Aof z4cNiHK1)2QJ+GAA*+QP11YDMC$YQ|+g;E6|=cOZAAb9ZEh?oIEAtC>jd1o8K^%Ggw zbb!0p;WdT3y6S?61BekmdjoXnj@P2_>zk)f^eDD1%^r?)m;|zS#0DWIBaf`b z6(@_>=&cNZL>C8)ai7{sC_xsa=O4 z0M@`f_&UKuV7$pKb&Xpl&hA~XWf78rM+H963&ThT;8h9GIRGgDEDv;1w^%C$HrFg< zB{#B`TI9k#jxx7{z0bP#zE&6l@-auCPe4(CA5GTuP>a`@d~oBS&6Bf9}H zRSa@?fJEHf-P?oI0pkE-CxEipmFgOsvQng?re-PNr8a$k*Pj5rl5I=`h)%_GsPCnN z6~0=v%3JMWvm;=F%%D&xzTeu?@)Odgrra}N9O~|V6%K4-kwrs+g(*uOjc?_Xix?3zCwdBLZ0d zsyh=Hu`;%0^Y#HvsgBV^Bh3$N-9{832IWK-%u?d>Po3p2VJN(R%=;Z7(A-w+FmcS7Yr! z?Q1LF*6_2BCLn0^LMRxdHNo7<%Id^qMlW6uGk#JzLl6WA=~cb zUF}nvN*R^M4hk&Ts!!D3iPyQ=R8t_gf9T0YDZ4qM?Qj(AiUpNZCllN8ego z=X!{6pIiIsf8&4+->PTtISlxSb;7$Z_5ULxIM)sP#i!PsNgeVGjIbEJ8g=PH0t}0C zw%Yc?_tljWY#w)pyU^{cjU|8J%5-;HB|miu8K08JE~fW7A*Rk2wyO8|n#2X?Swumk z1uM#7LoZ88#8Pt71=iQKVepsunR~X~|5*R?FS&j|ZLfcNW}7f%{nec(MZ_%r2cdT>9VWd5y1!3-9y5O2ML%Airk!b5{A>(N`LO z{Y6r-i)C^Wt?ciq|1EXC7XGgl#$Vta*?Z@%U2ZpTUIOG8AQcnFd};yfyMJ4R;;B1V}Lq#6f*!vv*Yn@?aNjc~VPJ|dq=oX9%VAzbfIT#nGTlT=pktb-iS0qLodvhv3n zh+W{3_)j3sD79}a?dlr+`uv9{Jez2M%Si-mL{;Tjmshy2d7PMvN6?eu;g_1+W%Mfd z6^J$d6YZ&J^Ay$CEBdNw%Q4SNT7|>IEitO}6-)1x3Q!y*irxhl6+qxT)z;SbX<$20&v5Yhm&GVL^MQwaGe5n5FCcu2!)Zpb-^Ys| z5*`d98iEtfsXv^4@<%QzPw{Png6uv)QPq0c%H%|$LX!zHCbs8hj36xiSPT%Oyh|Wv zxk?x*yuLGorky)c05f!fe)@~eGPtTUcc)w5@0E#_ze^(yu?J>Zz< zKTljmF-6k{L9zq;3_wJg#FQ9st|?*H7dnp{B~ggMXwb+;nVLxwumil-gxG~B3Q2*> zZW7S9VM=DYqdnJW;J%%=0#HMSHT!OQ{`rHEKkF71p5RL7KYR8rFEdfq&_wC7n54t% zm#QhqRu`9}d(u$UXc61zRaeQBb1ZPx;5Un|?wc2!pFAQ6i zaN|Yq%?yDl^Ex0re}P?|4PPg3bXEnudGluA4#4gegoJK~>%VVku)@r>>;?I+_?6hP zRdla6u*QAnUT<1cuV*4&k#vBP2#d&2k&m!9}G0Z=pf`OUqA zoH#8_6pM9xxGOTU0GQ#g5>wzbZa&BdayHdFeE|`-|2k~A(BiGc*IIzqs6#vJKChf1 zpE-zGpzM#CXq*LX_;#Ur8Ihz4M!TXxYM$f3{V>TH5#W=Y@#0rNVj)oz>Q4j!2e4{~05g>+*^C@4d{}$<$v@5R>kBWnMP(wu zMYgQZ_XPZA29$`kzE>m-A5FcBD%+{W`;>KYQ|8Z%QSX)nNyQ1xvJpZrIPz^zRajxP zv?way;?=De5WK{U!4iusAiGyJn-|H!E2%jp4-B~crS>M86PX4Qa;;%r}K4nlR z!oNUa12~@L6Feo0rw_ONb!me}+)ilWgF9zzr;eU^_E!ZJklGMXAMty|#$y81p@2USSbx^w_W$}NO!bCb-S&1#% z^J;i)4=ky&7{uk%pt=)$9=F4PcoW+a*ZT+2J-2b;pW3HPDV6E~L zm6WbeIiE@XhBb={<4tyV-LCA`zoS^6Y5(VN?!zcr+VOj`_ETDsMpGM&VIHzI_SRo5 z9wcZER_6FE-0>RTE#2;hVPf^+-_yXCP4`BOb-T5A)XYcjabD31=wA(D=7WZw*<1GN zDVk4>KZ$8O)!Tjev4lq2Rw=@SQ*JK{R#eP@I(S=2sZAnW@3w5l^#)bGd{y%Pqh4-` zsWDo)qEXrAo`If(Oh;#jg<~+^tNdc{q;dqD$TGUQ4KEr3yj`s>iW^DjdWq63UKXB* zD{WCyS2q5bQ1p;slg)&O*(NNC!Iy2zEYY7M+s3;QpJZpKx06V8Q&4==>t`tt*{U~C zBEREeJ}JatC!>lbCe&cf3@RwTcsDOnNYm|vsL|~c;61vr(E1%uK4{WK}OYH z)1IlFa{Kb}^q#4j*b|?g*3R|fhKnw;Ll$vKbfvROre>k`UNzsxFzVP}yzw!`#QFhT zO}!L_V3V91FPT_(I>@HW!|&FoIEdIa-MR&YGN^|bG$u0~TfR;c*bkRAd zd&$Y-r?+@PLjoWS|L~oMhx0qD1vA3P`#E!Rqo%?6PT=>T7lsXx&oqc zdFHv+jYcBKj%~_H1^M-+{{B^UU&cw*9plfc!ZQz1-L9J^hAxW5Jc7EZmQ3|iHGS_B zDEL%FM$dAO3)Ri*dZ0^M%dxzZ7yxSkAUbr^Bk1U!t#*wIKhd0ES+c=U^=Bc9-`y@zj`9ZBt_z&Yj%(fSEF?>|0lSe_`-JmY@>sL#&B1Nr(SJGlblAn|A>p|~vS z#AS2khCssTe7Pq{48oiv#2)T`gVAu?sa#lJVUSHW+HQUE=-Ki1V~|W6+6Y+^%m)WP zcV8<-e63s|<7v%1QZtwf1c7709yXIhSneFo^SnHB`0MGdGs$hvx1EpX1s(Z0ZV=jzzTL!-fx4RsAr|3{KLKP*SUTOo+*+(cEyo*Ybh15-MNq>#9h7IU4mY z&z^RAM^%kdaaO5$S&%LE)>~`ahhuENn^h{6`U#6cen&9t0%HhP;<(jq0HF7&Ex)uvOQ)-bbL=AVhO;U|^rS+qIX4#(!U3!q)Arw9|`#;?^&l4!LMHpLD~Tu7qO6hxy>B6N<&E4l~6Camqt zP#uMZCpy~OCu1xiCN4J7KzFLHy|wbL#s3Gb^RQw@868rm=D#|rKVMoqChclf=S|7- z9O8`3mrO1M?o?+?lr0)mfs&+HhS-x&Vd#Sk;0&l(=oo=`LI{Efos z2vpgJu(zy1G+awz3Cv!1f)VRl9p_#Fdnr&8z-Nv;>FydRQHf&|m*O+$=CWFi{5YOV zZ5_&{pmc(y53A95R@fe)Mgd7qlPD^U;ZJs5SzRFYMMf}>)5!}%> zTN(hiJ$@11I6wa#W`6$eA{^V^IR)p9@scI@pQNiG?bW=T5F?!%Hx3mq%pfiIY_;`DJA# z_7!%J%r0sAY3q+r1zcK?D)Lk5F2?Na$EP(HoNeq+{Gt5TE1y}7izLk2iBS7-S-?pe zTs3GrwFCIUqN9B|cbnLiFDr9Kx~A#-2tC9?qTS5144Y5ydMm-XHOpNfvqqbq8Fn#- z;cp$Kt+cvYQgA5liUv`{ZI>dIli140my<=Q*%Tpz8PaL3PJ6+3uPF+qkSNzfq1S-B zQN_crMP`+xFsgn?^P_e+`PAEO!^+*heG@o)TV%&~Gh6*X(3ye^btNTyzRIRslya}| zOHST0vX{;5DHhMmH0e80y%X)di;o=V-jb9~H#;Ag*Mf6Z>ZQvqw=6ADKQ}a>C!9SU zjBCVp6xY<70%z8eY3SnqTpecJchog&c2`85s-nCS@`H=Qe2Ck=0bCYKwQ)Fj;kw3w zkQ^S@zO$gA)G+YAC^)q)I{T@BFGs&XHwRZM5~(h;Yv{IN{XiP73tz-E+Faf_Wj;7v zwG!lKR-^KYWRr!$#&=21hd}+tayM3^HCrKlk1J?ZEAGlAU>N^OrIgC`O6!+|>VYqO z;e&dTTkfL3YhIHi1zjd)c&MULa+td#j9c7ub@jz|HM2XX2DYdDBf$^Yj9Uq+=V}ln zlgF^R?4*T;enzt67PARk_-i1e&^gieX$S4uH-gMa#8=su969}G*z60c;fpV04-e&U ziEF`o{D_(Rs1GE52(F6ctxl*N&CI;M0KSk-P7I;EE8e7eu^5ktFMl#Fvd=VGyjU0_ zhj>#Szl47-;p*ddi|A|npoz^M3u!o^qPbF%V=lXe$r#s=Qy2;E_>F=)NzajZ3LgMUe!c#^MRy+&!sYj8u1^W1r|m!@t7a-ypsvqzO2lY(nQjTFih7{_*m2MmO0=Zhq7QzM1^Prvu#YqxJlSqv6@Ju62q1L@J z7AeC+W&qc963}lVgt3Z)gQeqk#gBvguV&HG5E*TK(+N4ZrSr1lB|}`{nN&AU-8={R z2(Wbkhm^%09w-Ke`6e%NQSH2^ay}^Ut_u&;2@MHw$>_OIOPuY{a*gRg(5jQ4*Qu)c zY7!zEG)>`R0T@kt)k-Z6tCC!mYE3e^$q2UxF0v}zzKibZ%B0=Iq9%Cuj)!PJ;#L0=}XZ$25ug^ z#)fnXPz%L)dWuWOt@Dc2A?6mQ7hx@t7VHK6jhP+4RaK^Qj`cNN1~oOE=>yZUS3itV zU0&I)WOk4jkh3}3*(-LP2i)C04Wa}}*g?{wgsLwZ{2=9SZPfUt*4VPF+hkS*_bY_C(o}TgKkYyg!=5} zQEyQB+H`6xm@6A9_mQ#7)gXqEU{2rb$3i+`wcJWp8jE>GoP{>-YD2pzgJ^laLjV)JVy4`SLYz>ldCa-L+#x!sL!FmNad>~~QHk)@ZmJqp_vEC=At)kKLlC>b zwQGytA7i9xV+Sy2Bulkwa~gsaSaexHENmf7x*73M(wa6%1F&V4JzjpJ{QVIV;i3PRO5_puMm01*!_ARq?uphC9n%^E9fZx+!ip+KD>3Xb!RR&$V}jEZ8Wes$1x0LMwzSc|mOmVJy}o|H zzl8U^{mo#oSmTem?fQi!V=ZYx9}GlOPFt8$(><$9GHEl5tjdL|+9jWn-u|2XY5($( zZ4Ov1L> z8oYI3+xr|`s3+iTicmHhQnyNf30#c6u(xj5J69h{k!>Fy5v$b`tm)QBBb{ zG@<)g=y^F$(b*qz+g+84-|^KUkHBuC-E5wy8C`3M+2;if_^!q@=I9ai63vj?-x)U4|f-j)^D3i%c@b@QXX#jvhZil#ZYR-*t|S% zb)`t|bB0Jou;OXN@R%yAoBODB4;I@nw^Hs^w12)d!O-|)x_N~jT5~4MBM%}8h_SY| zT9W*JzErM307C>i5poL)r&V^@L)}LUrQ1v{+9B)Iw%7N-siKy;QtVtK51I2y$~Q@0 zo;|h3I0WlIKS7~PZ}s0_i2$do-7353+h;y@K|sx3clq0e?ZGvfhFBeIOpS>qmagqN z1Us$^Fm%%3%Wh0>%-fAI{VMxI0>%Tyc`GYJ^iL`J)bLvfq0ZS4frxnkjJHuel=E%M zH0wLsJNK6-2gO1+_m_etXr@8Du^!5PnTRgB6 z)c+UV7ESq4Mp_mMqCY5##BtM^TS4?(1UcfPxZGi-(qiOwfHMxp;Rq`Xd>J>rHDfCl z>UK<8H)H{qGCp_H^X2r+6uvZel;pOs!~uOyxi?Jj0XWzZRD!9p0&qYl!ILO_vOw)@ zRh?_s9`^)2bpPt)a?hd_#0x!;$z|(_kUtM2{8bLoXJ&gFhG)^Nm0?RbvR7@@-@np% zNKum%{4vGZY7;{_t*4h&-r*X*T^cj@tEDtAv^jT-<=eQ-G^WxN;&t+VUpFi~(%CI9 z+L^if2g-lgkbagc3Q4%RYuMZgh8(c|HH6pN%J2&@?@@4Q-mANUR@$bhlq0tj?awo2 z(L}XUdtZ<6(`?$k9xv+L-p451m09*@+;ZrDmAgA?*R)0964_ zdrd=@mvzq*bH^Vb46#L+qXjV7&mA&J0jciyZD!#NcK)0Ki)jAc3W3zj_ zrattzJk)k_+p1hxb@qAaMRC=al4jlBz6TElzW{C!hZ}yuTMEnv6zdC+dG;?p;$~_= zh7z16pxI|N&?-6nxKpnx;oRw3)wVR+3YOFyrmrh)=_H33GXq%`0LQ9BC& ze8WIH)j{&7O|r!lir+ttEwz?XZ!7>vNp;Sx@mGVLs*9^7#g|SO0%E`~@OIARPEZSU zp9i99w%m+`jqgvG6OVO{F>c(xMDQF=y#6j#ohcT>mk_s!%^-Mr?ZargGNe)cwZS0P z`_I3FvOXT}?e@83AGVM&tR8TQpO*Rl7~RTuJ&7L*(aLCZ(g^CM9cilnENrC)s#=M% zc$25Cq}+=fmLQdHdsf(SAkz2_s_(3f&)r-V$Tib3VUZ_f##BK4X|ARo%p(K?5g8yz z# zdK~ngmz@X9iJnBlGkaU<VrZN7K+ZZ49~RS(IZgZ%%So$kh^YGEW*+u%^ZZ}J_TvUv@KV~Cne|0>V@+v z@EY>dm2zo)EP|Byeit~)1qd7kQaalB#!!ATU0p@se|n1|G0u}sQ2Sus*&bj%OK_2I zg+h0MAaNNmH|_!ar@dA-t5QL>;zJZwOH;p~mzJjWGCellz`Y*ffDtUbhLDS(brW1x z)9)3~FVD7>FQ({|KF}8g8J-V*NrZ)Rs`u#XZ;#ebg78~CH~h3+8U46NPqApfFv)t~ zorhmm9dlFoA8hE`@UMQtqJSoTX9?&&NrFT=eWTF9qAEpEySCR;|C^tGZLr+X&zBMe zRr6msL2xEfuK7i-k)xuYu*8_H9zVA>s|~-1i0+8fOW>|p@NV7=P5)O{VKkRNAA4(FQWesI`+R$n@`7-Dn7 z8)>J@!(W;RLo84b94I<^LR&ro==DEv-{)C&8}m4c@RY@- zNQ={{z5JdI4GkIHZAaw_Ni4G%e8JE|-Gn_wUFb3!LX7?GUjGXTy+cDK3ND@R$3N1m zooKOpw-q)v+JoX`&?j2ls=L<7P9vZ|-?U#7xrAm{m%}yEx=x-f7%HRCN(;MIXNh&( zX#3lX?^4e?+2a!S@SjCmC$)CJo^}JF4A7i9Mu`BX>J?NF9ZSA4#6TS zu)}dzKyemmB<*Qw-FlzjDAP=yD{0kbCMWwXsWck*kPYy}!Qurmc*!d*c3q7-OqsDB zfQruHccRJ>c;EG^ui9ml3K5V?zeM`Wa;1X7nTHD&R9;lA#(|QTwaPB8&ezH=QEVMK zCsbcwl}WSrs_Q?hdw0YkgN;LtMU~hylabgw(X~gMQ<56|SKXJ(Ua=3w&FDsa@#PHN zFbUl{7`qy@@Q1ga4K;_LRCwed%#=cg2`CzYEykmxHiJXqHNuk*%UY^|~@+1ZL;-vJslU7yv)?cFx+pVw1I2EQyYJIgQns`t}15Wid! z8e~aKkwek@F`8*1Cu$KS$3G-&Ycy9v``1AcHmHTp-qiqS~D@R++9ra_$1Fna2E_(*TUe#|P-si=P~bi3E~A6~sS zcz8sZ6ur5|dwNhJAbsqN_ff4e%VcMa(w?(ndSj0%vd6pf&WcC(cI}`nFMQX1%=Zjw zfdF4=;-z=>^z=Z@QLY-r(a%lG18|tjLr6Q=emMpsZJ&2 zg9owA;H#sOG{}rIrr}X&%u-;*;(uJva8fz0*37p?pu0`+$fy`(`F?%fn>hG9S&7Gv z7$7pjO>Cz;2CI>?3@MA!k|9cj(Cngj2Mmq8isbjRj~sc?*r?U8(&2^Yq@_SYT*oy{P36_q(Y5TW z2FPJagPx>egob=rNFr^R`Jv7t)Cwh+4atV_`J%pGw=p!`2ezUxp-k;d@1ow4JnFpF zxd8^WYUWvQ#|7ru@UW_?0d_r@3MssNHnh6oQ3&|nhM7{ZHCM!7ilB*N)V8&&pamw( z<=&i*+n!;hoptR&(|rLr7uK0E*lT2EXlU31Jd!!RVn8iKv54v6NMtixBP26zNo{<= z@W&gl1KR~!=taZ6ym|0oIe2bM*^ivSRbs^3b7Rl*--X8{WBk=)h~KBcpSzVsW5h ztl+W{+AK`IC<3b`uXK=2&g~S+79`3mD+|VHELmQ{8(AkPSLeE|~%<`y6#^SS~MlDFlTyuecpvo*?eL{BEkVqY$fa3o91(bN| zN=O3(>D7z{od{2#K7Eks&-I-)gbUwK;b}yUx&zhRT{aJWWLhQ{E5tn}>vuTj!Gp50 zG9@`P9y+V@8GCiwr3`dOo(WsNvt#GZ%PuaIkFexqM>n^Vv0_@HLbA36p_z3UIG57L z86>rgz%+SXfioAHg6V1`4gdZC&PW{rYL5q0?n&{3frZpYcA@iO>*USXd}SqYv+vYI+KkxUW9Y z>#%0ntJ(V8kK;b3vkRAJh*R9*6QJk(-!IH9#x~by%60hl-~Ms`E+RxsnUTAuGj~u2 z*Urx$OKpbmb!hD2-L-b*x<xHo`G33!C6GbH+Jk=y8Cd$wqSn@vvByV-#sM9vf4IOVKhAT_hORdwycWDx zz|6X`_CrAL_itRQdGTp}%}+pov6WvN?{$5q(r7CNWZ|mzwID0 zbi|&^Aa&CSUN?ObLmh4fC?7epnZ>q2CxrdQpyktyMZZ=p4w)oGwSxw|g?fgES3sc; zV`G!xSf9F~(WEicKZ`5HnI2G4jD_XQeTIc9zmx_$u;EpWVaD0OL7E4UcBAu@4D|_Tf0}n$Nq}q}8NTMU}Z_c)yel(TZ|Ela| zA9Y;O;7Zny+2Z359=uXDj?r$q!e8p_klju+_#GB<{FWszYJG+8f;VeA;=zM60b|#8 z2<&`E`!ILLm)lL0E<`@jvzuEbWIlNCAd@?dv$QSoc-7V4e^7k<&4CjF+J(hZM~-MN zPrBPSj^uK|$ghQZz|apfM7)=?Hm0#=b3az$?g|Olc(_Y6uqK=26+a0@ydCHXrN~0o z9Yw>-S+~#EZLDMWN@|sa&b-;ke$jjVkrd$=*~i(D$mp+Ksjp=SLF|nJpKM`^A8~YW zkk6w`IJpNEG#B$la2r#9CpmwPQs+ z@@gt#_cn6oG8&hyi&OaS^OKLwXf7iY*WbTet>sE~O}?5SwCa_Q|LF-7$#OvjZ0(UF zOEbj1A|es5yq)CT^!1IWryqGZiFXkOMN|X@$Ln%cDQPO8 zS4l}j*tDl25cev>hOGuVCI9HE^9kk{8I>;sHKAA3=fPhS7j(YH{Ww&dh~# zTF=+~YV+q%;)#(_`Z7=f4V@mW(l`nB&t%+s-?oUpS`TUM`}aq??hCZE580-lwcuGC zX3h-n4h`^({!p0u%B)rppxEO4vO0aBX$nRyH{kX|mX;3`D6-9q)3$#5qszRQOF-FL z7O?8Oc`NpfF;o4uO2oPNq@EjMnT`7rO%=*sT1F#gP27crV`rSiy~jS?Gd_L^&3wbk zB20d{rXD)2;};Nc$v@6PoEvt`C^@Y?_c$g`cg-$M6nJrYHj0$*VKFZA<_a|;yqQ^)!tll{s z{^dqGYcfn4?*=W^TImx9mbF_5WgBhZFn8b5um?9$8=XSN#%VUZ5phFcXa5v;>KChf zUqfH0VrFy9p5@JTvc+0vMac5%ia$1Yb{5FUAVZUV-9nVPYz#xLRcx9b4JLKv(mOBi z9mkHBG;^)9T*&l*rs!a+w&U|gm0P#8RyKWzaw9WCVPCrXm%BNkFVxTcIM@6_qZA1(>dO=MxwIvp541GB#Y!#?0K6QE}aCp`d+Y!zjO?mNTLsMd`29R zg09c_DBaP8bCB3R6h_3}-)ynjn3!7{G+QXHq9qeX<(00caMR?H=qv5#klESdqQN)d z>M!9~s@fas6xF&uX(I=-d$+t&&vME>uRwmU)GrN zQL3E6DrWQZ#8W$$m zZ8`~(5H}RQ-*(nonFO^fu+>Ch=>R^R()#! z${E;_KSI}NJ5X+#U)mp^VTs7jK@EQ^i9lT4> zmS`nKzu^ua5EF@|G;%N5)+!$)94j&gv1Zo9;>rEZj$t{6cbDDz%$SR4o11Lfl8vg7 zY~T!)EiVt{KE;G<@C89Hohf@|8NEFP)lxd+#XS{sAECO3VXJGw`{I@*q+d!3neV5VMw!IL*EGoB`#%A1k6g&l z20e8`;mf0O-47nzW6pdS)3*8W<gIQ*M?ZK#htumLLI{IPzY&N})1O5FAHNfpud1;Z zHx&b;c+$6mdtbLy&7jtP<@21zw^N&9lfp~6Ca#RrK2m>~k$Av!y&W8~z6rIfHP%xB zM&-;_lu2RlH*=sr%K^-B!{Z23m(I(V-Z2}Q#0wbOH*k9Hh#ES4QHy6W(Bmx1??ro^ zywoNH2^#4)f`7X6;`-#NX+BJO&QVk!*}r?Iocku-1R!0DMix#GC6W0TU@!DjF>%PE5jf6vDE(n<_XpGwS?^RcGRpIT79k8{9NgOAosuX%D?l<|Eu%L zKjv9&(4*fTGrA;`r zMv43)^ZXk9V%(Z5{U%HF)!04MzUU=LBuISQqdt9OZT-R;S^X_$fKV;D##}r{fXQB$ zP5CBe11RNzN$d4GfR~&0QDKwu+Q3_F_!dj_Rh;~s8u-Tq2_!_@^RGD`1xtN>vtryg zcM$McYb053511@q-o8oML?{{v1IA#j_NDrl3m5^7|D&Dbxnj^--MH+0iO-LzGZ%Y| zuq4*dIx|z5dm-zS$nLlfEH*BjwNMRPS6aF1+1XhyX<6A=E#{CfMUzvz&e`3z03_po zD)#?OFby_THvFv|e@!9&&B*?>wf_H)k?s8?XtZI&jz<3f5%B*eI}7-A;&$FVikA#& z3>QyK8``c=Q2`RrPbAW}I80Q2z8V+&a74p3x^>fDi0{Henw^cQpI^ypXmZc^H{hjo zXib_OY*svG3w^NS?ppioYm7g&y><}dHJF0upK^Z_l>b{KDKa~0Txj;+nO<;)b^CwE zMw^|i`c}-b0BrPZgjmCJHaMLGZ0+gVwWj!+BfY7;u zSF!CaF%iw?a`~>R+aeB#oB)IeAm0=ZY4Y*%9SWcu0p)iv4&?f#q>PNTxE>cd0LaV4 z?>h$F{t03f+nTzNGJ8wcBiD@jke@eRy0p6Jf@&Fc^teb81H@6RN4ETF#RC`(BLB3f zVu3*JPJ((*tmaxmAPquo{2ZXKn@?&^Pd{i95b5g;l)GMv+=cFYI%{&GfivATNt>|> z^iV&tMDIU%UsV0aMi$Y=I0NCz{hl9-tS3u1L#lGe&v?%_)e%J1U&`s(HNW!lI4x^& z3~!g2k=B@I1JBwYEdprBz1z1(^Pl`G%>T&5MCp}6vqyk1nEQMe2GmBFv^-!jss#zw z5EN`Y6Bor_{t)gp)YbKbVY>Qt<^bURvH{on5%(by-ZTN&NpZjj{XeapYfw{X8pn6W znL1kqw9*zYBwH94E4Oh}f(8jKk!UHPfPx^T5({1+5fB1NNVYn~B7{u0McQTq1w=$j z0)~r_KvW>;iXzuQkzk43l1K~?5)zW^bEw@N)^TP(?8i(dZ*tCaeSiPwyaAxh93|x< z6e_SF2cacBeKA)(MZu(Y^p+P0`Q(bS~cCDk4?)z^_P6*lS2KqpeE#5rI z%?m6ze{_d^+*CuYgCpuH0qyIsJ2f?V@}!xV{0x||dbr8`uNCp*0A1ZYJq1NlrAJx^ z0MpIDCzDC1K6>&Gk$s;qwda_dv~_fZblu0H8#j+%hUb61ZX`?%UhE_s55Anmu!JH6 z`+l4|tvRqZDbc%u!*2i9-!7nJgI2y)btSf}&0njoUE!1iGe06=$IW9fF7f&{y=HXt zfdl1gjP}O2bAEU{M4?=`^5{$ALEu{Ta1{mxRwLMq;(0Hf@|k}@La>$(-MWKHCk+{=+h30(7&jB0dXTR2*ABosiN>Rb4(&M!#;$i>lqTAr~7D!oB??}{7F*; z`iJG!;={v*j}g+oUYOi4Df|yD84fqFe5^W$ zX%(9)$2nTfa^pw+73PW5kPcudpNCf{tQOf;6`x~c*U@NMK6Cx-7Mz(AAroU%gVc%} z35o=(2BRHjbp!8aOmRaXO|isA+UG$6oVFi=Lc+BCI1MSpI-g7I>{9crmtGLF6qP&d zY}-9qrcQ5GhBKGbfcLzRXCYkB@Yt z*pPz&f^R_Rzle;agv9NuxD7^sse=Aux!e_S;ZG+ryJ}#5gGx0Y9s`akvjLKro`eR< zqg+TFJr%J+iH`D4WU^#KhZKckyUu|$x2eAAOV+|X{O&EtfGgyUsH)mu1=+q zCzo8VeHH^4nlX}+boS$Si)UEo9M4X`?6q~`Z3&*S`O5x8H#ZMHUuS6%K`4l43(>he z9)`=d2A#0EewD}5KC5-!<>h0a3ZL)^YGQA{y{@`3fH!)u}=F?iD znRP(3L3JoQ9(}ctWi~-#rOS?&K8k$lt~~36%v?SG4!MYWf=pvJ4~vZe8cv#-HJ~wYWW- zd6Pxf$By{+-l?g%Kwx2ZW6>4ev3YAu=^Z_tb{zty{&+Y)h;I^wR=V2GjyP(VuX>aT zjm&}MDMRG?MLnoQE^EpytwkBi2PN5h-pydbm!(@2&J*5?hT>{^&hl4TB9d&8ZS$Nw z13r?F@B0DheIyVPV>4eq&X)K!ouD?qF-;I%ErY25_Mv>qhnLMQhz!vUhDYi!KPbGc zp>7*!2|GY4g$Q(tdwf@=SXZb3jVpji31OI;NLp=E;4ZqEwthh;mB);bl50Qs(1Xa1 z8R=BY^?FLnCP=@h^Vr`juq^FG2IIGs*Lf7Q4k=;ELuxs&6*sYWzmGk(vHF=1IuVIc z8fIfnCtGOZg?VC<0R<-d)5}}1UoH=w$+xCMRgcYd&$%M0!=aj4#Kf(R`ANk<(I0{Y zYPdgd|>#KvirLKbQ$qQP4L_mVZ zrLi|AHlJ#}xL=OTN)KBjh#&etQ)DUg&&kkp8BH`2L_3gvxCve@%oRVry$ZepMg@4|90iKPNB#eB!~k(eJgcYH7HXV ze(tS}?Mfq$V`vFy@$L6ai>FgoW>6m72MG{TvT4jjE|I6b1=;kzD%Tb6l*yZxtlY*e zh>7n6+Jt13AN}FnwtC I`o*Px0f8nctN;K2 literal 0 HcmV?d00001 diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/pict_3.png b/clones/download.racket-lang.org/releases/8.6/doc/guide/pict_3.png new file mode 100644 index 0000000000000000000000000000000000000000..96b54514c45c7470fc863478e4f177ef805abb28 GIT binary patch literal 38288 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 literal 0 HcmV?d00001 diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/pict_4.png b/clones/download.racket-lang.org/releases/8.6/doc/guide/pict_4.png new file mode 100644 index 0000000000000000000000000000000000000000..7714a00a2846ab1b6ec2f98c1434e36ce6ee297d GIT binary patch literal 28080 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 literal 0 HcmV?d00001 diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/ports.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/ports.html new file mode 100644 index 00000000..cc1406b1 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/ports.html @@ -0,0 +1,24 @@ + +8.1 Varieties of Ports

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/proc-macros.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/proc-macros.html new file mode 100644 index 00000000..db893d6a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/proc-macros.html @@ -0,0 +1,7 @@ + +16.2 General Macro Transformers

16.2 General Macro Transformers

The define-syntax form creates a transformer +binding for an identifier, which is a binding that can be used at +compile time while expanding expressions to be evaluated at run time. +The compile-time value associated with a transformer binding can be +anything; if it is a procedure of one argument, then the binding is +used as a macro, and the procedure is the macro transformer.

    16.2.1 Syntax Objects

    16.2.2 Macro Transformer Procedures

    16.2.3 Mixing Patterns and Expressions: syntax-case

    16.2.4 with-syntax and generate-temporaries

    16.2.5 Compile and Run-Time Phases

    16.2.6 General Phase Levels

      16.2.6.1 Phases and Bindings

      16.2.6.2 Phases and Modules

    16.2.7 Tainted Syntax

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/prompt.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/prompt.html new file mode 100644 index 00000000..b80c5e12 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/prompt.html @@ -0,0 +1,26 @@ + +10.2 Prompts and Aborts

10.2 Prompts and Aborts

When an exception is raised, control escapes out of an arbitrary deep +evaluation context to the point where the exception is caught—or all +the way out if the exception is never caught:

> (+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (/ 1 0)))))))

/: division by zero

But if control escapes “all the way out,” why does the REPL +keep going after an error is printed? You might think that it’s +because the REPL wraps every interaction in a +with-handlers form that catches all exceptions, but that’s +not quite the reason.

The actual reason is that the REPL wraps the interaction with a +prompt, which effectively marks the evaluation context with +an escape point. If an exception is not caught, then information about +the exception is printed, and then evaluation aborts to the +nearest enclosing prompt. More precisely, each prompt has a +prompt tag, and there is a designated default +prompt tag that the uncaught-exception handler uses to abort.

The call-with-continuation-prompt function installs a prompt +with a given prompt tag, and then it evaluates a given thunk +under the prompt. The default-continuation-prompt-tag +function returns the default prompt tag. The +abort-current-continuation function escapes to the nearest +enclosing prompt that has a given prompt tag.

> (define (escape v)
    (abort-current-continuation
     (default-continuation-prompt-tag)
     (lambda () v)))
> (+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (escape 0)))))))

0

> (+ 1
     (call-with-continuation-prompt
      (lambda ()
        (+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (escape 0))))))))
      (default-continuation-prompt-tag)))

1

In escape above, the value v is wrapped in a +procedure that is called after escaping to the enclosing prompt.

Prompts and aborts look very much like exception +handling and raising. Indeed, prompts and aborts are essentially a +more primitive form of exceptions, and with-handlers and +raise are implemented in terms of prompts and aborts. The +power of the more primitive forms is related to the word +“continuation” in the operator names, as we discuss in the next +section.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/protect-out.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/protect-out.html new file mode 100644 index 00000000..e0ecbe4c --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/protect-out.html @@ -0,0 +1,19 @@ + +6.8 Protected Exports

6.8 Protected Exports

Sometimes, a module needs to export bindings to other modules that are +at the same trust level as the exporting module, while at the same +time preventing access from untrusted modules. Such exports should use +the protect-out form in provide. For example, +ffi/unsafe exports all of its unsafe bindings as +protected in this sense.

Levels of trust are implemented with code inspectors (see +Code Inspectors for Trusted and Untrusted Code). +Only modules loaded with an equally strong code inspector as an +exporting module can use protected bindings from the exporting module. +Operations like dynamic-require are granted access depending +on the current code inspector as determined by +current-code-inspector.

When a module re-exports a protected binding, it does not need to use +protect-out again. Access is always determined by the code +inspector of the module that originally defines a protected binding. +When using a protected binding within a module, take care to either +provide new bindings from the module with protect-out or +ensure that no provided bindings expose functionality that was meant +to be protected in the first place.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/qq.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/qq.html new file mode 100644 index 00000000..f1312b5c --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/qq.html @@ -0,0 +1,21 @@ + +4.11 Quasiquoting: quasiquote and lsquo

4.11 Quasiquoting: quasiquote and

+Quasiquoting: quasiquote, unquote, and unquote-splicing in The Racket Reference also documents quasiquote.

The quasiquote form is similar to quote:

(quasiquote datum)

However, for each (unquote expr) +that appears within the datum, the expr is +evaluated to produce a value that takes the place of the +unquote sub-form.

Example:
> (quasiquote (1 2 (unquote (+ 1 2)) (unquote (- 5 1))))

'(1 2 3 4)

This form can be used to write functions that build lists according to +certain patterns.

Examples:
> (define (deep n)
    (cond
      [(zero? n) 0]
      [else
       (quasiquote ((unquote n) (unquote (deep (- n 1)))))]))
> (deep 8)

'(8 (7 (6 (5 (4 (3 (2 (1 0))))))))

Or even to cheaply construct expressions programmatically. (Of course, 9 times out of 10, +you should be using a macro to do this +(the 10th time being when you’re working through +a textbook like PLAI).)

Examples:
> (define (build-exp n)
    (add-lets n (make-sum n)))
> (define (add-lets n body)
    (cond
      [(zero? n) body]
      [else
       (quasiquote
        (let ([(unquote (n->var n)) (unquote n)])
          (unquote (add-lets (- n 1) body))))]))
> (define (make-sum n)
    (cond
      [(= n 1) (n->var 1)]
      [else
       (quasiquote (+ (unquote (n->var n))
                      (unquote (make-sum (- n 1)))))]))
> (define (n->var n) (string->symbol (format "x~a" n)))
> (build-exp 3)

'(let ((x3 3)) (let ((x2 2)) (let ((x1 1)) (+ x3 (+ x2 x1)))))

The unquote-splicing form is similar to unquote, but +its expr must produce a list, and the +unquote-splicing form must appear in a context that produces +either a list or a vector. As the name suggests, the resulting list +is spliced into the context of its use.

Example:
> (quasiquote (1 2 (unquote-splicing (list (+ 1 2) (- 5 1))) 5))

'(1 2 3 4 5)

Using splicing we can revise the construction of our example expressions above +to have just a single let expression and a single + expression.

Examples:
> (define (build-exp n)
    (add-lets
     n
     (quasiquote (+ (unquote-splicing
                     (build-list
                      n
                      (λ (x) (n->var (+ x 1)))))))))
> (define (add-lets n body)
    (quasiquote
     (let (unquote
           (build-list
            n
            (λ (n)
              (quasiquote
               [(unquote (n->var (+ n 1))) (unquote (+ n 1))]))))
       (unquote body))))
> (define (n->var n) (string->symbol (format "x~a" n)))
> (build-exp 3)

'(let ((x1 1) (x2 2) (x3 3)) (+ x1 x2 x3))

If a quasiquote form appears within an enclosing +quasiquote form, then the inner quasiquote +effectively cancels one layer of unquote and +unquote-splicing forms, so that a second unquote +or unquote-splicing is needed.

Examples:
> (quasiquote (1 2 (quasiquote (unquote (+ 1 2)))))

'(1 2 (quasiquote (unquote (+ 1 2))))

> (quasiquote (1 2 (quasiquote (unquote (unquote (+ 1 2))))))

'(1 2 (quasiquote (unquote 3)))

> (quasiquote (1 2 (quasiquote ((unquote (+ 1 2)) (unquote (unquote (- 5 1)))))))

'(1 2 (quasiquote ((unquote (+ 1 2)) (unquote 4))))

The evaluations above will not actually print as shown. Instead, the +shorthand form of quasiquote and unquote will be +used: ` (i.e., a backquote) and , (i.e., a comma). +The same shorthands can be used in expressions:

Example:
> `(1 2 `(,(+ 1 2) ,,(- 5 1)))

'(1 2 `(,(+ 1 2) ,4))

The shorthand form of unquote-splicing is ,@:

Example:
> `(1 2 ,@(list (+ 1 2) (- 5 1)))

'(1 2 3 4)

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/quote.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/quote.html new file mode 100644 index 00000000..36f27dea --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/quote.html @@ -0,0 +1,18 @@ + +4.10 Quoting: quote and '

4.10 Quoting: quote and

+Literals: quote and #%datum in The Racket Reference also documents quote.

The quote form produces a constant:

(quote datum)

The syntax of a datum is technically specified as anything +that the read function parses as a single element. The value +of the quote form is the same value that read would +produce given datum.

The datum can be a symbol, a boolean, a number, a (character +or byte) string, a character, a keyword, an empty list, a pair (or +list) containing more such values, a vector containing more such +values, a hash table containing more such values, or a box containing +another such value.

Examples:
> (quote apple)

'apple

> (quote #t)

#t

> (quote 42)

42

> (quote "hello")

"hello"

> (quote ())

'()

> (quote ((1 2 3) #("z" x) . the-end))

'((1 2 3) #("z" x) . the-end)

> (quote (1 2 . (3)))

'(1 2 3)

As the last example above shows, the datum does not have to +match the normalized printed form of a value. A datum cannot +be a printed representation that starts with #<, so it +cannot be #<void>, #<undefined>, or a procedure.

The quote form is rarely used for a datum that is a +boolean, number, or string by itself, since the printed forms of those +values can already be used as constants. The quote form is +more typically used for symbols and lists, which have other meanings +(identifiers, function calls, etc.) when not quoted.

An expression

'datum

is a shorthand for

(quote datum)

and this shorthand is almost always used instead of +quote. The shorthand applies even within the datum, +so it can produce a list containing quote.

+Reading Quotes in The Racket Reference provides more on the ' shorthand.

Examples:
> 'apple

'apple

> '"hello"

"hello"

> '(1 2 3)

'(1 2 3)

> (display '(you can 'me))

(you can (quote me))

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/racket.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/racket.html new file mode 100644 index 00000000..327cfc2b --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/racket.html @@ -0,0 +1,63 @@ + +21.1 Running racket and gracket

21.1 Running racket and gracket

The gracket executable is the same as racket, but with +small adjustments to behave as a GUI application rather than a console +application. For example, gracket by default runs in +interactive mode with a GUI window instead of a console prompt. GUI +applications can be run with plain racket, however.

Depending on command-line arguments, racket or gracket +runs in interactive mode, +module mode, or +load mode.

21.1.1 Interactive Mode

When racket is run with no command-line arguments (other than +configuration options, like -j), then it starts a REPL +with a >  prompt:

  Welcome to Racket v8.6 [cs].

  >

For enhancing your REPL experience, see +xrepl; for information on GNU Readline support, see +readline.

To initialize the REPL’s environment, racket first +requires the racket/init module, which provides all of +racket, and also installs pretty-print for display +results. Finally, racket loads the file reported by +(find-system-path 'init-file), if it exists, before starting +the REPL.

If any command-line arguments are provided (other than configuration +options), add -i or --repl to re-enable the +REPL. For example,

  racket -e '(display "hi\n")' -i

displays “hi” on start-up, but still presents a REPL.

If module-requiring flags appear before -i/--repl, they +cancel the automatic requiring of racket/init. This +behavior can be used to initialize the REPL’s environment with +a different language. For example,

  racket -l racket/base -i

starts a REPL using a much smaller initial language (that loads +much faster). Beware that most modules do not provide the basic syntax +of Racket, including function-call syntax and require. For +example,

  racket -l racket/date -i

produces a REPL that fails for every expression, because +racket/date provides only a few functions, and not the +#%top-interaction and #%app bindings that are needed +to evaluate top-level function calls in the REPL.

If a module-requiring flag appears after -i/--repl instead +of before it, then the module is required after +racket/init to augment the initial environment. For +example,

  racket -i -l racket/date

starts a useful REPL with racket/date available +in addition to the exports of racket.

21.1.2 Module Mode

If a file argument is supplied to racket before any +command-line switch (other than configuration options), then the file +is required as a module, and (unless -i/--repl is +specified), no REPL is started. For example,

  racket hello.rkt

requires the "hello.rkt" module and then exits. Any argument +after the file name, flag or otherwise, is preserved as a command-line +argument for use by the required module via +current-command-line-arguments.

If command-line flags are used, then the -u or +--require-script flag can be used to explicitly require a file +as a module. The -t or --require flag is similar, except +that additional command-line flags are processed by racket, +instead of preserved for the required module. For example,

  racket -t hello.rkt -t goodbye.rkt

requires the "hello.rkt" module, then requires the +"goodbye.rkt" module, and then exits.

The -l or --lib flag is similar to +-t/--require, but it requires a module using a +lib module path instead of a file path. For example,

  racket -l raco

is the same as running the raco executable with no arguments, +since the raco module is the executable’s main module.

Note that if you wanted to pass command-line flags to +raco above, you would need to protect the flags with a +--, so that racket doesn’t try to parse them itself:

  racket -l raco -- --help

21.1.3 Load Mode

The -f or --load flag supports loading top-level +expressions in a file directly, as opposed to expressions within a +module file. This evaluation is like starting a REPL and typing +the expressions directly, except that the results are not printed. +For example,

  racket -f hi.rkts

loads "hi.rkts" and exits. Note that load mode is +generally a bad idea, for the reasons explained in +A Note to Readers with Lisp/Scheme Experience; using module mode is typically better.

The -e or --eval flag accepts an expression to evaluate +directly. Unlike file loading, the result of the expression is +printed, as in a REPL. For example,

  racket -e '(current-seconds)'

prints the number of seconds since January 1, 1970.

For file loading and expression evaluation, the top-level environment +is created in the same way for +interactive mode: +racket/init is required unless another module is +specified first. For example,

  racket -l racket/base -e '(current-seconds)'

likely runs faster, because it initializes the environment for +evaluation using the smaller racket/base language, +instead of racket/init.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/read-write.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/read-write.html new file mode 100644 index 00000000..5d1cba6c --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/read-write.html @@ -0,0 +1,18 @@ + +8.3 Reading and Writing Racket Data

8.3 Reading and Writing Racket Data

As noted throughout Built-In Datatypes, Racket provides three +ways to print an instance of a built-in value:

  • print, which prints a value in the same way that is it +printed for a REPL result; and

  • write, which prints a value in such a way that +read on the output produces the value back; and

  • display, which tends to reduce a value to just its +character or byte content—at least for those datatypes that +are primarily about characters or bytes, otherwise it falls +back to the same output as write.

Here are some examples using each:

> (print 1/2)

1/2

> (print #\x)

#\x

> (print "hello")

"hello"

> (print #"goodbye")

#"goodbye"

> (print '|pea pod|)

'|pea pod|

> (print '("i" pod))

'("i" pod)

> (print write)

#<procedure:write>

 

> (write 1/2)

1/2

> (write #\x)

#\x

> (write "hello")

"hello"

> (write #"goodbye")

#"goodbye"

> (write '|pea pod|)

|pea pod|

> (write '("i" pod))

("i" pod)

> (write write)

#<procedure:write>

 

> (display 1/2)

1/2

> (display #\x)

x

> (display "hello")

hello

> (display #"goodbye")

goodbye

> (display '|pea pod|)

pea pod

> (display '("i" pod))

(i pod)

> (display write)

#<procedure:write>

Overall, print corresponds to the expression layer of +Racket syntax, write corresponds to the reader layer, and +display roughly corresponds to the character layer.

The printf function supports simple formatting of data and +text. In the format string supplied to printf, ~a +displays the next argument, ~s +writes the next argument, and ~v +prints the next argument.

Examples:
(define (deliver who when what)
  (printf "Items ~a for shopper ~s: ~v" who when what))
> (deliver '("list") '("John") '("milk"))

Items (list) for shopper ("John"): '("milk")

After using write, as opposed to display or +print, many forms of data can be read back in using +read. The same values printed can also be parsed by +read, but the result may have extra quote forms, since a +printed form is meant to be read like an expression.

Examples:
> (define-values (in out) (make-pipe))
> (write "hello" out)
> (read in)

"hello"

> (write '("alphabet" soup) out)
> (read in)

'("alphabet" soup)

> (write #hash((a . "apple") (b . "banana")) out)
> (read in)

'#hash((a . "apple") (b . "banana"))

> (print '("alphabet" soup) out)
> (read in)

''("alphabet" soup)

> (display '("alphabet" soup) out)
> (read in)

'(alphabet soup)

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/reflection.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/reflection.html new file mode 100644 index 00000000..542154ae --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/reflection.html @@ -0,0 +1,4 @@ + +15 Reflection and Dynamic Evaluation

15 Reflection and Dynamic Evaluation

Racket is a dynamic language. It offers numerous facilities +for loading, compiling, and even constructing new code at run +time.

    15.1 eval

      15.1.1 Local Scopes

      15.1.2 Namespaces

      15.1.3 Namespaces and Modules

    15.2 Manipulating Namespaces

      15.2.1 Creating and Installing Namespaces

      15.2.2 Sharing Data and Code Across Namespaces

    15.3 Scripting Evaluation and Using load

    15.4 Code Inspectors for Trusted and Untrusted Code

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-alternation.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-alternation.html new file mode 100644 index 00000000..953968fd --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-alternation.html @@ -0,0 +1,14 @@ + +9.7 Alternation

9.7 Alternation

You can specify a list of alternate subpatterns by +separating them by |. The | separates +subpatterns in the nearest enclosing cluster (or in the entire +pattern string if there are no enclosing parens).

> (regexp-match #rx"f(ee|i|o|um)" "a small, final fee")

'("fi" "i")

> (regexp-replace* #rx"([yi])s(e[sdr]?|ing|ation)"
                   (string-append
                    "analyse an energising organisation"
                    " pulsing with noisy organisms")
                   "\\1z\\2")

"analyze an energizing organization pulsing with noisy organisms"

Note again that if you wish to use clustering merely to specify a list +of alternate subpatterns but do not want the submatch, use +(?: instead of (.

> (regexp-match #rx"f(?:ee|i|o|um)" "fun for all")

'("fo")

An important thing to note about alternation is that the leftmost +matching alternate is picked regardless of its length. Thus, if one +of the alternates is a prefix of a later alternate, the latter may not +have a chance to match.

> (regexp-match #rx"call|call-with-current-continuation"
                "call-with-current-continuation")

'("call")

To allow the longer alternate to have a shot at matching, place it +before the shorter one:

> (regexp-match #rx"call-with-current-continuation|call"
                "call-with-current-continuation")

'("call-with-current-continuation")

In any case, an overall match for the entire regexp is always +preferred to an overall non-match. In the following, the longer +alternate still wins, because its preferred shorter prefix fails to +yield an overall match.

> (regexp-match
   #rx"(?:call|call-with-current-continuation) constrained"
   "call-with-current-continuation constrained")

'("call-with-current-continuation constrained")

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-assert.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-assert.html new file mode 100644 index 00000000..32f89d6c --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-assert.html @@ -0,0 +1,10 @@ + +9.3 Basic Assertions

9.3 Basic Assertions

The assertions ^ and $ identify the +beginning and the end of the text string, respectively. They ensure +that their adjoining regexps match at one or other end of the text +string:

> (regexp-match-positions #rx"^contact" "first contact")

#f

The regexp above fails to match because contact does +not occur at the beginning of the text string. In

> (regexp-match-positions #rx"laugh$" "laugh laugh laugh laugh")

'((18 . 23))

the regexp matches the last laugh.

The metasequence \b asserts that a word boundary exists, but +this metasequence works only with #px syntax. In

> (regexp-match-positions #px"yack\\b" "yackety yack")

'((8 . 12))

the yack in yackety doesn’t end at a word boundary +so it isn’t matched. The second yack does and is.

The metasequence \B (also #px only) has the +opposite effect to \b; it asserts that a word boundary does +not exist. In

> (regexp-match-positions #px"an\\B" "an analysis")

'((3 . 5))

the an that doesn’t end in a word boundary is matched.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-chars.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-chars.html new file mode 100644 index 00000000..1e1f3450 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-chars.html @@ -0,0 +1,60 @@ + +9.4 Characters and Character Classes

9.4 Characters and Character Classes

Typically, a character in the regexp matches the same character in the +text string. Sometimes it is necessary or convenient to use a regexp +metasequence to refer to a single character. For example, the +metasequence \. matches the period character.

The metacharacter . matches any character +(other than newline in multi-line mode; see +Cloisters):

> (regexp-match #rx"p.t" "pet")

'("pet")

The above pattern also matches pat, pit, +pot, put, and p8t, but not +peat or pfffft.

A character class matches any one character from a set of +characters. A typical format for this is the bracketed +character class [...], which matches any one +character from the non-empty sequence of characters enclosed within +the brackets. Thus, #rx"p[aeiou]t" matches pat, +pet, pit, pot, put, and +nothing else.

Inside the brackets, a - between two characters specifies +the Unicode range between the characters. For example, +#rx"ta[b-dgn-p]" matches tab, tac, +tad, tag, tan, tao, and +tap.

An initial ^ after the left bracket inverts the set +specified by the rest of the contents; i.e., it specifies the set of +characters other than those identified in the brackets. For +example, #rx"do[^g]" matches all three-character sequences +starting with do except dog.

Note that the metacharacter ^ inside brackets means +something quite different from what it means outside. Most other +metacharacters (., *, +, +?, etc.) cease to be metacharacters when inside +brackets, although you may still escape them for peace of mind. A +- is a metacharacter only when it’s inside brackets, +and when it is neither the first nor the last character between the +brackets.

Bracketed character classes cannot contain other bracketed character +classes (although they contain certain other types of character +classes; see below). Thus, a [ inside a bracketed character +class doesn’t have to be a metacharacter; it can stand for itself. +For example, #rx"[a[b]" matches a, [, and +b.

Furthermore, since empty bracketed character classes are disallowed, a +] immediately occurring after the opening left bracket also +doesn’t need to be a metacharacter. For example, #rx"[]ab]" +matches ], a, and b.

9.4.1 Some Frequently Used Character Classes

In #px syntax, some standard character classes can be +conveniently represented as metasequences instead of as explicit +bracketed expressions: \d matches a digit +(the same as [0-9]); \s matches an ASCII whitespace character; and +\w matches a character that could be part of a +“word”.

Following regexp custom, we identify “word” characters +as [A-Za-z0-9_], although these are too restrictive for what +a Racketeer might consider a “word.”

The upper-case versions of these metasequences stand for the +inversions of the corresponding character classes: \D +matches a non-digit, \S a non-whitespace character, and +\W a non-“word” character.

Remember to include a double backslash when putting these +metasequences in a Racket string:

> (regexp-match #px"\\d\\d"
   "0 dear, 1 have 2 read catch 22 before 9")

'("22")

These character classes can be used inside a bracketed expression. For +example, #px"[a-z\\d]" matches a lower-case letter or a +digit.

9.4.2 POSIX character classes

A POSIX character class is a special metasequence of +the form [:...:] that can be used only inside a +bracketed expression in #px syntax. The POSIX classes +supported are

  • [:alnum:] ASCII letters and digits

  • [:alpha:] ASCII letters

  • [:ascii:] ASCII characters

  • [:blank:] ASCII widthful whitespace: space and tab

  • [:cntrl:] “control” characters: ASCII 0 to 31

  • [:digit:] ASCII digits, same as \d

  • [:graph:] ASCII characters that use ink

  • [:lower:] ASCII lower-case letters

  • [:print:] ASCII ink-users plus widthful whitespace

  • [:space:] ASCII whitespace, same as \s

  • [:upper:] ASCII upper-case letters

  • [:word:] ASCII letters and _, same as \w

  • [:xdigit:] ASCII hex digits

For example, the #px"[[:alpha:]_]" matches a letter or +underscore.

> (regexp-match #px"[[:alpha:]_]" "--x--")

'("x")

> (regexp-match #px"[[:alpha:]_]" "--_--")

'("_")

> (regexp-match #px"[[:alpha:]_]" "--:--")

#f

The POSIX class notation is valid only inside a bracketed +expression. For instance, [:alpha:], when not inside a +bracketed expression, will not be read as the letter class. Rather, +it is (from previous principles) the character class containing the +characters :, a, l, p, +h.

> (regexp-match #px"[:alpha:]" "--a--")

'("a")

> (regexp-match #px"[:alpha:]" "--x--")

#f

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-clusters.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-clusters.html new file mode 100644 index 00000000..7c4a4d9a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-clusters.html @@ -0,0 +1,50 @@ + +9.6 Clusters

9.6 Clusters

Clusteringenclosure within parens +(...)identifies the enclosed +subpattern as a single entity. It causes the matcher to +capture the submatch, or the portion of the string matching +the subpattern, in addition to the overall match:

> (regexp-match #rx"([a-z]+) ([0-9]+), ([0-9]+)" "jan 1, 1970")

'("jan 1, 1970" "jan" "1" "1970")

Clustering also causes a following quantifier to treat the entire +enclosed subpattern as an entity:

> (regexp-match #rx"(pu )*" "pu pu platter")

'("pu pu " "pu ")

The number of submatches returned is always equal to the number of +subpatterns specified in the regexp, even if a particular subpattern +happens to match more than one substring or no substring at all.

> (regexp-match #rx"([a-z ]+;)*" "lather; rinse; repeat;")

'("lather; rinse; repeat;" " repeat;")

Here, the *-quantified subpattern matches three times, but +it is the last submatch that is returned.

It is also possible for a quantified subpattern to fail to match, even +if the overall pattern matches. In such cases, the failing submatch +is represented by #f

> (define date-re
    ; match month year' or month day, year';
    ; subpattern matches day, if present
    #rx"([a-z]+) +([0-9]+,)? *([0-9]+)")
> (regexp-match date-re "jan 1, 1970")

'("jan 1, 1970" "jan" "1," "1970")

> (regexp-match date-re "jan 1970")

'("jan 1970" "jan" #f "1970")

9.6.1 Backreferences

Submatches can be used in the insert string argument of the +procedures regexp-replace and regexp-replace*. The +insert string can use \n as a backreference +to refer back to the nth submatch, which is the substring +that matched the nth subpattern. A \0 refers to the +entire match, and it can also be specified as \&.

> (regexp-replace #rx"_(.+?)_"
    "the _nina_, the _pinta_, and the _santa maria_"
    "*\\1*")

"the *nina*, the _pinta_, and the _santa maria_"

> (regexp-replace* #rx"_(.+?)_"
    "the _nina_, the _pinta_, and the _santa maria_"
    "*\\1*")

"the *nina*, the *pinta*, and the *santa maria*"

> (regexp-replace #px"(\\S+) (\\S+) (\\S+)"
    "eat to live"
    "\\3 \\2 \\1")

"live to eat"

Use \\ in the insert string to specify a literal backslash. +Also, \$ stands for an empty string, and is useful for +separating a backreference \n from an immediately +following number.

Backreferences can also be used within a #px pattern to +refer back to an already matched subpattern in the pattern. +\n stands for an exact repeat of the nth +submatch. Note that \0, which is useful in an insert string, +makes no sense within the regexp pattern, because the entire regexp +has not matched yet so you cannot refer back to it.}

> (regexp-match #px"([a-z]+) and \\1"
                "billions and billions")

'("billions and billions" "billions")

Note that the backreference is not simply a repeat of the +previous subpattern. Rather it is a repeat of the particular +substring already matched by the subpattern.

In the above example, the backreference can only match +billions. It will not match millions, even though +the subpattern it harks back to—([a-z]+)would have had +no problem doing so:

> (regexp-match #px"([a-z]+) and \\1"
                "billions and millions")

#f

The following example marks all immediately repeating patterns in a +number string:

> (regexp-replace* #px"(\\d+)\\1"
    "123340983242432420980980234"
    "{\\1,\\1}")

"12{3,3}40983{24,24}3242{098,098}0234"

The following example corrects doubled words:

> (regexp-replace* #px"\\b(\\S+) \\1\\b"
    (string-append "now is the the time for all good men to "
                   "to come to the aid of of the party")
    "\\1")

"now is the time for all good men to come to the aid of the party"

9.6.2 Non-capturing Clusters

It is often required to specify a cluster (typically for +quantification) but without triggering the capture of submatch +information. Such clusters are called non-capturing. To +create a non-capturing cluster, use (?: instead of +( as the cluster opener.

In the following example, a non-capturing cluster eliminates the +“directory” portion of a given Unix pathname, and a capturing +cluster identifies the basename.

But don’t parse paths with regexps. Use functions like +split-path, instead.

> (regexp-match #rx"^(?:[a-z]*/)*([a-z]+)$"
                "/usr/local/bin/racket")

'("/usr/local/bin/racket" "racket")

9.6.3 Cloisters

The location between the ? and the : of a +non-capturing cluster is called a cloister. You can put +modifiers there that will cause the enclustered subpattern to +be treated specially. The modifier i causes the subpattern +to match case-insensitively:

The term cloister is a useful, if terminally +cute, coinage from the abbots of Perl.

> (regexp-match #rx"(?i:hearth)" "HeartH")

'("HeartH")

The modifier m causes the subpattern to match in +multi-line mode, where . does not match a newline +character, ^ can match just after a newline, and $ +can match just before a newline.

> (regexp-match #rx"." "\na\n")

'("\n")

> (regexp-match #rx"(?m:.)" "\na\n")

'("a")

> (regexp-match #rx"^A plan$" "A man\nA plan\nA canal")

#f

> (regexp-match #rx"(?m:^A plan$)" "A man\nA plan\nA canal")

'("A plan")

You can put more than one modifier in the cloister:

> (regexp-match #rx"(?mi:^A Plan$)" "a man\na plan\na canal")

'("a plan")

A minus sign before a modifier inverts its meaning. Thus, you can use +-i in a subcluster to overturn the +case-insensitivities caused by an enclosing cluster.

> (regexp-match #rx"(?i:the (?-i:TeX)book)"
                "The TeXbook")

'("The TeXbook")

The above regexp will allow any casing for the and +book, but it insists that TeX not be differently +cased.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-intro.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-intro.html new file mode 100644 index 00000000..3708acb6 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-intro.html @@ -0,0 +1,41 @@ + +9.1 Writing Regexp Patterns

9.1 Writing Regexp Patterns

A string or byte string can be used directly as a regexp +pattern, or it can be prefixed with #rx to form a literal +regexp value. For example, #rx"abc" is a string-based +regexp value, and #rx#"abc" is a byte +string-based regexp value. Alternately, a string or byte +string can be prefixed with #px, as in #px"abc", +for a slightly extended syntax of patterns within the string.

Most of the characters in a regexp pattern are meant to match +occurrences of themselves in the text string. Thus, the pattern +#rx"abc" matches a string that contains the characters +a, b, and c in succession. Other +characters act as metacharacters, and some character +sequences act as metasequences. That is, they specify +something other than their literal selves. For example, in the +pattern #rx"a.c", the characters a and c +stand for themselves, but the metacharacter . can +match any character. Therefore, the pattern #rx"a.c" +matches an a, any character, and c in succession.

When we want a literal \ inside a Racket string +or regexp literal, we must escape it so that it shows up in the string +at all. Racket strings use \ as the escape character, so we +end up with two \s: one Racket-string \ to escape +the regexp \, which then escapes the .. Another +character that would need escaping inside a Racket string is +".

If we needed to match the character . itself, we can escape +it by preceding it with a \. The character sequence +\. is thus a metasequence, since it doesn’t match +itself but rather just .. So, to match a, +., and c in succession, we use the regexp pattern +#rx"a\\.c"; the double \ is an artifact of Racket +strings, not the regexp pattern itself.

The regexp function takes a string or byte string and +produces a regexp value. Use regexp when you construct +a pattern to be matched against multiple strings, since a pattern is +compiled to a regexp value before it can be used in a match. +The pregexp function is like regexp, but using the +extended syntax. Regexp values as literals with #rx or +#px are compiled once and for all when they are read.

The regexp-quote function takes an arbitrary string and +returns a string for a pattern that matches exactly the original +string. In particular, characters in the input string that could serve +as regexp metacharacters are escaped with a backslash, so that they +safely match only themselves.

> (regexp-quote "cons")

"cons"

> (regexp-quote "list?")

"list\\?"

The regexp-quote function is useful when building a composite +regexp from a mix of regexp strings and verbatim strings.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-match.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-match.html new file mode 100644 index 00000000..7e625a0b --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-match.html @@ -0,0 +1,40 @@ + +9.2 Matching Regexp Patterns

9.2 Matching Regexp Patterns

The regexp-match-positions function takes a regexp +pattern and a text string, and it returns a match if the regexp +matches (some part of) the text string, or #f if the regexp +did not match the string. A successful match produces a list of +index pairs.

Examples:
> (regexp-match-positions #rx"brain" "bird")

#f

> (regexp-match-positions #rx"needle" "hay needle stack")

'((4 . 10))

In the second example, the integers 4 and 10 +identify the substring that was matched. The 4 is the +starting (inclusive) index, and 10 the ending (exclusive) +index of the matching substring:

> (substring "hay needle stack" 4 10)

"needle"

In this first example, regexp-match-positions’s return list +contains only one index pair, and that pair represents the entire +substring matched by the regexp. When we discuss subpatterns +later, we will see how a single match operation can yield a list of +submatches.

The regexp-match-positions function takes optional third and +fourth arguments that specify the indices of the text string within +which the matching should take place.

> (regexp-match-positions
   #rx"needle"
   "his needle stack -- my needle stack -- her needle stack"
   20 39)

'((23 . 29))

Note that the returned indices are still reckoned relative to the full +text string.

The regexp-match function is like +regexp-match-positions, but instead of returning index pairs, +it returns the matching substrings:

> (regexp-match #rx"brain" "bird")

#f

> (regexp-match #rx"needle" "hay needle stack")

'("needle")

When regexp-match is used with byte-string regexp, the result +is a matching byte substring:

> (regexp-match #rx#"needle" #"hay needle stack")

'(#"needle")

A byte-string regexp can be applied to a string, and a +string regexp can be applied to a byte string. In both +cases, the result is a byte string. Internally, all +regexp matching is in terms of bytes, and a string regexp +is expanded to a regexp that matches UTF-8 encodings of +characters. For maximum efficiency, use byte-string +matching instead of string, since matching bytes directly +avoids UTF-8 encodings.

If you have data that is in a port, there’s no need to first read it +into a string. Functions like regexp-match can match on the +port directly:

> (define-values (i o) (make-pipe))
> (write "hay needle stack" o)
> (close-output-port o)
> (regexp-match #rx#"needle" i)

'(#"needle")

The regexp-match? function is like +regexp-match-positions, but simply returns a boolean +indicating whether the match succeeded:

> (regexp-match? #rx"brain" "bird")

#f

> (regexp-match? #rx"needle" "hay needle stack")

#t

The regexp-split function takes two arguments, a +regexp pattern and a text string, and it returns a list of +substrings of the text string; the pattern identifies the delimiter +separating the substrings.

> (regexp-split #rx":" "/bin:/usr/bin:/usr/bin/X11:/usr/local/bin")

'("/bin" "/usr/bin" "/usr/bin/X11" "/usr/local/bin")

> (regexp-split #rx" " "pea soup")

'("pea" "soup")

If the first argument matches empty strings, then the list of all the +single-character substrings is returned.

> (regexp-split #rx"" "smithereens")

'("" "s" "m" "i" "t" "h" "e" "r" "e" "e" "n" "s" "")

Thus, to identify one-or-more spaces as the delimiter, take care to +use the regexp #rx" +", not #rx" *".

> (regexp-split #rx" +" "split pea     soup")

'("split" "pea" "soup")

> (regexp-split #rx" *" "split pea     soup")

'("" "s" "p" "l" "i" "t" "" "p" "e" "a" "" "s" "o" "u" "p" "")

The regexp-replace function replaces the matched portion of +the text string by another string. The first argument is the pattern, +the second the text string, and the third is either the string to be +inserted or a procedure to convert matches to the insert string.

> (regexp-replace #rx"te" "liberte" "ty")

"liberty"

> (regexp-replace #rx"." "racket" string-upcase)

"Racket"

If the pattern doesn’t occur in the text string, the returned string +is identical to the text string.

The regexp-replace* function replaces all matches in +the text string by the insert string:

> (regexp-replace* #rx"te" "liberte egalite fraternite" "ty")

"liberty egality fratyrnity"

> (regexp-replace* #rx"[ds]" "drracket" string-upcase)

"Drracket"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-quant.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-quant.html new file mode 100644 index 00000000..aa72e09d --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp-quant.html @@ -0,0 +1,26 @@ + +9.5 Quantifiers

9.5 Quantifiers

The quantifiers *, +, and ? +match respectively: zero or more, one or more, and zero or one +instances of the preceding subpattern.

> (regexp-match-positions #rx"c[ad]*r" "cadaddadddr")

'((0 . 11))

> (regexp-match-positions #rx"c[ad]*r" "cr")

'((0 . 2))

> (regexp-match-positions #rx"c[ad]+r" "cadaddadddr")

'((0 . 11))

> (regexp-match-positions #rx"c[ad]+r" "cr")

#f

> (regexp-match-positions #rx"c[ad]?r" "cadaddadddr")

#f

> (regexp-match-positions #rx"c[ad]?r" "cr")

'((0 . 2))

> (regexp-match-positions #rx"c[ad]?r" "car")

'((0 . 3))

In #px syntax, you can use braces to specify much +finer-tuned quantification than is possible with *, ++, ?:

  • The quantifier {m} matches +exactly m instances of the preceding +subpattern; m must be a nonnegative integer.

  • The quantifier +{m,n} matches +at least m and at most n instances. m +and n are nonnegative integers with m less or +equal to n. You may omit either or both numbers, in +which case m defaults to 0 and n to +infinity.

It is evident that + and ? are abbreviations for +{1,} and {0,1} respectively, and * +abbreviates {,}, which is the same as {0,}.

> (regexp-match #px"[aeiou]{3}" "vacuous")

'("uou")

> (regexp-match #px"[aeiou]{3}" "evolve")

#f

> (regexp-match #px"[aeiou]{2,3}" "evolve")

#f

> (regexp-match #px"[aeiou]{2,3}" "zeugma")

'("eu")

The quantifiers described so far are all greedy: they match +the maximal number of instances that would still lead to an overall +match for the full pattern.

> (regexp-match #rx"<.*>" "<tag1> <tag2> <tag3>")

'("<tag1> <tag2> <tag3>")

To make these quantifiers non-greedy, append a ? +to them. Non-greedy quantifiers match the minimal number of instances +needed to ensure an overall match.

> (regexp-match #rx"<.*?>" "<tag1> <tag2> <tag3>")

'("<tag1>")

The non-greedy quantifiers are *?, +?, +??, {m}?, and +{m,n}?, although +{m}? is always the same as +{m}. Note that the metacharacter +? has two different uses, and both uses are represented in +??.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp.html new file mode 100644 index 00000000..63a0de3f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/regexp.html @@ -0,0 +1,7 @@ + +9 Regular Expressions

9 Regular Expressions

This chapter is a modified version of [Sitaram05].

A regexp value encapsulates a pattern that is described by a +string or byte string. The regexp matcher tries to match this +pattern against (a portion of) another string or byte string, which we +will call the text string, when you call functions like +regexp-match. The text string is treated as raw text, and +not as a pattern.

    9.1 Writing Regexp Patterns

    9.2 Matching Regexp Patterns

    9.3 Basic Assertions

    9.4 Characters and Character Classes

      9.4.1 Some Frequently Used Character Classes

      9.4.2 POSIX character classes

    9.5 Quantifiers

    9.6 Clusters

      9.6.1 Backreferences

      9.6.2 Non-capturing Clusters

      9.6.3 Cloisters

    9.7 Alternation

    9.8 Backtracking

    9.9 Looking Ahead and Behind

      9.9.1 Lookahead

      9.9.2 Lookbehind

    9.10 An Extended Example

+Regular Expressions in The Racket Reference provides more on regexps.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/running.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/running.html new file mode 100644 index 00000000..7faf3d93 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/running.html @@ -0,0 +1,6 @@ + +21 Running and Creating Executables

21 Running and Creating Executables

While developing programs, many Racket programmers use the +DrRacket programming environment. To run a program without the +development environment, use racket (for console-based +programs) or gracket (for GUI programs). This chapter mainly +explains how to run racket and gracket.

    21.1 Running racket and gracket

      21.1.1 Interactive Mode

      21.1.2 Module Mode

      21.1.3 Load Mode

    21.2 Scripts

      21.2.1 Unix Scripts

      21.2.2 Windows Batch Files

    21.3 Creating Stand-Alone Executables

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/scheme-forms.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/scheme-forms.html new file mode 100644 index 00000000..6f1efbd7 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/scheme-forms.html @@ -0,0 +1,5 @@ + +4 Expressions and Definitions

4 Expressions and Definitions

The Racket Essentials chapter introduced some of Racket’s syntactic +forms: definitions, procedure applications, conditionals, and so +on. This section provides more details on those forms, plus a few +additional basic forms.

    4.1 Notation

    4.2 Identifiers and Binding

    4.3 Function Calls (Procedure Applications)

      4.3.1 Evaluation Order and Arity

      4.3.2 Keyword Arguments

      4.3.3 The apply Function

    4.4 Functions (Procedures): lambda

      4.4.1 Declaring a Rest Argument

      4.4.2 Declaring Optional Arguments

      4.4.3 Declaring Keyword Arguments

      4.4.4 Arity-Sensitive Functions: case-lambda

    4.5 Definitions: define

      4.5.1 Function Shorthand

      4.5.2 Curried Function Shorthand

      4.5.3 Multiple Values and define-values

      4.5.4 Internal Definitions

    4.6 Local Binding

      4.6.1 Parallel Binding: let

      4.6.2 Sequential Binding: let*

      4.6.3 Recursive Binding: letrec

      4.6.4 Named let

      4.6.5 Multiple Values: let-values, let*-values, letrec-values

    4.7 Conditionals

      4.7.1 Simple Branching: if

      4.7.2 Combining Tests: and and or

      4.7.3 Chaining Tests: cond

    4.8 Sequencing

      4.8.1 Effects Before: begin

      4.8.2 Effects After: begin0

      4.8.3 Effects If...: when and unless

    4.9 Assignment: set!

      4.9.1 Guidelines for Using Assignment

      4.9.2 Multiple Values: set!-values

    4.10 Quoting: quote and

    4.11 Quasiquoting: quasiquote and

    4.12 Simple Dispatch: case

    4.13 Dynamic Binding: parameterize

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/scripts.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/scripts.html new file mode 100644 index 00000000..bb0d2e05 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/scripts.html @@ -0,0 +1,41 @@ + +21.2 Scripts

21.2 Scripts

Racket files can be turned into executable scripts on Unix and Mac +OS. On Windows, a compatibility layer like Cygwin support the +same kind of scripts, or scripts can be implemented as batch files.

21.2.1 Unix Scripts

In a Unix environment (including Linux and Mac OS), a Racket file can +be turned into an executable script using the shell’s #! +convention. The first two characters of the file must be #!; +the next character must be either a space or /, and the +remainder of the first line must be a command to execute the script. For +some platforms, the total length of the first line is restricted to 32 +characters, and sometimes the space is required.

Use #lang racket/base instead +of #lang racket to produce scripts with a +faster startup time.

The simplest script format uses an absolute path to a racket +executable followed by a module declaration. For example, if +racket is installed in "/usr/local/bin", then a file +containing the following text acts as a “hello world” script:

  #! /usr/local/bin/racket

  #lang racket/base

  "Hello, world!"

In particular, if the above is put into a file "hello" and +the file is made executable (e.g., with chmod a+x hello), then +typing ./hello at the shell prompt produces the output +"Hello, world!".

The above script works because the operating system automatically puts +the path to the script as the argument to the program started by the +#! line, and because racket treats a single non-flag +argument as a file containing a module to run.

Instead of specifying a complete path to the racket +executable, a popular alternative is to require that racket +is in the user’s command path, and then “trampoline” using +/usr/bin/env:

  #! /usr/bin/env racket

  #lang racket/base

  "Hello, world!"

In either case, command-line arguments to a script are available via +current-command-line-arguments:

  #! /usr/bin/env racket

  #lang racket/base

  (printf "Given arguments: ~s\n"

          (current-command-line-arguments))

If the name of the script is needed, it is available via +(find-system-path 'run-file), instead of via +(current-command-line-arguments).

Usually, the best way to handle command-line arguments is to parse +them using the command-line form provided by +racket. The command-line form extracts +command-line arguments from (current-command-line-arguments) +by default:

  #! /usr/bin/env racket

  #lang racket

  

  (define verbose? (make-parameter #f))

  

  (define greeting

    (command-line

     #:once-each

     [("-v") "Verbose mode" (verbose? #t)]

     #:args

     (str) str))

  

  (printf "~a~a\n"

          greeting

          (if (verbose?) " to you, too!" ""))

Try running the above script with the --help flag to see what +command-line arguments are allowed by the script.

An even more general trampoline uses /bin/sh plus some lines +that are comments in one language and expressions in the other. This +trampoline is more complicated, but it provides more control over +command-line arguments to racket:

  #! /bin/sh

  #|

  exec racket -e '(printf "Running...\n")' -u "$0" ${1+"$@"}

  |#

  #lang racket/base

  (printf "The above line of output had been produced via\n")

  (printf "a use of the `-e' flag.\n")

  (printf "Given arguments: ~s\n"

          (current-command-line-arguments))

Note that #! starts a line comment in Racket, and +#|...|# forms a block comment. Meanwhile, +# also starts a shell-script comment, while exec +racket aborts the shell script to start racket. That way, +the script file turns out to be valid input to both /bin/sh and +racket.

21.2.2 Windows Batch Files

A similar trick can be used to write Racket code in Windows +.bat batch files:

  ; @echo off

  ; Racket.exe "%~f0" %*

  ; exit /b

  #lang racket/base

  "Hello, world!"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/serialization.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/serialization.html new file mode 100644 index 00000000..50b6261e --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/serialization.html @@ -0,0 +1,18 @@ + +8.4 Datatypes and Serialization

8.4 Datatypes and Serialization

Prefab structure types (see Prefab Structure Types) +automatically support serialization: they can be written to +an output stream, and a copy can be read back in from an input stream:

> (define-values (in out) (make-pipe))
> (write #s(sprout bean) out)
> (read in)

'#s(sprout bean)

Other structure types created by struct, which offer +more abstraction than prefab structure types, normally +write either using #<....> notation (for +opaque structure types) or using #(....) vector +notation (for transparent structure types). In neither case can the +result be read back in as an instance of the structure type:

> (struct posn (x y))
> (write (posn 1 2))

#<posn>

> (define-values (in out) (make-pipe))
> (write (posn 1 2) out)
> (read in)

pipe::1: read: bad syntax `#<`

> (struct posn (x y) #:transparent)
> (write (posn 1 2))

#(struct:posn 1 2)

> (define-values (in out) (make-pipe))
> (write (posn 1 2) out)
> (define v (read in))
> v

'#(struct:posn 1 2)

> (posn? v)

#f

> (vector? v)

#t

The serializable-struct form defines a structure type +that can be serialized to a value that can be printed using +write and restored via read. The serialized +result can be deserialized to get back an instance of the +original structure type. The serialization form and functions are +provided by the racket/serialize library.

Examples:
> (require racket/serialize)
> (serializable-struct posn (x y) #:transparent)
> (deserialize (serialize (posn 1 2)))

(posn 1 2)

> (write (serialize (posn 1 2)))

((3) 1 ((#f . deserialize-info:posn-v0)) 0 () () (0 1 2))

> (define-values (in out) (make-pipe))
> (write (serialize (posn 1 2)) out)
> (deserialize (read in))

(posn 1 2)

In addition to the names bound by struct, +serializable-struct binds an identifier with deserialization +information, and it automatically provides the +deserialization identifier from a module context. This deserialization +identifier is accessed reflectively when a value is deserialized.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/set_.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/set_.html new file mode 100644 index 00000000..31017928 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/set_.html @@ -0,0 +1,24 @@ + +4.9 Assignment: set!

4.9 Assignment: set!

+Assignment: set! and set!-values in The Racket Reference also documents set!.

Assign to a variable using set!:

(set! id expr)

A set! expression evaluates expr and changes +id (which must be bound in the enclosing environment) to the +resulting value. The result of the set! expression itself is +#<void>.

Examples:
(define greeted null)
(define (greet name)
  (set! greeted (cons name greeted))
  (string-append "Hello, " name))
> (greet "Athos")

"Hello, Athos"

> (greet "Porthos")

"Hello, Porthos"

> (greet "Aramis")

"Hello, Aramis"

> greeted

'("Aramis" "Porthos" "Athos")

(define (make-running-total)
  (let ([n 0])
    (lambda ()
      (set! n (+ n 1))
      n)))
(define win (make-running-total))
(define lose (make-running-total))

 

> (win)

1

> (win)

2

> (lose)

1

> (win)

3

4.9.1 Guidelines for Using Assignment

Although using set! is sometimes appropriate, Racket style +generally discourages the use of set!. The following +guidelines may help explain when using set! is appropriate.

  • As in any modern language, assigning to a shared identifier is no + substitute for passing an argument to a procedure or getting + its result.

    Really awful example:
    (define name "unknown")
    (define result "unknown")
    (define (greet)
      (set! result (string-append "Hello, " name)))

     

    > (set! name "John")
    > (greet)
    > result

    "Hello, John"

    Ok example:
    (define (greet name)
      (string-append "Hello, " name))

     

    > (greet "John")

    "Hello, John"

    > (greet "Anna")

    "Hello, Anna"

  • A sequence of assignments to a local variable is far inferior +to nested bindings.

    Bad example:
    > (let ([tree 0])
        (set! tree (list tree 1 tree))
        (set! tree (list tree 2 tree))
        (set! tree (list tree 3 tree))
        tree)

    '(((0 1 0) 2 (0 1 0)) 3 ((0 1 0) 2 (0 1 0)))

    Ok example:
    > (let* ([tree 0]
             [tree (list tree 1 tree)]
             [tree (list tree 2 tree)]
             [tree (list tree 3 tree)])
        tree)

    '(((0 1 0) 2 (0 1 0)) 3 ((0 1 0) 2 (0 1 0)))

  • Using assignment to accumulate results from an iteration is +bad style. Accumulating through a loop argument is better.

    Somewhat bad example:
    (define (sum lst)
      (let ([s 0])
        (for-each (lambda (i) (set! s (+ i s)))
                  lst)
        s))

     

    > (sum '(1 2 3))

    6

    Ok example:
    (define (sum lst)
      (let loop ([lst lst] [s 0])
        (if (null? lst)
            s
            (loop (cdr lst) (+ s (car lst))))))

     

    > (sum '(1 2 3))

    6

    Better (use an existing function) example:
    (define (sum lst)
      (apply + lst))

     

    > (sum '(1 2 3))

    6

    Good (a general approach) example:
    (define (sum lst)
      (for/fold ([s 0])
                ([i (in-list lst)])
        (+ s i)))

     

    > (sum '(1 2 3))

    6

  • For cases where stateful objects are necessary or appropriate, +then implementing the object’s state with set! is +fine.

    Ok example:
    (define next-number!
      (let ([n 0])
        (lambda ()
          (set! n (add1 n))
          n)))

     

    > (next-number!)

    1

    > (next-number!)

    2

    > (next-number!)

    3

All else being equal, a program that uses no assignments or mutation +is always preferable to one that uses assignments or mutation. While +side effects are to be avoided, however, they should be used if the +resulting code is significantly more readable or if it implements a +significantly better algorithm.

The use of mutable values, such as vectors and hash tables, raises +fewer suspicions about the style of a program than using set! +directly. Nevertheless, simply replacing set!s in a program +with vector-set!s obviously does not improve the style of +the program.

4.9.2 Multiple Values: set!-values

+Assignment: set! and set!-values in The Racket Reference also documents set!-values.

The set!-values form assigns to multiple variables at once, +given an expression that produces an appropriate number of values:

(set!-values (id ...) expr)

This form is equivalent to using let-values to receive +multiple results from expr, and then assigning the results +individually to the ids using set!.

Examples:
(define game
  (let ([w 0]
        [l 0])
    (lambda (win?)
      (if win?
          (set! w (+ w 1))
          (set! l (+ l 1)))
      (begin0
        (values w l)
        ; swap sides...
        (set!-values (w l) (values l w))))))
> (game #t)

1

0

> (game #t)

1

1

> (game #f)

1

2

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/standards.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/standards.html new file mode 100644 index 00000000..f6d9ebfd --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/standards.html @@ -0,0 +1,31 @@ + +23.2 Standards

23.2 Standards

Standard dialects of Scheme include the ones defined by R5RS and +R6RS.

23.2.1 R5RS

“R5RS” stands for The +Revised5 Report on the Algorithmic Language Scheme, and +it is currently the most widely implemented Scheme standard.

Racket tools in their default modes do not conform to R5RS, +mainly because Racket tools generally expect modules, and R5RS +does not define a module system. Typical single-file R5RS programs +can be converted to Racket programs by prefixing them with +#lang r5rs, but other Scheme +systems do not recognize #lang r5rs. The plt-r5rs executable (see +plt-r5rs) more directly +conforms to the R5RS standard.

Aside from the module system, the syntactic forms and functions of +R5RS and Racket differ. Only simple R5RS become Racket +programs when prefixed with #lang racket, and +relatively few Racket programs become R5RS programs when a +#lang line is removed. Also, when mixing “R5RS modules” +with Racket modules, beware that R5RS pairs correspond to +Racket mutable pairs (as constructed with mcons).

See R5RS: Legacy Scheme for more +information about running R5RS programs with Racket.

23.2.2 R6RS

“R6RS” stands for The +Revised6 Report on the Algorithmic Language Scheme, +which extends R5RS with a module system that is similar to the +Racket module system.

When an R6RS library or top-level program is prefixed with +#!r6rs (which is valid R6RS +syntax), then it can also be used as a Racket program. This works +because #! in Racket is treated as a shorthand +for #lang followed by a space, so +#!r6rs selects the +r6rs module language. As with R5RS, however, beware +that the syntactic forms and functions of R6RS differ from +Racket, and R6RS pairs are mutable pairs.

See R6RS: Scheme for more +information about running R6RS programs with Racket.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/strings.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/strings.html new file mode 100644 index 00000000..be69709f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/strings.html @@ -0,0 +1,28 @@ + +3.4 Strings (Unicode)

3.4 Strings (Unicode)

A string is a fixed-length array of +characters. It prints using double quotes, +where double quote and backslash characters within the string are +escaped with backslashes. Other common string escapes are supported, +including \n for a linefeed, \r for a +carriage return, octal escapes using \ followed by up +to three octal digits, and hexadecimal escapes with \u +(up to four digits). Unprintable characters in a string are normally +shown with \u when the string is printed.

+Reading Strings in The Racket Reference documents the fine points of the syntax of strings.

The display procedure directly writes the characters of a +string to the current output port (see Input and Output), in contrast +to the string-constant syntax used to print a string result.

Examples:
> "Apple"

"Apple"

> "\u03BB"

"λ"

> (display "Apple")

Apple

> (display "a \"quoted\" thing")

a "quoted" thing

> (display "two\nlines")

two

lines

> (display "\u03BB")

λ

A string can be mutable or immutable; strings written directly as +expressions are immutable, but most other strings are mutable. The +make-string procedure creates a mutable string given a length +and optional fill character. The string-ref procedure +accesses a character from a string (with 0-based indexing); the +string-set! procedure changes a character in a mutable +string.

Examples:
> (string-ref "Apple" 0)

#\A

> (define s (make-string 5 #\.))
> s

"....."

> (string-set! s 2 #\λ)
> s

"..λ.."

String ordering and case operations are generally +locale-independent; that is, they work the same for all +users. A few locale-dependent operations are provided that +allow the way that strings are case-folded and sorted to depend on the +end-user’s locale. If you’re sorting strings, for example, use +string<? or string-ci<? if the sort result should be +consistent across machines and users, but use string-locale<? +or string-locale-ci<? if the sort is purely to order strings +for an end user.

Examples:
> (string<? "apple" "Banana")

#f

> (string-ci<? "apple" "Banana")

#t

> (string-upcase "Straße")

"STRASSE"

> (parameterize ([current-locale "C"])
    (string-locale-upcase "Straße"))

"STRAßE"

For working with plain ASCII, working with raw bytes, or +encoding/decoding Unicode strings as bytes, use +byte strings.

+Strings in The Racket Reference provides more on strings and string procedures.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-certs.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-certs.html new file mode 100644 index 00000000..e7df3d9f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-certs.html @@ -0,0 +1,34 @@ + +16.2.7 Tainted Syntax
16.2.7 Tainted Syntax

Modules often contain definitions that are meant only for use within +the same module and not exported with provide. Still, a use +of a macro defined in the module can expand into a reference of an +unexported identifier. In general, such an identifier must not be +extracted from the expanded expression and used in a different +context, because using the identifier in a different context may break +invariants of the macro’s module.

For example, the following module exports a macro go that +expands to a use of unchecked-go:

"m.rkt"

#lang racket
(provide go)
 
(define (unchecked-go n x)
  ; to avoid disaster, n must be a number
  (+ n 17))
 
(define-syntax (go stx)
  (syntax-case stx ()
    [(_ x)
     #'(unchecked-go 8 x)]))

If the reference to unchecked-go is extracted from the +expansion of (go 'a), then it might be inserted into a new +expression, (unchecked-go #f 'a), leading to disaster. The +datum->syntax procedure can be used similarly to construct +references to an unexported identifier, even when no macro expansion +includes a reference to the identifier.

Ultimately, protection of a module’s private bindings depends on +changing the current code inspector by setting the +current-code-inspector parameter. See also +Code Inspectors for Trusted and Untrusted Code. That’s because a code inspector +controls access to a module’s internal state through functions like +module->namespace. The current code inspector also gates +access to the protected exports of unsafe modules like +racket/unsafe/ops.

Since the result of macro expansion can be abused to gain access to +protected bindings, macro functions like local-expand are +also protected: references to local-expand and similar +are allowed only within modules that are declared while the original +code inspector is the current code inspector. Functions like +expand, which are not used to implement macros but are used +to inspect the result of macro expansion, are protected in a different +way: the expansion result is tainted so that it cannot be +compiled or expanded again. More precisely, functions like +expand accept an optional inspector argument that determines +whether the result is tainted, but the default value of the argument +is (current-code-inspector).

In previous versions of Racket, a macro was responsible +for protecting expansion using syntax-protect. The use of +syntax-protect is no longer required or recommended.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-obj.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-obj.html new file mode 100644 index 00000000..65da23ea --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-obj.html @@ -0,0 +1,40 @@ + +16.2.1 Syntax Objects
16.2.1 Syntax Objects

The input and output of a macro transformer (i.e., source and +replacement forms) are represented as syntax objects. A +syntax object contains symbols, lists, and constant values (such as +numbers) that essentially correspond to the quoted form of +the expression. For example, a representation of the expression +(+ 1 2) contains the symbol '+ and the numbers +1 and 2, all in a list. In addition to this quoted +content, a syntax object associates source-location and +lexical-binding information with each part of the form. The +source-location information is used when reporting syntax errors (for +example), and the lexical-binding information allows the macro system +to maintain lexical scope. To accommodate this extra information, the +representation of the expression (+ 1 2) is not merely +'(+ 1 2), but a packaging of '(+ 1 2) into a syntax +object.

To create a literal syntax object, use the syntax form:

> (syntax (+ 1 2))

#<syntax:eval:1:0 (+ 1 2)>

In the same way that ' abbreviates quote, +#' abbreviates syntax:

> #'(+ 1 2)

#<syntax:eval:1:0 (+ 1 2)>

A syntax object that contains just a symbol is an identifier +syntax object. Racket provides some additional operations specific to +identifier syntax objects, including the identifier? +operation to detect identifiers. Most notably, +free-identifier=? determines whether two identifiers refer +to the same binding:

> (identifier? #'car)

#t

> (identifier? #'(+ 1 2))

#f

> (free-identifier=? #'car #'cdr)

#f

> (free-identifier=? #'car #'car)

#t

> (require (only-in racket/base [car also-car]))
> (free-identifier=? #'car #'also-car)

#t

To see the lists, symbols, numbers, etc. within a syntax object, use +syntax->datum:

> (syntax->datum #'(+ 1 2))

'(+ 1 2)

The syntax-e function is similar to syntax->datum, +but it unwraps a single layer of source-location and lexical-context +information, leaving sub-forms that have their own information wrapped +as syntax objects:

> (syntax-e #'(+ 1 2))

'(#<syntax:eval:1:0 +> #<syntax:eval:1:0 1> #<syntax:eval:1:0 2>)

The syntax-e function always leaves syntax-object wrappers +around sub-forms that are represented via symbols, numbers, and other +literal values. The only time it unwraps extra sub-forms is when +unwrapping a pair, in which case the cdr of the pair may be +recursively unwrapped, depending on how the syntax object was +constructed.

The opposite of syntax->datum is, of course, +datum->syntax. In addition to a datum like '(+ 1 2), datum->syntax needs an existing syntax object to donate +its lexical context, and optionally another syntax object to donate +its source location:

> (datum->syntax #'lex
                 '(+ 1 2)
                 #'srcloc)

#<syntax:eval:1:0 (+ 1 2)>

In the above example, the lexical context of #'lex is used +for the new syntax object, while the source location of +#'srcloc is used.

When the second (i.e., the “datum”) argument to +datum->syntax includes syntax objects, those syntax objects +are preserved intact in the result. That is, deconstructing the result +with syntax-e eventually produces the syntax objects that +were given to datum->syntax.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-phases.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-phases.html new file mode 100644 index 00000000..bfbecd5a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/stx-phases.html @@ -0,0 +1,65 @@ + +16.2.5 Compile and Run-Time Phases
16.2.5 Compile and Run-Time Phases

As sets of macros get more complicated, you might want to write +your own helper functions, like +generate-temporaries. For example, to provide good +syntax error messages, swap, rotate, and +define-cbr all should check that certain sub-forms in +the source form are identifiers. We could use a +check-ids function to perform this checking everywhere:

(define-syntax (swap stx)
  (syntax-case stx ()
    [(swap x y) (begin
                  (check-ids stx #'(x y))
                  #'(let ([tmp x])
                      (set! x y)
                      (set! y tmp)))]))
 
(define-syntax (rotate stx)
  (syntax-case stx ()
    [(rotate a c ...)
     (begin
       (check-ids stx #'(a c ...))
       #'(shift-to (c ... a) (a c ...)))]))

The check-ids function can use the syntax->list +function to convert a syntax-object wrapping a list into a list +of syntax objects:

(define (check-ids stx forms)
  (for-each
   (lambda (form)
     (unless (identifier? form)
       (raise-syntax-error #f
                           "not an identifier"
                           stx
                           form)))
   (syntax->list forms)))

If you define swap and check-ids in this way, +however, it doesn’t work:

> (let ([a 1] [b 2]) (swap a b))

check-ids: undefined;

 cannot reference an identifier before its definition

  in module: top-level

The problem is that check-ids is defined as a run-time +expression, but swap is trying to use it at compile time. In +interactive mode, compile time and run time are interleaved, but they +are not interleaved within the body of a module, and they are not +interleaved across modules that are compiled ahead-of-time. To help +make all of these modes treat code consistently, Racket separates the +binding spaces for different phases.

To define a check-ids function that can be referenced at +compile time, use begin-for-syntax:

(begin-for-syntax
  (define (check-ids stx forms)
    (for-each
     (lambda (form)
       (unless (identifier? form)
         (raise-syntax-error #f
                             "not an identifier"
                             stx
                             form)))
     (syntax->list forms))))

With this for-syntax definition, then swap works:

> (let ([a 1] [b 2]) (swap a b) (list a b))

'(2 1)

> (swap a 1)

eval:13:0: swap: not an identifier

  at: 1

  in: (swap a 1)

When organizing a program into modules, you may want to put helper +functions in one module to be used by macros that reside on other +modules. In that case, you can write the helper function using +define:

"utils.rkt"

#lang racket
 
(provide check-ids)
 
(define (check-ids stx forms)
  (for-each
   (lambda (form)
     (unless (identifier? form)
       (raise-syntax-error #f
                           "not an identifier"
                           stx
                           form)))
   (syntax->list forms)))

Then, in the module that implements macros, import the helper function +using (require (for-syntax "utils.rkt")) instead of +(require "utils.rkt"):

#lang racket
 
(require (for-syntax "utils.rkt"))
 
(define-syntax (swap stx)
  (syntax-case stx ()
    [(swap x y) (begin
                  (check-ids stx #'(x y))
                  #'(let ([tmp x])
                      (set! x y)
                      (set! y tmp)))]))

Since modules are separately compiled and cannot have circular +dependencies, the "utils.rkt" module’s run-time body can be +compiled before compiling the module that implements +swap. Thus, the run-time definitions in +"utils.rkt" can be used to implement swap, as long +as they are explicitly shifted into compile time by (require (for-syntax ....)).

The racket module provides syntax-case, +generate-temporaries, lambda, if, and more +for use in both the run-time and compile-time phases. That is why we +can use syntax-case in the racket REPL both +directly and in the right-hand side of a define-syntax +form.

The racket/base module, in contrast, exports those +bindings only in the run-time phase. If you change the module above +that defines swap so that it uses the +racket/base language instead of +racket, then it no longer works. Adding +(require (for-syntax racket/base)) imports +syntax-case and more into the compile-time phase, so that the +module works again.

Suppose that define-syntax is used to define a local macro in +the right-hand side of a define-syntax form. In that case, +the right-hand side of the inner define-syntax is in the +meta-compile phase level, also known as phase level +2. To import syntax-case into that phase level, you would +have to use (require (for-syntax (for-syntax racket/base))) +or, equivalently, (require (for-meta 2 racket/base)). For example,

#lang racket/base
(require  ;; This provides the bindings for the definition
          ;; of shell-game.
          (for-syntax racket/base)
 
          ;; And this for the definition of
          ;; swap.
          (for-syntax (for-syntax racket/base)))
 
(define-syntax (shell-game stx)
 
  (define-syntax (swap stx)
    (syntax-case stx ()
      [(_ a b)
       #'(let ([tmp a])
           (set! a b)
           (set! b tmp))]))
 
  (syntax-case stx ()
    [(_ a b c)
     (let ([a #'a] [b #'b] [c #'c])
       (when (= 0 (random 2)) (swap a b))
       (when (= 0 (random 2)) (swap b c))
       (when (= 0 (random 2)) (swap a c))
       #`(list #,a #,b #,c))]))
 
(shell-game 3 4 5)
(shell-game 3 4 5)
(shell-game 3 4 5)

Negative phase levels also exist. If a macro uses a helper function +that is imported for-syntax, and if the helper function +returns syntax-object constants generated by syntax, then +identifiers in the syntax will need bindings at phase level +-1, also known as the template phase level, to have any +binding at the run-time phase level relative to the module that +defines the macro.

For instance, the swap-stx helper function in the example below +is not a syntax transformer—it’s just an ordinary function—but it +produces syntax objects that get spliced into the result of +shell-game. Therefore, its containing helper submodule +needs to be imported at shell-game’s phase 1 with +(require (for-syntax 'helper)).

But from the perspective of swap-stx, its results will ultimately +be evaluated at phase level -1, when the syntax +returned by shell-game is evaluated. In other words, a negative phase +level is a positive phase level from the opposite direction: +shell-game’s phase 1 is swap-stx’s phase 0, so +shell-game’s phase 0 is swap-stx’s phase -1. +And that’s why this example won’t work—the 'helper submodule +has no bindings at phase -1.

#lang racket/base
(require (for-syntax racket/base))
 
(module helper racket/base
  (provide swap-stx)
  (define (swap-stx a-stx b-stx)
    #`(let ([tmp #,a-stx])
          (set! #,a-stx #,b-stx)
          (set! #,b-stx tmp))))
 
(require (for-syntax 'helper))
 
(define-syntax (shell-game stx)
  (syntax-case stx ()
    [(_ a b c)
     #`(begin
         #,(swap-stx #'a #'b)
         #,(swap-stx #'b #'c)
         #,(swap-stx #'a #'c)
         (list a b c))]))
 
(define x 3)
(define y 4)
(define z 5)
(shell-game x y z)

To repair this example, we add (require (for-template racket/base)) +to the 'helper submodule.

#lang racket/base
(require (for-syntax racket/base))
 
(module helper racket/base
  (require (for-template racket/base)) ; binds `let` and `set!` at phase -1
  (provide swap-stx)
  (define (swap-stx a-stx b-stx)
    #`(let ([tmp #,a-stx])
          (set! #,a-stx #,b-stx)
          (set! #,b-stx tmp))))
 
(require (for-syntax 'helper))
 
(define-syntax (shell-game stx)
  (syntax-case stx ()
    [(_ a b c)
     #`(begin
         #,(swap-stx #'a #'b)
         #,(swap-stx #'b #'c)
         #,(swap-stx #'a #'c)
         (list a b c))]))
 
(define x 3)
(define y 4)
(define z 5)
(shell-game x y z)
(shell-game x y z)
(shell-game x y z)
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/symbols.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/symbols.html new file mode 100644 index 00000000..99d50e9f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/symbols.html @@ -0,0 +1,28 @@ + +3.6 Symbols

3.6 Symbols

A symbol is an atomic value that prints like an identifier +preceded with '. An expression that starts with ' +and continues with an identifier produces a symbol value.

Examples:
> 'a

'a

> (symbol? 'a)

#t

For any sequence of characters, exactly one corresponding symbol is +interned; calling the string->symbol procedure, or +reading a syntactic identifier, produces an interned +symbol. Since interned symbols can be cheaply compared with +eq? (and thus eqv? or equal?), they serve +as a convenient values to use for tags and enumerations.

Symbols are case-sensitive. By using a #ci prefix or in +other ways, the reader can be made to case-fold character sequences to +arrive at a symbol, but the reader preserves case by default.

Examples:
> (eq? 'a 'a)

#t

> (eq? 'a (string->symbol "a"))

#t

> (eq? 'a 'b)

#f

> (eq? 'a 'A)

#f

> #ci'A

'a

Any string (i.e., any character sequence) can be supplied to +string->symbol to obtain the corresponding symbol. For reader +input, any character can appear directly in an identifier, except for +whitespace and the following special characters:

   ( ) [ ] +{ } +" , ' ` +; # | \

Actually, # is disallowed only at the beginning of a symbol, +and then only if not followed by %; otherwise, # is +allowed, too. Also, . by itself is not a symbol.

Whitespace or special characters can be included in an identifier by +quoting them with | or \. These quoting +mechanisms are used in the printed form of identifiers that contain +special characters or that might otherwise look like numbers.

Examples:
> (string->symbol "one, two")

'|one, two|

> (string->symbol "6")

'|6|

+Reading Symbols in The Racket Reference documents the fine points of the syntax of symbols.

The write function prints a symbol without a ' +prefix. The display form of a symbol is the same as the +corresponding string.

Examples:
> (write 'Apple)

Apple

> (display 'Apple)

Apple

> (write '|6|)

|6|

> (display '|6|)

6

The gensym and string->uninterned-symbol procedures +generate fresh uninterned symbols that are not equal +(according to eq?) to any previously interned or uninterned +symbol. Uninterned symbols are useful as fresh tags that cannot be +confused with any other value.

Examples:
> (define s (gensym))
> s

'g42

> (eq? s 'g42)

#f

> (eq? 'a (string->uninterned-symbol "a"))

#f

+Symbols in The Racket Reference provides more on symbols.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-case.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-case.html new file mode 100644 index 00000000..c79c799a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-case.html @@ -0,0 +1,32 @@ + +16.2.3 Mixing Patterns and Expressions: syntax-case
16.2.3 Mixing Patterns and Expressions: syntax-case

The procedure generated by syntax-rules internally uses +syntax-e to deconstruct the given syntax object, and it uses +datum->syntax to construct the result. The +syntax-rules form doesn’t provide a way to escape from +pattern-matching and template-construction mode into an arbitrary +Racket expression.

The syntax-case form lets you mix pattern matching, template +construction, and arbitrary expressions:

(syntax-case stx-expr (literal-id ...)
  [pattern expr]
  ...)

Unlike syntax-rules, the syntax-case form does not +produce a procedure. Instead, it starts with a stx-expr +expression that determines the syntax object to match against the +patterns. Also, each syntax-case clause has a +pattern and expr, instead of a pattern +and template. Within an expr, the syntax +form—usually abbreviated with #'shifts into +template-construction mode; if the expr of a clause starts +with #', then we have something like a syntax-rules +form:

> (syntax->datum
   (syntax-case #'(+ 1 2) ()
    [(op n1 n2) #'(- n1 n2)]))

'(- 1 2)

We could write the swap macro using syntax-case +instead of define-syntax-rule or syntax-rules:

(define-syntax (swap stx)
  (syntax-case stx ()
    [(swap x y) #'(let ([tmp x])
                    (set! x y)
                    (set! y tmp))]))

One advantage of using syntax-case is that we can provide +better error reporting for swap. For example, with the +define-syntax-rule definition of swap, then +(swap x 2) produces a syntax error in terms of set!, +because 2 is not an identifier. We can refine our +syntax-case implementation of swap to explicitly +check the sub-forms:

(define-syntax (swap stx)
  (syntax-case stx ()
    [(swap x y)
     (if (and (identifier? #'x)
              (identifier? #'y))
         #'(let ([tmp x])
             (set! x y)
             (set! y tmp))
         (raise-syntax-error #f
                             "not an identifier"
                             stx
                             (if (identifier? #'x)
                                 #'y
                                 #'x)))]))

With this definition, (swap x 2) provides a syntax error +originating from swap instead of set!.

In the above definition of swap, #'x and +#'y are templates, even though they are not used as the +result of the macro transformer. This example illustrates how +templates can be used to access pieces of the input syntax, in this +case for checking the form of the pieces. Also, the match for +#'x or #'y is used in the call to +raise-syntax-error, so that the syntax-error message can +point directly to the source location of the non-identifier.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-notation.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-notation.html new file mode 100644 index 00000000..f9b69833 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-notation.html @@ -0,0 +1,26 @@ + +4.1 Notation

4.1 Notation

This chapter (and the rest of the documentation) uses a slightly +different notation than the character-based grammars of the +Racket Essentials chapter. The grammar for a use of a syntactic +form something is shown like this:

(something [id ...+] an-expr ...)

The italicized meta-variables in this specification, such as +id and an-expr, use the syntax of Racket +identifiers, so an-expr is one meta-variable. A naming +convention implicitly defines the meaning of many meta-variables:

  • A meta-variable that ends in id stands for an +identifier, such as x or +my-favorite-martian.

  • A meta-identifier that ends in keyword stands +for a keyword, such as #:tag.

  • A meta-identifier that ends with expr stands for any +sub-form, and it will be parsed as an expression.

  • A meta-identifier that ends with body stands for any +sub-form; it will be parsed as either a local definition or an +expression. The last body must be an expression; +see also Internal Definitions.

Square brackets in the grammar indicate a parenthesized sequence of +forms, where square brackets are normally used (by convention). That +is, square brackets do not mean optional parts of the +syntactic form.

A ... indicates zero or more repetitions of the +preceding form, and ...+ indicates one or more +repetitions of the preceding datum. Otherwise, non-italicized +identifiers stand for themselves.

Based on the above grammar, then, here are a few conforming uses of +something:

(something [x])
(something [x] (+ 1 2))
(something [x my-favorite-martian x] (+ 1 2) #f)

Some syntactic-form specifications refer to meta-variables that are +not implicitly defined and not previously defined. Such meta-variables +are defined after the main form, using a BNF-like format for +alternatives:

(something-else [thing ...+] an-expr ...)
 
thing = thing-id
  | thing-keyword

The above example says that, within a something-else +form, a thing is either an identifier or a keyword.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-overview.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-overview.html new file mode 100644 index 00000000..ff1752ad --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax-overview.html @@ -0,0 +1,145 @@ + +2.2 Simple Definitions and Expressions

2.2 Simple Definitions and Expressions

A program module is written as

#lang langname topform*

where a topform is either a definition or an +expr. The REPL also evaluates topforms.

In syntax specifications, text with a gray background, such as +#lang, represents literal text. Whitespace must appear +between such literals and nonterminals like id, +except that whitespace is not required before or after (, +), [, or ]. A comment, which starts +with ; and runs until the end of the line, is treated the +same as whitespace.

+Reading Comments in The Racket Reference provides more on different forms of comments.

Following the usual conventions, * in a grammar means zero +or more repetitions of the preceding element, + means one +or more repetitions of the preceding element, and {} groups +a sequence as an element for repetition.

2.2.1 Definitions

A definition of the form

+Definitions: define (later in this guide) explains more about definitions.

( define id expr )

binds id to the result of expr, while

( define ( id id* ) expr+ )

binds the first id to a function (also called a +procedure) that takes arguments as named by the remaining +ids. In the function case, the exprs are the body +of the function. When the function is called, it returns the result of +the last expr.

Examples:
(define pie 3)             ; defines pie to be 3
(define (piece str)        ; defines piece as a function
  (substring str 0 pie))   ;  of one argument
> pie

3

> (piece "key lime")

"key"

Under the hood, a function definition is really the same as a +non-function definition, and a function name does not have to be +used in a function call. A function is just another kind of value, +though the printed form is necessarily less complete than the printed +form of a number or string.

Examples:
> piece

#<procedure:piece>

> substring

#<procedure:substring>

A function definition can include multiple expressions for the +function’s body. In that case, only the value of the last expression +is returned when the function is called. The other expressions are +evaluated only for some side-effect, such as printing.

Examples:
(define (bake flavor)
  (printf "preheating oven...\n")
  (string-append flavor " pie"))
> (bake "apple")

preheating oven...

"apple pie"

Racket programmers prefer to avoid side-effects, so a definition usually +has just one expression in its body. It’s +important, though, to understand that multiple expressions are allowed +in a definition body, because it explains why the following +nobake function fails to include its argument in its result:

(define (nobake flavor)
  string-append flavor "jello")

 

> (nobake "green")

"jello"

Within nobake, there are no parentheses around +string-append flavor "jello", so they are three separate +expressions instead of one function-call expression. The expressions +string-append and flavor are evaluated, but the +results are never used. Instead, the result of the function is just +the result of the final expression, "jello".

2.2.2 An Aside on Indenting Code

Line breaks and indentation are not significant for parsing Racket +programs, but most Racket programmers use a standard set of conventions +to make code more readable. For example, the body of a definition is +typically indented under the first line of the definition. Identifiers +are written immediately after an open parenthesis with no extra space, +and closing parentheses never go on their own line.

DrRacket automatically indents according to the standard style when +you type Enter in a program or REPL expression. For example, if you +hit Enter after typing (define (greet name), then DrRacket +automatically inserts two spaces for the next line. If you change a +region of code, you can select it in DrRacket and hit Tab, and +DrRacket will re-indent the code (without inserting any line breaks). +Editors like Emacs offer a Racket or Scheme mode with similar indentation +support.

Re-indenting not only makes the code easier to read, it gives you +extra feedback that your parentheses match in the way that you +intended. For example, if you leave out a closing parenthesis after +the last argument to a function, automatic indentation starts the +next line under the first argument, instead of under the +define keyword:

(define (halfbake flavor
                  (string-append flavor " creme brulee")))

In this case, indentation helps highlight the mistake. In other cases, +where the indentation may be normal while an open parenthesis has no +matching close parenthesis, both racket and DrRacket use the +source’s indentation to suggest where a parenthesis might be missing.

2.2.3 Identifiers

Racket’s syntax for identifiers is especially liberal. Excluding the +special characters

+Identifiers and Binding (later in this guide) explains more about identifiers.

   ( ) [ ] +{ } +" , ' ` +; # | \

and except for the sequences of characters that make number constants, +almost any sequence of non-whitespace characters forms an +id. For example substring is an +identifier. Also, string-append and a+b are +identifiers, as opposed to arithmetic expressions. Here are several +more examples:

+
integer?
pass/fail
Hfuhruhurr&Uumellmahaye
john-jacob-jingleheimer-schmidt
a-b-c+1-2-3
2.2.4 Function Calls (Procedure Applications)

We have already seen many function calls, which are called +procedure applications in more traditional +terminology. The syntax of a function call is

+Function Calls (later in this guide) explains more about function calls.

( id expr* )

where the number of exprs determines the number of +arguments supplied to the function named by id.

The racket language pre-defines many function +identifiers, such as substring and +string-append. More examples are below.

In example Racket code throughout the documentation, uses of +pre-defined names are hyperlinked to the reference manual. So, you can +click on an identifier to get full details about its use.

> (string-append "rope" "twine" "yarn")  ; append strings

"ropetwineyarn"

> (substring "corduroys" 0 4)            ; extract a substring

"cord"

> (string-prefix? "shoelace" "shoe")     ; recognize string prefix/suffix

#t

> (string-suffix? "shoelace" "shoe")

#f

> (string? "Ceci n'est pas une string.") ; recognize strings

#t

> (string? 1)

#f

> (sqrt 16)                              ; find a square root

4

> (sqrt -16)

0+4i

> (+ 1 2)                                ; add numbers

3

> (- 2 1)                                ; subtract numbers

1

> (< 2 1)                                ; compare numbers

#f

> (>= 2 1)

#t

> (number? "c'est une number")           ; recognize numbers

#f

> (number? 1)

#t

> (equal? 6 "half dozen")                ; compare anything

#f

> (equal? 6 6)

#t

> (equal? "half dozen" "half dozen")

#t

2.2.5 Conditionals with if, and, or, and cond

The next simplest kind of expression is an if conditional:

( if expr expr expr )

+Conditionals (later in this guide) explains more about conditionals.

The first expr is always evaluated. If it produces a +non-#f value, then the second expr is +evaluated for the result of the whole if expression, otherwise +the third expr is evaluated for the result.

Example:
> (if (> 2 3)
      "2 is bigger than 3"
      "2 is smaller than 3")

"2 is smaller than 3"

(define (reply s)
  (if (string-prefix? s "hello ")
      "hi!"
      "huh?"))

 

> (reply "hello racket")

"hi!"

> (reply "λx:(μα.α→α).xx")

"huh?"

Complex conditionals can be formed by nesting if +expressions. For example, in the previous reply example, +the input must be a string because string-prefix? +would error when given non-strings. You can remove this restriction +by adding another if to check first if the input is a string:

(define (reply-non-string s)
  (if (string? s)
      (if (string-prefix? s "hello ")
          "hi!"
          "huh?")
      "huh?"))

Instead of duplicating the "huh?" case, this function is +better written as

(define (reply-non-string s)
  (if (if (string? s)
          (string-prefix? s "hello ")
          #f)
      "hi!"
      "huh?"))

but these kinds of nested ifs are difficult to read. Racket +provides more readable shortcuts through the and and +or forms:

+Combining Tests: and and or (later in this guide) explains more about and and or.

( and expr* )
( or expr* )

The and form short-circuits: it stops and returns #f +when an expression produces #f, otherwise it keeps +going. The or form similarly short-circuits when it +encounters a true result.

Examples:
(define (reply-non-string s)
  (if (and (string? s) (string-prefix? s "hello "))
      "hi!"
      "huh?"))
> (reply-non-string "hello racket")

"hi!"

> (reply-non-string 17)

"huh?"

Note that in the above grammar, the and and or forms +work with any number of expressions.

Examples:
(define (reply-only-enthusiastic s)
  (if (and (string? s)
           (string-prefix? s "hello ")
           (string-suffix? s "!"))
      "hi!"
      "huh?"))
> (reply-only-enthusiastic "hello racket!")

"hi!"

> (reply-only-enthusiastic "hello racket")

"huh?"

Another common pattern of nested ifs involves a sequence of +tests, each with its own result:

(define (reply-more s)
  (if (string-prefix? s "hello ")
      "hi!"
      (if (string-prefix? s "goodbye ")
          "bye!"
          (if (string-suffix? s "?")
              "I don't know"
              "huh?"))))

The shorthand for a sequence of tests is the cond form:

+Chaining Tests: cond (later in this guide) explains more about cond.

( cond {[ expr expr* ]}* )

A cond form contains a sequence of clauses between square +brackets. In each clause, the first expr is a test +expression. If it produces true, then the clause’s remaining +exprs are evaluated, and the last one in the clause provides +the answer for the entire cond expression; the rest of the +clauses are ignored. If the test expr produces #f, +then the clause’s remaining exprs are ignored, and +evaluation continues with the next clause. The last clause can use +else as a synonym for a #t test expression.

Using cond, the reply-more function can be more +clearly written as follows:

(define (reply-more s)
  (cond
   [(string-prefix? s "hello ")
    "hi!"]
   [(string-prefix? s "goodbye ")
    "bye!"]
   [(string-suffix? s "?")
    "I don't know"]
   [else "huh?"]))

 

> (reply-more "hello racket")

"hi!"

> (reply-more "goodbye cruel world")

"bye!"

> (reply-more "what is your favorite color?")

"I don't know"

> (reply-more "mine is lime green")

"huh?"

The use of square brackets for cond clauses is a +convention. In Racket, parentheses and square brackets are actually +interchangeable, as long as ( is matched with ) and +[ is matched with ]. Using square brackets in a +few key places makes Racket code even more readable.

2.2.6 Function Calls, Again

In our earlier grammar of function calls, we oversimplified. The +actual syntax of a function call allows an arbitrary +expression for the function, instead of just an id:

+Function Calls (later in this guide) explains more about function calls.

( expr expr* )

The first expr is often an id, such +as string-append or +, but it can be anything that +evaluates to a function. For example, it can be a conditional +expression:

(define (double v)
  ((if (string? v) string-append +) v v))

 

> (double "mnah")

"mnahmnah"

> (double 5)

10

Syntactically, the first expression in a function call could +even be a number—but that leads to an error, since a number is not a +function.

> (1 2 3 4)

application: not a procedure;

 expected a procedure that can be applied to arguments

  given: 1

When you accidentally omit a function name or when you use +extra parentheses around an expression, you’ll most often get an “expected +a procedure” error like this one.

2.2.7 Anonymous Functions with lambda

Programming in Racket would be tedious if you had to name all of your +numbers. Instead of writing (+ 1 2), you’d have to write

+Functions: lambda (later in this guide) explains more about lambda.

> (define a 1)
> (define b 2)
> (+ a b)

3

It turns out that having to name all your functions can be tedious, +too. For example, you might have a function twice that takes +a function and an argument. Using twice is convenient if you +already have a name for the function, such as sqrt:

(define (twice f v)
  (f (f v)))

 

> (twice sqrt 16)

2

If you want to call a function that is not yet defined, you could +define it, and then pass it to twice:

(define (louder s)
  (string-append s "!"))

 

> (twice louder "hello")

"hello!!"

But if the call to twice is the only place where +louder is used, it’s a shame to have to write a whole +definition. In Racket, you can use a lambda expression to +produce a function directly. The lambda form is followed by +identifiers for the function’s arguments, and then the function’s +body expressions:

( lambda ( id* ) expr+ )

Evaluating a lambda form by itself produces a function:

> (lambda (s) (string-append s "!"))

#<procedure>

Using lambda, the above call to twice can be +re-written as

> (twice (lambda (s) (string-append s "!"))
         "hello")

"hello!!"

> (twice (lambda (s) (string-append s "?!"))
         "hello")

"hello?!?!"

Another use of lambda is as a result for a function that +generates functions:

(define (make-add-suffix s2)
  (lambda (s) (string-append s s2)))

 

> (twice (make-add-suffix "!") "hello")

"hello!!"

> (twice (make-add-suffix "?!") "hello")

"hello?!?!"

> (twice (make-add-suffix "...") "hello")

"hello......"

Racket is a lexically scoped language, which means that +s2 in the function returned by make-add-suffix +always refers to the argument for the call that created the +function. In other words, the lambda-generated function +“remembers” the right s2:

> (define louder (make-add-suffix "!"))
> (define less-sure (make-add-suffix "?"))
> (twice less-sure "really")

"really??"

> (twice louder "really")

"really!!"

We have so far referred to definitions of the form (define id expr) as “non-function +definitions.” This characterization is misleading, because the +expr could be a lambda form, in which case +the definition is equivalent to using the “function” definition +form. For example, the following two definitions of louder +are equivalent:

(define (louder s)
  (string-append s "!"))
 
(define louder
  (lambda (s)
    (string-append s "!")))

 

> louder

#<procedure:louder>

Note that the expression for louder in the second case is an +“anonymous” function written with lambda, but, if +possible, the compiler infers a name, anyway, to make printing and +error reporting as informative as possible.

2.2.8 Local Binding with +define, let, and let*

It’s time to retract another simplification in our grammar of +Racket. In the body of a function, definitions can appear before the +body expressions:

+Internal Definitions (later in this guide) explains more about local (internal) definitions.

( define ( id id* ) definition* expr+ )
( lambda ( id* ) definition* expr+ )

Definitions at the start of a function body are local to the +function body.

Examples:
(define (converse s)
  (define (starts? s2) ; local to converse
    (define spaced-s2 (string-append s2 " ")) ; local to starts?
    (string-prefix? s spaced-s2))
  (cond
   [(starts? "hello") "hi!"]
   [(starts? "goodbye") "bye!"]
   [else "huh?"]))
> (converse "hello world")

"hi!"

> (converse "hellonearth")

"huh?"

> (converse "goodbye friends")

"bye!"

> (converse "urp")

"huh?"

> starts? ; outside of converse, so...

starts?: undefined;

 cannot reference an identifier before its definition

  in module: top-level

Another way to create local bindings is the let form. An +advantage of let is that it can be used in any expression +position. Also, let binds many identifiers at once, instead +of requiring a separate define for each identifier.

+Internal Definitions (later in this guide) explains more about let and let*.

( let ( {[ id expr ]}* ) expr+ )

Each binding clause is an id and an +expr surrounded by square brackets, and the +expressions after the clauses are the body of the let. In +each clause, the id is bound to the result of the +expr for use in the body.

> (let ([x (random 4)]
        [o (random 4)])
    (cond
     [(> x o) "X wins"]
     [(> o x) "O wins"]
     [else "cat's game"]))

"O wins"

The bindings of a let form are available only in the body of +the let, so the binding clauses cannot refer to each +other. The let* form, in contrast, allows later clauses to +use earlier bindings:

> (let* ([x (random 4)]
         [o (random 4)]
         [diff (number->string (abs (- x o)))])
    (cond
     [(> x o) (string-append "X wins by " diff)]
     [(> o x) (string-append "O wins by " diff)]
     [else "cat's game"]))

"cat's game"

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax_module-reader.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax_module-reader.html new file mode 100644 index 00000000..dfc8f1f0 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/syntax_module-reader.html @@ -0,0 +1,26 @@ + +17.3.3 Using #lang s-exp syntax/module-reader
17.3.3 Using #lang s-exp syntax/module-reader

Parsing a module body is usually not as trivial as in +"literal.rkt". A more typical module parser must iterate to +parse multiple forms for a module body. A language is also more likely +to extend Racket syntax—perhaps through a readtableinstead +of replacing Racket syntax completely.

The syntax/module-reader module language +abstracts over common parts of a language implementation to simplify +the creation of new languages. In its most basic form, a language +implemented with syntax/module-reader simply specifies +the module language to be used for the language, in which case +the reader layer of the language is the same as Racket. For +example, with

"raquet-mlang.rkt"

#lang racket
(provide (except-out (all-from-out racket) lambda)
         (rename-out [lambda function]))

and

"raquet.rkt"

#lang s-exp syntax/module-reader
"raquet-mlang.rkt"

then

#lang reader "raquet.rkt"
(define identity (function (x) x))
(provide identity)

implements and exports the identity function, since +"raquet-mlang.rkt" exports lambda as +function.

The syntax/module-reader language accepts many optional +specifications to adjust other features of the language. For example, +an alternate read and read-syntax for +parsing the language can be specified with #:read and +#:read-syntax, respectively. The following +"dollar-racket.rkt" language uses "dollar.rkt" (see +Readtables) to build a language that is like +racket but with a $ escape to simple infix +arithmetic:

"dollar-racket.rkt"

#lang s-exp syntax/module-reader
racket
#:read $-read
#:read-syntax $-read-syntax
 
(require (prefix-in $- "dollar.rkt"))

The require form appears at the end of the module, +because all of the keyword-tagged optional specifications for +syntax/module-reader must appear before any helper +imports or definitions.

The following module uses "dollar-racket.rkt" to implement a +cost function using a $ escape:

"store.rkt"

#lang reader "dollar-racket.rkt"
 
(provide cost)
 
; Cost of n' $1 rackets with 7% sales
; tax and shipping-and-handling fee h':
(define (cost n h)
  $n*107/100+h$)
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/teaching-langs.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/teaching-langs.html new file mode 100644 index 00000000..b69105f8 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/teaching-langs.html @@ -0,0 +1,6 @@ + +23.3 Teaching

23.3 Teaching

The How to Design Programs textbook relies on pedagogic variants of Racket that +smooth the introduction of programming concepts for new programmers. +See the How to Design Programs language documentation.

The How to Design Programs languages are typically not used with #lang +prefixes, but are instead used within DrRacket by selecting the +language from the Choose Language... dialog.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/to-scheme.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/to-scheme.html new file mode 100644 index 00000000..0e5e1e6a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/to-scheme.html @@ -0,0 +1,5 @@ + +2 Racket Essentials
 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/unit_versus_module.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/unit_versus_module.html new file mode 100644 index 00000000..e63fd79f --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/unit_versus_module.html @@ -0,0 +1,36 @@ + +14.7 unit versus module

14.7 unit versus module

As a form for modularity, unit complements module:

  • The module form is primarily for managing a universal +namespace. For example, it allows a code fragment to refer +specifically to the car operation from +racket/basethe one that extracts the first +element of an instance of the built-in pair datatype—as +opposed to any number of other functions with the name +car. In other words, the module construct lets +you refer to the binding that you want.

  • The unit form is for parameterizing a code fragment +with respect to most any kind of run-time value. For example, +it allows a code fragment to work with a car +function that accepts a single argument, where the specific +function is determined later by linking the fragment to +another. In other words, the unit construct lets you +refer to a binding that meets some specification.

The lambda and class forms, among others, also allow +parameterization of code with respect to values that are chosen +later. In principle, any of those could be implemented in terms of any +of the others. In practice, each form offers certain +conveniences—such as allowing overriding of methods or especially +simple application to values—that make them suitable for different +purposes.

The module form is more fundamental than the others, in a +sense. After all, a program fragment cannot reliably refer to a +lambda, class, or unit form without the +namespace management provided by module. At the same time, +because namespace management is closely related to separate expansion +and compilation, module boundaries end up as +separate-compilation boundaries in a way that prohibits mutual +dependencies among fragments. For similar reasons, module +does not separate interface from implementation.

Use unit when module by itself almost works, but +when separately compiled pieces must refer to each other, or when you +want a stronger separation between interface (i.e., the +parts that need to be known at expansion and compilation time) and +implementation (i.e., the run-time parts). More generally, +use unit when you need to parameterize code over functions, +datatypes, and classes, and when the parameterized code itself +provides definitions to be linked with other parameterized code.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/units.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/units.html new file mode 100644 index 00000000..9546b924 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/units.html @@ -0,0 +1,15 @@ + +14 Units

14 Units (Components)

Units organize a program into separately compilable and +reusable components. A unit resembles a procedure in that +both are first-class values that are used for abstraction. While +procedures abstract over values in expressions, units abstract over +names in collections of definitions. Just as a procedure is called to +evaluate its expressions given actual arguments for its formal +parameters, a unit is invoked to evaluate its definitions +given actual references for its imported variables. Unlike a +procedure, however, a unit’s imported variables can be partially +linked with the exported variables of another unit prior to +invocation. Linking merges multiple units together into a single +compound unit. The compound unit itself imports variables that will be +propagated to unresolved imported variables in the linked units, and +re-exports some variables from the linked units for further linking.

    14.1 Signatures and Units

    14.2 Invoking Units

    14.3 Linking Units

    14.4 First-Class Units

    14.5 Whole-module Signatures and Units

    14.6 Contracts for Units

      14.6.1 Adding Contracts to Signatures

      14.6.2 Adding Contracts to Units

    14.7 unit versus module

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/vectors.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/vectors.html new file mode 100644 index 00000000..cb746fcb --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/vectors.html @@ -0,0 +1,16 @@ + +3.9 Vectors

3.9 Vectors

A vector is a fixed-length array of arbitrary +values. Unlike a list, a vector supports constant-time access and +update of its elements.

A vector prints similar to a list—as a parenthesized sequence of its +elements—but a vector is prefixed with # after +', or it uses vector if one of its elements +cannot be expressed with quote.

For a vector as an expression, an optional length can be +supplied. Also, a vector as an expression implicitly quotes +the forms for its content, which means that identifiers and +parenthesized forms in a vector constant represent symbols and lists.

+Reading Vectors in The Racket Reference documents the fine points of the syntax of vectors.

Examples:
> #("a" "b" "c")

'#("a" "b" "c")

> #(name (that tune))

'#(name (that tune))

> #4(baldwin bruce)

'#(baldwin bruce bruce bruce)

> (vector-ref #("a" "b" "c") 1)

"b"

> (vector-ref #(name (that tune)) 1)

'(that tune)

Like strings, a vector is either mutable or immutable, and vectors +written directly as expressions are immutable.

Vectors can be converted to lists and vice versa via +vector->list and list->vector; such conversions are +particularly useful in combination with predefined procedures on +lists. When allocating extra lists seems too expensive, consider +using looping forms like for/fold, which recognize vectors as +well as lists.

Example:
> (list->vector (map string-titlecase
                     (vector->list #("three" "blind" "mice"))))

'#("Three" "Blind" "Mice")

+Vectors in The Racket Reference provides more on vectors and vector procedures.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/void_undefined.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/void_undefined.html new file mode 100644 index 00000000..73f79bfb --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/void_undefined.html @@ -0,0 +1,15 @@ + +3.12 Void and Undefined

3.12 Void and Undefined

Some procedures or expression forms have no need for a result +value. For example, the display procedure is called only for +the side-effect of writing output. In such cases the result value is +normally a special constant that prints as #<void>. When the +result of an expression is simply #<void>, the REPL does not +print anything.

The void procedure takes any number of arguments and returns +#<void>. (That is, the identifier void is bound +to a procedure that returns #<void>, instead of being bound +directly to #<void>.)

Examples:
> (void)
> (void 1 2 3)
> (list (void))

'(#<void>)

The undefined constant, which prints as #<undefined>, is +sometimes used as the result of a reference whose value is not yet +available. In previous versions of Racket (before version 6.1), +referencing a local binding too early produced #<undefined>; +too-early references now raise an exception, instead.

The undefined result can still be produced +in some cases by the shared form.

(define (fails)
  (define x x)
  x)

 

> (fails)

x: undefined;

 cannot use before initialization

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/guide/with-syntax.html b/clones/download.racket-lang.org/releases/8.6/doc/guide/with-syntax.html new file mode 100644 index 00000000..94174765 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/guide/with-syntax.html @@ -0,0 +1,20 @@ + +16.2.4 with-syntax and generate-temporaries
16.2.4 with-syntax and generate-temporaries

Since syntax-case lets us compute with arbitrary Racket +expressions, we can more simply solve a problem that we had in +writing define-for-cbr (see +Extended Example: Call-by-Reference Functions), where we needed to generate a +set of names based on a sequence id ...:

(define-syntax (define-for-cbr stx)
  (syntax-case stx ()
    [(_ do-f (id ...) body)
     ....
       #'(define (do-f get ... put ...)
           (define-get/put-id id get put) ...
           body) ....]))

In place of the ....s above, we need to bind get ... and put ... to lists of generated identifiers. We +cannot use let to bind get and put, +because we need bindings that count as pattern variables, instead +of normal local variables. The with-syntax form lets us +bind pattern variables:

(define-syntax (define-for-cbr stx)
  (syntax-case stx ()
    [(_ do-f (id ...) body)
     (with-syntax ([(get ...) ....]
                   [(put ...) ....])
       #'(define (do-f get ... put ...)
           (define-get/put-id id get put) ...
           body))]))

Now we need an expression in place of .... that +generates as many identifiers as there are id matches in +the original pattern. Since this is a common task, Racket +provides a helper function, generate-temporaries, that +takes a sequence of identifiers and returns a sequence of +generated identifiers:

(define-syntax (define-for-cbr stx)
  (syntax-case stx ()
    [(_ do-f (id ...) body)
     (with-syntax ([(get ...) (generate-temporaries #'(id ...))]
                   [(put ...) (generate-temporaries #'(id ...))])
       #'(define (do-f get ... put ...)
           (define-get/put-id id get put) ...
           body))]))

This way of generating identifiers is normally easier to think +about than tricking the macro expander into generating names with +purely pattern-based macros.

In general, the left-hand side of a with-syntax +binding is a pattern, just like in syntax-case. In fact, +a with-syntax form is just a syntax-case form +turned partially inside-out.

 
\ No newline at end of file diff --git a/clones/download.racket-lang.org/releases/8.6/doc/local-redirect/local-redirect.js b/clones/download.racket-lang.org/releases/8.6/doc/local-redirect/local-redirect.js new file mode 100644 index 00000000..c2830be6 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/local-redirect/local-redirect.js @@ -0,0 +1,210 @@ +// Autogenerated by `scribblings/main/private/local-redirect' +// This script is included by generated documentation to rewrite +// links expressed as tag queries into local-filesystem links. + +var link_dirs = [ + ["2d", "../2d"], + ["algol60", "../algol60"], + ["browser", "../browser"], + ["bug-report", "../bug-report"], + ["cards", "../cards"], + ["compatibility", "../compatibility"], + ["continue", "../continue"], + ["contract-profile", "../contract-profile"], + ["cookies", "../cookies"], + ["data", "../data"], + ["datalog", "../datalog"], + ["db", "../db"], + ["deinprogramm", "../deinprogramm"], + ["demo-m1", "../demo-m1"], + ["demo-m2", "../demo-m2"], + ["demo-manual-m1", "../demo-manual-m1"], + ["demo-manual-m2", "../demo-manual-m2"], + ["demo-manual-s1", "../demo-manual-s1"], + ["demo-manual-s2", "../demo-manual-s2"], + ["demo-s1", "../demo-s1"], + ["demo-s2", "../demo-s2"], + ["distributed-places", "../distributed-places"], + ["draw", "../draw"], + ["drracket", "../drracket"], + ["drracket-tools", "../drracket-tools"], + ["ds-store", "../ds-store"], + ["dynext", "../dynext"], + ["embedded-gui", "../embedded-gui"], + ["eopl", "../eopl"], + ["errortrace", "../errortrace"], + ["expeditor", "../expeditor"], + ["file", "../file"], + ["foreign", "../foreign"], + ["framework", "../framework"], + ["frtime", "../frtime"], + ["future-visualizer", "../future-visualizer"], + ["games", "../games"], + ["getting-started", "../getting-started"], + ["gl-board-game", "../gl-board-game"], + ["graphics", "../graphics"], + ["gui", "../gui"], + ["guide", "../guide"], + ["help", "../help"], + ["htdp", "../htdp"], + ["htdp-langs", "../htdp-langs"], + ["htdp-ptr", "../htdp-ptr"], + ["html", "../html"], + ["images", "../images"], + ["inside", "../inside"], + ["json", "../json"], + ["lazy", "../lazy"], + ["macro-debugger", "../macro-debugger"], + ["make", "../make"], + ["math", "../math"], + ["more", "../more"], + ["mrlib", "../mrlib"], + ["mysterx", "../mysterx"], + ["mzcom", "../mzcom"], + ["mzlib", "../mzlib"], + ["mzscheme", "../mzscheme"], + ["net", "../net"], + ["openssl", "../openssl"], + ["optimization-coach", "../optimization-coach"], + ["option-contract", "../option-contract"], + ["osx-ssl", "../osx-ssl"], + ["parser-tools", "../parser-tools"], + ["pict", "../pict"], + ["pict-snip", "../pict-snip"], + ["picturing-programs", "../picturing-programs"], + ["pkg", "../pkg"], + ["plai", "../plai"], + ["planet", "../planet"], + ["plot", "../plot"], + ["plt-installer", "../plt-installer"], + ["preprocessor", "../preprocessor"], + ["profile", "../profile"], + ["quick", "../quick"], + ["quickscript", "../quickscript"], + ["quickscript-test", "../quickscript-test"], + ["r5rs", "../r5rs"], + ["r6rs", "../r6rs"], + ["racket-cheat", "../racket-cheat"], + ["racklog", "../racklog"], + ["rackunit", "../rackunit"], + ["raco", "../raco"], + ["readline", "../readline"], + ["redex", "../redex"], + ["reference", "../reference"], + ["sasl", "../sasl"], + ["scheme", "../scheme"], + ["scribble", "../scribble"], + ["scribble-pp", "../scribble-pp"], + ["scriblib", "../scriblib"], + ["sgl", "../sgl"], + ["simple-tree-text-markup", "../simple-tree-text-markup"], + ["slatex-wrap", "../slatex-wrap"], + ["slideshow", "../slideshow"], + ["source-syntax", "../source-syntax"], + ["srfi", "../srfi"], + ["stepper", "../stepper"], + ["string-constants", "../string-constants"], + ["style", "../style"], + ["swindle", "../swindle"], + ["syntax", "../syntax"], + ["syntax-color", "../syntax-color"], + ["teachpack", "../teachpack"], + ["test-engine", "../test-engine"], + ["tool", "../tool"], + ["tools", "../tools"], + ["trace", "../trace"], + ["ts-guide", "../ts-guide"], + ["ts-reference", "../ts-reference"], + ["turtles", "../turtles"], + ["unix-socket", "../unix-socket"], + ["version", "../version"], + ["web-server", "../web-server"], + ["web-server-internal", "../web-server-internal"], + ["win32-ssl", "../win32-ssl"], + ["xml", "../xml"], + ["xrepl", "../xrepl"]]; + +function bsearch(str, a, start, end) { + if (start >= end) + return false; + else { + var mid = Math.floor((start + end) / 2); + if (a[mid][0] == str) + return mid; + else if (a[mid][0] < str) + return bsearch(str, a, mid+1, end); + else + return bsearch(str, a, start, mid); + } +} + +var link_target_prefix = false; + +function hash_string(s) { + var v = 0; + for (var i = 0; i < s.length; i++) { + v = (((v << 5) - v) + s.charCodeAt(i)) & 0xFFFFFF; + } + return v; +} + +function demand_load(p, callback) { + // Based on a StackOverflow answer, which cites: + // JavaScript Patterns, by Stoyan Stefanov (Oโ€™Reilly). Copyright 2010 Yahoo!, Inc., 9780596806750. + var script = document.getElementsByTagName('script')[0]; + var newjs = document.createElement('script'); + newjs.src = p; + if (callback) { + // IE + newjs.onreadystatechange = function () { + if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') { + newjs.onreadystatechange = null; + callback(); + } + }; + // others + newjs.onload = callback; + } + script.parentNode.appendChild(newjs); +} + +var loaded_link_targets = []; +var link_targets = []; +var num_link_target_bins = 7; + +function convert_all_links() { + var elements = document.getElementsByClassName("Sq"); + for (var i = 0; i < elements.length; i++) { + var elem = elements[i]; + var tag = elem.href.match(/tag=[^&]*/); + var doc = elem.href.match(/doc=[^&]*/); + var rel = elem.href.match(/rel=[^&]*/); + if (doc && rel) { + var pos = bsearch(decodeURIComponent(doc[0].substring(4)), + link_dirs, + 0, + link_dirs.length); + if (pos) { + var p = link_dirs[pos][1]; + if (link_target_prefix) { + p = link_target_prefix + p; + } + elem.href = p + "/" + decodeURIComponent(rel[0].substring(4)); + tag = false; + } + } + if (tag) { + var v = hash_string(decodeURIComponent(tag[0].substring(4))) % 7; + if (!loaded_link_targets[v]) { + loaded_link_targets[v] = true; + var p = "../local-redirect/local-redirect_" + v + ".js"; + if (link_target_prefix) { + p = link_target_prefix + p; + } + demand_load(p, false); + } + } + } +} + +AddOnLoad(convert_all_links); diff --git a/clones/download.racket-lang.org/releases/8.6/doc/local-redirect/local-user-redirect.js b/clones/download.racket-lang.org/releases/8.6/doc/local-redirect/local-user-redirect.js new file mode 100644 index 00000000..e69de29b diff --git a/clones/download.racket-lang.org/releases/8.6/doc/manual-fonts.css b/clones/download.racket-lang.org/releases/8.6/doc/manual-fonts.css new file mode 100644 index 00000000..0801112b --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/manual-fonts.css @@ -0,0 +1,251 @@ +@font-face { +font-family: Cooper-Hewitt; +font-style: normal; +font-weight: bold; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} + + + +/************* Start Cooper-Hewitt license ******************* +Copyright (c) 2014, Cooper Hewitt Smithsonian Design Museum (cooperhewitt.org), with Reserved Font Name Cooper Hewitt. + + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the copyright statement(s). + +"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. + +5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. + +************** End Cooper-Hewitt license *********************/ + + + + +@font-face { +font-family: Charter-Racket; +font-style: normal; +font-weight: normal; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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Gdwnk11yPSSukc8TPCQWbot5zt/fYISyvlKyz9v+v5z//Z18rO9h3r3A8mrojASslPx73Oss621WrIJbXDdpFbAaZZX26SXkNKQ6RYnOkbx0tanfBp5TElEnDAc/AXtlHdYAAHjabc5VcA8AAMDh77+e7u5uC8O0jenu7gUzE8O003mcO5449YLTefJBN6fd4U73ecCjY+LN7+V7/Qnyux/JmvhfzwgEBYIFCxEqTLgIkXLJLY+88smvgIIKKayIoooproSSSimtjLLKKa+CiiqprIqqqqmuhppqqa2OuuqpL0q0GLEaiNNQI43F/3ppqpnmWmipldYSJGqjrSTttNdBR5101kVX3XTXQ0+99NZHX/30N8BAgww2xFDDDDfCNgstcsp6by222gob7bDdco8tsC4QEgi1ygZLnfU0EGaTnb756rutdrvsoj1GGmWN0a4a45IrbrrmuhveSXbHLbftleKLte67655UH3yyzFhpxhkvXYbNJpgo0ySTZZliqmnem26GbDPNNssxW8w1xzzzffTZcQ8898I++730ygmvvfHQE48ccNARR51zyGHnLbHLBaedcdLKQHggIhAZlpKenZka/YeY8KyMtKiohH/G/jU+x5i4pMQckxKiov8a8xPlfHWxAAAAAVoSAhQAAA==') format('woff'); +} +@font-face { +font-family: Charter-Racket; +font-style: italic; +font-weight: normal; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} +@font-face { +font-family: Charter-Racket; +font-style: normal; +font-weight: bold; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} + + + +/************* Start Charter license ******************* +(c) Copyright 1989-1992, Bitstream Inc., Cambridge, MA. You are hereby granted permission under all Bitstream propriety rights to use, copy, modify, sublicense, sell, and redistribute the 4 Bitstream Charter (r) Type 1 outline fonts and the 4 Courier Type 1 outline fonts for any purpose and without restriction; provided, that this notice is left intact on all copies of such fonts and that Bitstream's trademark is acknowledged as shown below on all unmodified copies of the 4 Charter Type 1 fonts. BITSTREAM CHARTER is a registered trademark of Bitstream Inc. +************** End Charter license *********************/ + + + + + + +@font-face { +font-family: Fira; +font-style: normal; +font-weight: 300; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} +@font-face { +font-family: Fira; +font-style: normal; +font-weight: 400; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} +@font-face { +font-family: Fira; +font-style: normal; +font-weight: 600; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAHAAABMAAAAA8dwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABqAAAABwAAAAcejWA8EdERUYAAAHEAAAAHgAAAB4AJwEvR1BPUwAAAeQAAAzJAAAufsATCxdHU1VCAAAOsAAAApcAAAeEea4ezk9TLzIAABFIAAAAXQAAAGARTEjhY21hcAAAEagAAAJeAAADfi1PSJpjdnQgAAAUCAAAAGUAAADcLqwVBGZwZ20AABRwAAAGcAAADW04JI58Z2FzcAAAGuAAAAAIAAAACAAAABBnbHlmAAAa6AAASaEAAJVwJvOfpWhlYWQAAGSMAAAANgAAADYHEy/+aGhlYQAAZMQAAAAhAAAAJAe1AsZobXR4AABk6AAAApQAAASkYRswlWxvY2EAAGd8AAACTAAAAlQv41YUbWF4cAAAacgAAAAgAAAAIAPMAktuYW1lAABp6AAAAjYAAAWWeXHCQHBvc3QAAGwgAAADDwAABL0OjfQ0cHJlcAAAbzAAAADHAAAA5wgX+o93ZWJmAABv+AAAAAYAAAAGTJpaEgAAAAEAAAAA1e6U9QAAAADODu7hAAAAANY3/RkAAQAAAAwAAAAWAAAAAgABAAEBKAABAAQAAAACAAAAAHjaxZp5kBXFHce/82BhWY4VfMDuAgvLsaCIogiiYhSWUzQqhwcpSwOxrJQWZRGLqqRIwj8oHonGxOCxnlFykERiguIikpD1WI/VuCTZlCwxj+NVdDxeGYcUE518umfetfeFzq++0zPd/evj19/+dU+/J0dSkTbqAfWdv/CiFSpb8+11N2rK9euuu0Gzbvz6zWs1X33JoyBQjMBp922K+s1dtWCcplTNXWHuy8z94ksu4r7skou5r1i2lHuORmzNTd+6SUNuuG7dWsVtjOydFPXTEPvukGJy99FLfV4YEOO9SAVIEU+Xa5IqNZkyT9LJmqpTNE2n6jRN1+k6QzN0pmZqls7SbJ2tc3Su5ug8fUWbdItu1Wbdptt1h+7UD/RD3aW79SPdox/rJ7pXP9UW3af7scuDekgP6xE9qsf0uH6mF/Wy6vSa3tCb+osa9Ff9Xf/QO2rSP/UvHdRhJfVvva8P9JFS+kSf6qj+q2P6n0PLYwutxa7QTu3Vfn2u/U6JM96Z43zV+Yaz1tnobHV2OgecA6QiziHnPeRj4MUGOe+htT82LDYaDIudHJsemxWbRdznJj9ah3LkvayQZkOrFYn2cp9lkM5rS0Qcj+c5aH1uWkf7DnCPaSljsA/00/AgqRFBQiODlEoDT6OCRo0JfBUqTszwYBupvkpIKeN9FDlHE44JXKvrkppE10XXJ7Xe6sZ4ch3H5imxaWltF23P5umLtoe2F9WaggEjqTvMb/KafEnKGm7r8yKNUfbtGKV7GhC18SjlHEP7GNqNUW2mJpecqUhvZKhrWzUgqjtlY0tsz1PopEv3bC7HvjmOo2JzNzHc62nnU0GttoMdQYN2BbXE2nzox6I6PNg9BHaO0lnOOF1qywpL9G1O068C7D8EezrwZxB1nKChGkbcCI1UiUpVhvZojVG5xmqcKjSeuTElmgOzYf95Ol9VWqgLtVwrKOMqrdLVukartU7rtSFvVtybw/9qZoBh/hN6FrY9pxrt0vPaDUP/rFrmg5kLB3VIrj7Ux3D+KA2OOUOdYc5w2F3qlMkpmGJ5P1gTnaed150jsbjzdOxCsNF5um9l3wv6rtIaFdLjMno6GkwIdmgS75N5ngpmgJngLOJmB4/pbMJzsOi5QZPm8HxeUK0FhIvIsxgsARdiq6WEy8FKcCVWX0Xc18h3NeH1xG3i+RZwK9gMbgO3gzvAnaRvAfeB+8ED4EHwEHiY9EfAo+Ax8Dj1P0m4Ffwc/AL8EvwKbAO/Ruc34LfgKbAd7ADPgp3gOVADdoHdYC/tqwUvovsSeJm4V0AdeBW8DurBW+Bt0AD2gYPgEDgMjoD30f0AfARS2O0Twk/B0aDaiQVJ58Sg0YmDEYDZ5EwOEs4U6u2nE7DWMFAFP5lRDqx3zJw0KR4pHikeKR4pnmPmwkAVozmUPOMIK8B4sJr39YTV4HlKJ90x5Q4mt5cpaxyoAOPDctHw0PDQyK8jrRW2LV8r1Uwr2+ZvotWAVjWtS6BZrXJsMxaMI74CjAeTeJ/MfJsKZoCZoCrDKxdeufDKhVOuLqPUZWA5zysIVxJeTngFZVxFuNryy9U63tdT9neI22D5loRvSfiWhG9J+JaEb0n4loRvPnzz4ZsP33z45sM3nx41wDm/A3658MuFXy78cuGXC79cPUO9zxLuBM+BGrALPE+ZuwlfIH0P+CP4E3iRdoR88+GbC998+ObCNxe+ufDNhW8ufPPhm6u/ofMuSICDxB0i7jDhEUKXsj4EH4P/kO4xGrHAhwEJGJBghKoZoWqnFB6WYWfDrFpGpxar15JaS2otKbU2xSfFjIdPik+KTwrjhBeMh6NKWA7GgiqwCB4sBkvAUrAcrATGA1xteWlGyMP3xfF9cSzoYUEPC3pY0MOCHhb0sJ6H9Tys52E9D+t5WM7LzNBXeH4VvA7qwVvgbbAPHAJH4GK6xyfSn7jpm+LMuFpmHH3kuRSU2V1OX3Y1RXjKOH7cweM+oYGOWVEGKTZhr/GhYxdX3I0Hn8UeqiFoCrygPkgh2DZwzTqmiTwnA5+3FFZLsuLVqYC8CQN18zLlc0/mx9m7b1P9CKYtqTCNd9MuL8zXpdp8e28KGpFUfmym7lIbJoI6VvBeutpvadibvFYW97Qu+mdsFtrQPIWxydxcoUXxWE3BZvqbBMwsUorzx6OlDZmDvdj/DrXNWDRZSeKnR4b9sX0qSreUtHp2RLkjWh49JzO1F1nu+K3WscPWsQO71Zgao+jB5McjGcsQy46LXaiCWuK2Z2vLHckWlkr1Anv8Hugm7axpbNlKO6/ScyyZO0bEJDIzM4VVUq2NZVvzLz+WXVRziyTyYwxLo3mZCG62NSaaa7esKaw9v93Gu3WNaZ3zIVHrvLz56rNrDmdR6J+8KMWNemn9Vo6tU/kM6ahe2FwDkqARZprQeN5IbI46pMGwOpyR5Glkd9sQbMWOfBOQatbVeLDH5I3KrO9NLnZnVls/E1mDtnrhCBoGWD/lpz1TxkeF/WUnGWwj3fjtcMyLrYdLtpx1edxy0+21WqmWY5mJ8TOjVIxWXWjRrN/oaC6Suz7yoKbsUrte+dkeRfZvsCOWLSkesaZTPiqHG7XGEvZ5D3UYO7rWiqnQ05Nu/GEy7YPI0Yifrw+20MIao20tEg+2pz15/jzNW5vq0cnaqyDXA7TJkKJIt1Pez7bI5bssy5F0P5pC/01Mo7VnurWN4XN0T+WOQzTf3PbY2SytnO/j/Ks0b9TnROtxkU0pt0/xTI4ivoXjUTkmvahFaTl+o4NVu/m6WtSNGeb2YHZ7x2d96kmbclnRqYwLc57nRBxq2/LhWK1Ur13NW9mT1TvvmtDjlrl2RejOVdw7Y9iRrTJ1+V8ce7vb8g7ncqqFhp+X7rVrhXC8mrpndbt+NdvbtNLe0q7NUbOedc7qrezXjuXvSrtp9tKucyO79+qiXm3+CtaqfeIt6uoecxs60c7iZmxq6LhfreYo6vpMsd/8X+jVzuxKRbuqxPFcbbrmAewupFM2bf411bVvuV5rfEEb8eU2rTgvX0EmJZ5ZLxV+e7D7TOV7QuOzbC89+72cjW/sdft/lv1WMDvo1rnTXS7Qj8Zc3S+K/9R6rPOzM7gn+KhXag2/flx9WVdpL+wO63I9QvY7qz3+dHuMavLeDwc7YGCdZf6O/BXky/eXnepPsrnFwi/nzFdzU8v5G32hJdv3ap06X0nk7g5a31nZuuz4mjOinlon54whcVxHxc/uVzo6L+v6PoXd/O60jw2/lDutubWtcemMP8nuZI+T1RLZ8xB7UpHq7PiaM6Iu7ISanxF1yf+FZ2pd+R4Oz4hy+9mJHbffvfUnPCNKP3dm/c2crWxpq13tnxF1zxf1ZF2NfhGqsb01J0R7WhuDXvoqjOuMLuQubzcl3quz5doucMKcoR1Xj5fjYbaxIm7J7HrrO1qRW2NoR+wIrrU771r8hZtdbdvws81+Y8z5tSiV/UZNtzI6R3ynxe8ViexK1PlVoHtnQvaE28/apXW/m++1wt9yWtkHp5rbtbdPS4LtPSzgjB6ktryWZjifwCb1LVllvWLC+v/6tr93886WU+1y01GhU6FB0dtie1+iKs0H0oAoj7nG2vcBmocssbIoSo0R20d9o2+uIeqn/iq0uYvAQEofTGz6H1onRrXI1jCCckcShv/YCi/zry3Z/22ZOsP/bpmTxImaxL0y0p9PSW1dC8C86HlJTnw6bmGrWn3oSZ9I0teAqNehLAFDIhnG81jan5US+8+zUMw1Ckn3I5QltkfhNYHnCdYC5t+csUxdph0lFgWRRfpjj/72aYx9Dv1xua3fWG4gNjIYpIoMBtuRCGFsXplBbs/avuYjc5Gq6D7PjtaCNiw3xvJohKZmYk633+Dj4cL4ZnkLI5yGFFgxvayIYpUJR2VmUFpjKrVMs2M0GradmqnH1DAJTLQiC2mGvVciEyOcopncDSsnc58e6feLSkrr5V79bTvzTx8qc+Kyp9sVeVLYqpUKM1IApkVi/zNM+3NlYkZkZ8C4qA9pKbDvoYSsqUCrkNjCjAWyCOMqW2lRpUVWL7zM/4bTMHN/GnkMjM2nZ6C80Wrr6oeciYyP7qfZ0eqP5WKUWWi1ByHmX6LDiIvbf9WORPrDizLSR5N3AL2bivc4lfEqYWTPJ7YKOQlGLtLJzKullHaJLqVdy7QC1lyuKxntVbpGs7Vaa/QV3YRcoHXIXK1H5mkDUqWNyHxt0t2UdS9ymbZoO6X8Xn/QjXpGu7VWe/UyGnXIBr2GfFdvIN/Tm9qn79t/PG/Sfh3QZr2L3KGEDulOHVFKd+kT5EF9ilTrqD7TQ07MiekJZ6hTpied0c4YPeVMcabod/8HCOJD8wAAAHjarZXrS1RRFMV/d2acatQ0s0mGCgszK7Mye5dkqYT5YhokRCLR6kOiMRoVREH0zt7vtz0+Rn9A36MiIqIiKiIiIqIiIqMIwdZ96C0JGR8c7l733rPXOnvfe/Y+GECAo7zEV1hcGiFUtzXaQPb66NoN5DfUtjRSiU8+dHZaaODBG9ObLPwF1UXpZC0riJg2bNqyilLZcEWZbCS8QranTl1tQwuhddHaOtKbovWN5Ddv2thMoeWRJJvYvWIcfoYwlGHKIJ4EzZg+wy0LI8ggm0VilhKhhnoaaGEbu2jlJBe5wU3Lz1D2fmEcl2k3Soydxm3r2TA6bPRkOljlYKuD92z0BhwMO9jmYLuNvnIHbzn41MY4v4M5dhxxn5VXgjLbzma26J2XUQQZLTSjTBGmkaf/YT4ZjJS3z8k6ScNDKmPlM14jsdc5m+3t1jO1GTRVUydZc0FyY9Ls4tkMk0ufeAYhXam65ljfMXmAeXR9bYMcR6/3KHAYqZqZoe8ZG8flBYW5in1BH5guO03eeczTPl/SR76rEdLeN9fPZynF/VBxlcZoR9uxFLJcddc/LVdvnOq7K64SygkPQNFVTVfPcGOsVHdYNUBdV3uCutHf8VZRzepBUHdXyFC3+zf2Gtaouw3OGvY6BlOcTkoMu///FeiLmZnirJtsdfYiVlr93fSGJo0AOzTiLf9gD3/zroqJZDJJZ8lkxT1VXX+aane6qnGmKmuW6mO2IpurnTlfu2mh/v1i/aPd7GEv+9jPAQ7qTDjEYY7oLDjGcU7ohDjFac5wlnOc5wKXdDpcoY2rXOM6d7jLfR7wkEc85gnPeM4LXvGaN7zlHe/5wEc+8YWvfOM7P/jJL37TYXiUW0BXkzJysv0DynOOjgB42mNgYeJn/MLAysDC1MUUwcDA4A2hGeMYjBhtuDiYuFmZWRkYmBhYGhiY3jswLPgNVKMAxAwBkUHBjAcYeH8zMQv+12Q4wSLF+EWBgXE+SI5JkGkzWB03ALa2D3oAAAB42q2SR0zUQRSHv7e7gmIDaUv/gywgNrACihUBe0VRFMSIGmMjoLGCB7EjIMaCiprYxV5QEZFEOXjXGDHxbywnj0YSwR3HhRgSD16cZN6bkvne5Pd7gJX2GYzoiBTqnbj2NsnUeQ7j6EIfvepJEYeoRom7eEmQhEm8JEmKpEuGZEmu5Em+FFmaLG8t76x1tjeGh+FjBBqhRoQRZQw2kowcoyY8IrzS8dLR1mpR6nc1zTRczLNikx5il1CJk0RJljSZJZmSLctlnWzuxMTwNOxGcAczsYNZ7mKKZor6rj6pV6pJvVCNql7VqvvqgqpWp1SVqlQVqkyVqhJV7ExwOpyRP1PbYj9YTafZav4wW8xv5lfzo9lgFrx3vq9ozmqOdYtq1+Q/DzeLh0tp/qILlo6V9R+M9pc27Ywb7nSlGx50p4fWsxe98cRLO+aND7744Y+dAAIJ0p6GEEqY1jycCPoSiYMooomhH7H0ZwADGcRg4ohnCEMZxnBGMJIEEkliFKNJZgxjdUeMZwITSWESqaSRzmSmMJVpTGcGM5nFbN03c5lHBvNZQCYLWUQWi1lCNjksJZdl+v/72M9B7f9RTnKOi1zgEle4zFVquMF1bnKLO9zmLvd4wENqeUQdj2ngKc9o1ISNrGQVaySAbZyngHVisIW1+uYAp3Xc5NJpNVs7abeeYh2vUc8uVpD/53wDOyWQPErYSxWf+aK7vI/4ib94iw9PxMFzWrT0YRIsIRItMfrNdvEVu857KGM35ZRymEqOUMFxTujzY5zhrO7v1zi1ZYWuOood7QV/AV3srcgAAHjaY2AgE7QBYSJDIpMZAwOT0//PyPz/H0Ei/z/CxTYD1QgCxdWYDgHlFP5//K+GkAOKfGZSBIr1gGWhbBS9nxG6maWh+lOB0BMI7/43YXj8XxfGZ3rKaMv0htGMQZGpEgABeTrCAAAAeNqtVml3EzcU1XhLCNlISGiZlsoIpzTWGEpZAhgIM3FccBcnQDsDpZ2JHbov0I3u+4J/zZukPYd+46f1Psk2CST0tKf+4HclXemtehoSWpK4EtYiKRt3xehSgwqXroZ01KWDUXxDdq6ElCklfw2KQdFqqRW3WCQRkQjUwppwRBD7HjmaZHzDo4yWbUn3mpSbubp20NkZ1Fo1KtTCImVL0fK1sKiKbieU1Gxiaj5yJc0xmosimVp20qaDmOqOJB3m9cPMvNcMJazpJJKGmmGMGclrQ4yOMzoeu3EURS6spaGgRWI5JNFgMliB26B9jPY1krvjosWMu3mxEkXtJCKnHEWKRDNcjSKPslpCc66UwJd80Awpr3wqKB+egxp7lNMKnsh2ml/xJa+wj661mf9pIK61KDtbxGIgO7IDBenhfAlhWQrjppssR6GKipGk+Ush1lwORle/R3lNA0F5TWRsbAsYKl8hR8pPKLNyg5wWrKD8rEcDWrKpw/AlJ1Ykn0DzccSUeMGYOqjXBoZFUPNni/1s7dCbszdkT3HKMCGA37GsdVTCmTQRFi5ngaQLI3tWIp8qWbAqdm6znQ5gl3Dvu7Zx07A2Dq3tHMqiPFxVjGaLHo3oNJOpUTtZ8GhUgygljQQXeTuA8iMa5dEyRqMYeTSGY8ZNSCQi0IJeGgti2YkljSFoHo3rxuUwzbUXogM0sqpue7RLN5bCxiU76RYxP2nmJ3QqxoMrYTo+HpCT+DRW5ipHNfnpCP+N4o+caWQiW2qGKQcP3vod5BdqR2eLCtt62LXrvAWXh2cieFKH/XXMbk7VNglMhZhUiFZA4uya4zgmV5NapCJTuxzSuPJljYZRfDsVCs6XMdT/OTHhiDHh+504nSiU6U7Z3Y8w7YZvk2WPpnTqsJxGnFnu0WmW5WM6zbF8XKd5lnt1WmDp6nSA5RM6HWT5pE53sHxGq17cqRAjwkpWyLnOF8Sj2Q2L0/3Fm3axvGFxpr94yy7u04JGyv/Bv6fg3z7YJeEfyyL8Y7kf/rFU8I/lAfjHsgT/WM7AP5ZPwz+WB+EfS61l1ZSpp6F2IpYBchsHJpW4epprtaLJK5OHW3gIF6Aut8miSuYU99BHMlz2/nAvtelwocaVRodm07wzVQvR/9jLZzeEZzvOES2PGcufw2mWU3tYJy7rlrbwvJj+Q/Bv4ayaS484U+zrUcQDDmxtPy5JMufRMV3ZU/Xo+D9RUdAt0E8gRWK6JCuyzo0Aob3Q6dRVHZ0jxBuDRovucNxxpnYjwnPoWNO0C7QcmmjJ0NIh4dOOoLzaqSgpqx2ceXIzTVbseZRTfo8tKeZeMr8UrmdkVrrrmZns3sjn/jqIVq3MDrWImx08eE1j7nH2AcoEcVtRNkjaWM4EiQscc397cE8C09D11SJyrKBhkR+nwcBowXlbKFG2k+bQPJCMPAou/9CpOJG9Khkj8N+0HfS+LhTCqV4sJGbzM91YqCrCdLq/RINmfVHVWSlnsdoPITtjI03icliRVbzdbH13UrJd3VRQoYTRhY2fCTaJW1V7N1uKS/7MBkuCXrpi/pZ40OVeis+if1Q4iou0KwibLl5SWY0qacXZjXt7btPqstvctDq/5d5H7Tivaa78KIW+ppPlDmzjGoNT21KR0ApVsCMwLnN9ztjIJzSkfOs6F6jC9ang5tnzF9CY8Mb0tvzLkq7/X1XMPnEfqyq0qg31Uoy6dtbQgOfKvagsYnSyXFTduHS96YegjhBM2WuPbxDc8MkKHcUtf36b+Qs4ztk9SceAL2o6AdHgKNYQbrmIB7cXrRc0FzQ1AF/Ua2hhAC8BOAxe1muOmWkCmJkl5tQAlpnD4BJzGFxmDoMreh298DzQK0COQa/qdcfOhUB2LmKew+gq8wy6xjyDXmOeQddZZwDwOutk8AbrZBCzTgYJcxYBVpjDoMUcBm3mMFg1dvlAN4xdjN40djF6y9jF6G1jF6N3jF2M3jV2MXrP2MXofcT4VD+BH5gRnQX80MJzgB9x0M1oHqObeGu7nFsWMudjw3G6nE+w+XT/1E/NyOz4zELe8bmFTL+Nc7qELyxkwpcWMuErcKv98742I0P/xkKmf2sh07/Dzi7hewuZ8IOFTPgR3DP9834yI0P/2UKm/2Ih03/Fzi7hNwuZ8LuFTLij13fkMr0vWr9Mg6uUPdC83Xuivb8ByjvTswABAAH//wAPeNrNvQlgHNWRMPze657pGY000tySRiNpbt3XSBrJkq227tOWLMuSbMuyLNuysY0PjDmMjcAX2GASbpxkQ/KR5EuWJA7mSoCFJCTZDUn42FyQzR3ItyFZEpZkD4JHf9Xr7rkkG0iy//8D0oiZ6X5V9ep+VdWEES8htIydIwKRSNUXKKlufUQSd/9b3Rf0uh+3PiIw+JN8QcC3dfj2I5J+zzutj1B8P2LxWsIRi99Ljf/6jW+wcxe3e9kEIYxUL7xJXmIXiJFkkSK5gDAmTBFBGB4gsNg0oXScDlqsdqtoyi2P1jfWOR12vS8U9QuR6upO/O/krpzT7b7qap+3pua79Fm8Zy99iB6DeyKcLtnOKNxqSqCUDpNBi8WSg/eywR3w56vrvYefgx+4JDv2Js3G6/Phlweud5Micv3A+drhCbnELDGqFwE6yrZl0oyM4YGcbINAiHEqy8SMxtEBHRWEEWHQLYfwDf4hNZLti69TvzgpFxYUFBQVFBV63Pl5uS5AzGa1qP/kWEyecuqXIg6/5I/yn4YI/4lI/EcHL8wz7O5eY9/lOGjfZe9YXdA9An9fDT+dsX92X1VAv/LixIfgn4kXJ++HfyZffBHIQIoXtrBsYYyESYNcV5DvEgTmMTIqGPQCACz0A/oAqjBHkGjjQH8yhZcNBQuCdqRb0K6XHP6GUDjqjNQ1NtSHwlW0ob4x2hBxOF1SyO/TO+xOVyFl2dunth4e6uzb3NjVOLhzdnr17PahDnl1bUvT6OatXx+9MuveuzP7V3VEayqiLu/Wvt7N5gfuzejobSwPB6vyi7YToiPywk+FTvZN2EcTccBuBMlKeQWSk/YLVOilVN8DXMIkwuZgp3WipAOwqTAN/LNugIiifpro9eP6QSCszW/zBQ2mgnIjDVOdPVLXUO/3uZCV6hsjdU6bHd5Q/r8BmYx9J1azhr4YC/f19PS9NX3v5s0D/Zuf+cAH/h3/vHea3XexJ8K++MXNM5s3D8/M/N2WmdjKGeXv4dUzMwQg7lx4k/2RfYUUkACpITOypaS4yJ1vFqhBEPWUCKx/4HwOMJYL4GTTwPbrOGOQaaA4GSHAR+7EJ4DlCP9Yk4hJ2Vzoqa70BAoDZT673uQqpy695PKH9X6OQZRvSoRLi+RqlOqiYdwXAbZmBXyC28TkfcGmjz04MHX9vqNtHdHqHTMb93a3f8j/28HmR3uWl3lD5WVlgVAJPeTdv+bOjjU7Jls3ltf3VfZsnOhqWVt2z8p/jHyurquuiX6noMbvbvD6S0tRYlH2yFe57NnkHHxniihyl8NMznJN4lDaCP9+wcJOWiasIdlEfyFLpDXl1hzgoyqhfgWLuvQfbe8bqW5c7nYvb6we6aP/FvvlP25valt79OzDZ4+OtkXnlHu44R6lyfdozAH+LBTsZiaFGz+Zco8XaeE35qJto/wWa9uatsP1OXQD/Qx7jZhJRM7JyjRlGA2SXicKjGaRnoHz9uGJx3FX1sCuPIp/HJyUjbCwmZiZyV5OpahLcklhKRwNR11h6rSd8J2dm+rr2rT1rO+4jb121/Jd7h1d8ze173bvar0T1hske+mvgG1NpFvRLg5QUbC9IhG2waZzko2KwAL58GWRjiV9Sqk4BW+JQwCCoin0pvxyWwTED3QFCKZ/8J4998B/dM+5c9seeIDTp2RhLXmJ3AXrFcruDMCA9hOU7HF1fwgdclhxe1QFm0390RDq1rz2VaW+Dl9Vta+o5e6Hc/Fe9VRPZ+lu2N9c2cGVxFhCSSibTL0NXjobe4lWU/12fJ/reFjfqPGEysX25EVB9FSNrmlzDvvEwt30vFAF6+kvgAqvKadC2EbP/2bv64LjnRvzhXlQWCUga0aQNSOxkBI5mNABIsDHRWicDVKSbTZl6EVipEYdbFuwDrgE5CCnkPpCOQBCDs1tbmxsbmps/Nzvrr/+d4fXHKb51x+O/esNM0/RjV96KvZJDk8E7pgB/J1BSuUQcIigUJMMDyC/ULYJVhthg/BOBsmwWOw6kM2gBXgjYok4vA1Ud1/Lz/afio3O0m9vWHfLxfOzswoPg/TQ/wIc7KRMDudkM1BrQFbWjwZRVWiqMI3QQX/IYkNlTEG6vZK3QZVpYHYQefqbYx+lteZY/6NHmqv6lq2ZPLXjWrow8sSd2zZ94aHO6mjv8n1XKms6Ft6k78CaAdImt+ZRUZcLXOYF7a8HRHSAmK4f6A44gn4VRd000ekADABrGi4fJ4P+gNcPFAQGBKvg92kmoZxGFdOgQYRKyFFI6Ttnr7pz7cCy9ct75peZS+tWttUOreyYmp87PNDcPvH8+utmOzvaogc2NtRV1q/oHd/Wv2JdliiNK7AGgO64x2ZSIZeiAqX9BomJvSAYIB5UIHHJAfoA3VXJCKJMeBtsLgHMpiPCjENHYq99bffD95r3Dp07d26cvlQam/3sZ5U1QsBHFPY2j8jycgdleqCDgHQAswirgA0/SvQEyAP00OlQEMXhZHr4QB6BIJLJnUoQeMtvgX1yIDEYvePA6eFVDcOtPXuryjfS27JjsZqm8b0/n7tlpqt9cMXNLrpz+rPOa4GvSwGeDMDZRYrJCrkFHBiipyLNp6Cb+gkIoqijIupAjUN0Oo3b83I97tzivOJQAOEBTuGmWVJ3w++rYtw+CD5JAZH+MFJev3KNTt64ds+x7fLMMs+9x9ft6WsUDkTq2X0jnmv3Dl29Z9eZ+g1XdT7ySuzvB/55uP0Mp1nrwlv0T0AzPeoWVCW0HyhFepJVvw3FHA0vKoY/xf79OqqP/SP9Ilt/8YEga0IBEMAveZPlAK424gHfBKTY68pkIpAcSK+YPcCPMY3UeXklIUUCJAUhsHrRkGLzBHBK0NrVNaK9Q0b06emf9t928uqDNx3feWzD9JG5zrHR5QeWv9zS1h/ZFGG2TSs6rlt3cP+6gy0tu9du3hgba2worJqsa2mlN1U0Omt7Sutq0C8MLPya86CNFKKU2oH1GDflNgoIC4jGLMCoQMsGAyUBDmM0EA37/KplVsWB1quuUqRuI9UVwdY2bBrbf2buqvkvv0SzIq2R5SC77R1for03bJu7+Z5rv/5yLX16dlN3R+dK5FXVb6Zvo04lrQPnHWhFgFJ8/0eTnWe3bEOfjqBPl3h38nG7Pd2ptqQr4lR1TG/1Vld7fVwvM8WmwPromXU9phgVBQwr5ws6E4cGneLcBAyphgcAcTiSAeHGJxUUboYUYBLGiN6ZAAfu1El20t+yJuBDsBME7EQlbQi6sih9NnaCHq6IPU9bdz58zcNTZ04o9BskH6ev0u/yGMEnF6l6btsii6aGC0FgXfyXvhrbQe/Hn4/Pzc4tta5N59CFK+k+ejh2ooK2xp5nTbDu5lO3Kut6QOd+E3goHzRatVyBmp5ycwyGRDgKf2sunyCI06BgxsVBe76/zKIz5ZVT0GX1K8QUzWoWpDitqPPavGB5MK+ytKt57fpjW3cHGxqCZxTCUXN+Ubgt6M8POr3BdnnHps6K9nCw4fcJW8vIsoWQ8BWArZo0kdvknGJqEKONdkFnAHJIAmxvJWxvGREzqEEnGubAuVYF00hR80DcwEYGiCRxIR1DH7Y68WWB6YTx9EtI2hWTsq22piFS01TbFPD7A8FQwGcCp13nAukJNNSTSF0hU8Q97DdTTaJcFu7QxyVK8DngjWhDiL1UvOfQ9xbAkH1/2yevaN67paldEi09DeMbrtu5brhp6qP3f/rJxz+1ecsVg8s8nrGNpW+/9ALVr9xzdtXJh1vDpQ3Xbjtye3nsX0d/dNtHX/jEJ7/KHI/d0v5GFt/HhT/DrzWg99CLC8l+IsIWimQ7IAQRHnoCYIbABzDCFyRgInTRvWEI5GwRGxUiAn2+4v9WnP6X//VK7KXJxyYefJBduDjEumLP0pXAiWvh3l1cp5qJD7mkiNs71DDc0DGmmwJdz20Pt0Ij4qA35PV5vdzkgQF2ABGUl0YXeMHl1KJSjtvhp+a3bDyZf2jNRHP0ocrhqaaffbdhor+st2bF+Av7Xqb3rH+qOtY0UmFjFyzhntqWQZOYOcRlrAZ0dAT4w0Gicn0WiIsZFDJoZ4CuX5N2xenS1AwlluxMdLoc1KE4XVFXXBHGw0U6M9TdNjF/6qHP3HzNeGdLz+DU+g3Lhtf+w8P/+9m+1XVHjt98VJEdpMtmnivI5bkCULhqrgDEZkpxvIAOAW4Y6qsUtKMgIgr+Av1BYXNLSUfHl06H29avb3jmC81Tm9pK6NTAthpbzPb2miODNVZ2Iaey/wZFp8B69Dewngl9Pfh/HsTDJxr1QURV6idccernjrjX4bV46Q9jP/kJzYntoh9kI1/e8sIs3Eu77485Hn65OOm+mkfB8wP8jlzq+R0t4EHQb//xe987QW9hIy9uif0cb6bsySrYkzzSLXcYKKMgWAxYTMyFXRH7IYoWBZ24LW6W8O5kGhwotKKUYNrBmpOZIelIHs2TYIt06buDkuQPRyx6uv7sh584eXyid8XImu0jo3L1lVnv7M7+4vnP/MOa/qajJ09f735kS+x8Z5x2bJDTzisXgnRgILMNQ9jhAaZEuAmaeRE7vyWC/7LBE2+cgP9oQ+wFdiH2W+qI34+8Eo8rwa/gQbEWV0bg6ldOnFDou/Cnha3kl3xti2ymlDsj4Ic4qMlR7gqDswwLgVTk+uWSE4Ut7R/ektfdxfouPrJsYllQ47O9fC0jKZdLDDquo8EbwWVBuPnCIki8aBSNkh6+J4CAO8ptgAQVbCDdr5ygR//4+zt+DxoRBRt+6H7aHvtG7KS2//8G9weay04FFxCkTSpClhwBlEUpsCzs+E9jh05QO9zgi3BdFcD1O7jOhv5RjkEUKGoFUAlgO46KybS1WRwOzjxev4DJMvjXKQmofOBf9rubnEZRnL/xpGgw2uejnzkqXvcw3XBXR8xFf7Pq7tgXgO4e+qvEPg7Dmtk8dgQwGSZfUMupiQqHxcEtpBfXcOA22iIhoDAb/uyvRft1n/6NaLuOlW39aAx27+L3Nn6KlnJZRr49CXxrAmyUvF8yf6r+tC3gU8OcuPMk5RRbckCtsZMfO33mQfw5E3vuwdUjdP1nnn36YfyhQuyd2MXD6j42cR1tvZykeS0Br5dLmqoyo3Y92loLBlOfu61vqL379AePDp/4p1vuoj88HGvtuXr/m+zClUTF4yb2FOAhgQRWymXmLCb0oCsB0QJqLW7DedDEffRxYTAQCPgUa65iErVLLpC2qrg5c9I/c5TO3EWvnFyz7Mj6Mx9BPOl6FbNbfzwsrti1rPnJzwK6Gr9OAZ6ZED0Cv4JC1lGUfEwbYFikakmVN7x+L8RHXFeBPbDBtuGmFUv1IY49axjtfPb+T/Sc+A61nV7ZOTRyE/3X3s3O2A+oI/ZbduGFpsjPkC/MsH8WwNtLquRyJ9gCl54lgiXNFiQHi2V+n5pATERGavYwSdtg6tBy23UfmekZ2tbc07xq38zJuVs3dHSM1bZGx+a2f3360PSqnsba8to83+ZV63aODbaWh0Plbu8mgCkT6GDm+w0OJ2KbMA88KFRcOcq1TYOXkQsnnmaM9V98nPXvRJz6AScQVpKDOouH88PJMQf8ziE5fpsfY3pqUZgSVQng0mBhQ6cOHzl+olU+AuJTu+fk8b30xVhjX+8H6Tfx3nqAbYDD5pCtCFsCLCvKexDEBsQ0QkvF+0599+++d/YIa0TNgdfmACZRLoNhOZBlFNBX7YcYUEgSQwAum2TbLDbQRICjwGVeiCgSbxOiRz+7Q9z1qaPH14n7brtSnOZqyXnxdXj9Cltx8XnWip4vwNgK6/BMfIYE9wennnJYuW/HBm1Wm4Vnz4WICwJqwcaXeeGpu64Rj9z+7HfvPCueuZ3upZ2//W3sq7HT1Bl7HfVxDO4ra/ZOAkWF6hRjp7gWh99GYrRCHOAE2GF/OORM/tmJn975AfEDQNHR2NvA1Z+LfZUu53oJk1F/5PfktpkB62npksT5gZYOsFo41EaKyRIehb4Ze452mGN1tDP2E/okG4oV7d5GX9tJVD/nFloo1KuRgaY1ML4bQ+00hYFePDLQgfCgrqCFb7xx9dXXCg9vvehOy1sxjAt0QtRGV/7mytd3CzflvTOP64RhHUd8nXeJQHT+hgiwbYQ6YJk3rp1lv57lORyWzQQQOT0Jf0G/tVMu0Gn5PXKMk/ggoATBCVLAWf4FPel004jNH5Yczxx8Zv7agyybtsS+9oMf4AVZC1vonxf+CaNxfq9L5PfwJjok4p9jVvrG380pOVh2lPoEOSlPJ4Wj1Bf+eQt7rn3TVq4ri3i+qZi4IfbplFe6YNec4LkVUlEnATuDpupHnSVS3ZyW9poc0FOwtKoEegq8RQUBD4YGJTyrgQpDCmlZ75bkNJiAbguqFPpDi71gXUH0iuFNN1+3srZp+VDR7OSebb9cUVLZu4Lu/pWnwDBmaOvbMLB2Q2FdiXsiuCF268orqiqHOcyrQScE2VsgEy5yk5Kyt4PXTZwOJkBsA0a3PwuPnNwpbzPt7clElp8jMamm8WFjlODcnfiEB0NpWf5ss91qdmW7rJhnc4GHAahxzROW/BabEvRIDueLTRNf37dtXb1+/8/3RSKtVQH2VuyXA7HXj3y4o569dnH3kzPren7fjPtUDnvwEuyB7TI+/OTSPryN2pb24YHG5fXRlsGp646fODTbuyzSdN1k6drl99545CMrVoUf+yzSsRLoqAc6ou++R7ZnglQZJNCD4DCBxQCzyXoVUuXqeNJWTxEObjdF7WStIOUjeJMHQGqUPCk7TBmUgDebnZFrylUSvejQUp/qxIbCECm6LPFDEho8AOF0RXjD6sj8fkN089ZtB+lzT2wZ636rYXMjNZovuttW3XPshg9xPkC6LQDdrMAHy+SojufiGGVoZyG+JNuQT1WW1aL4cTZotzkdNpfdFfB7cySeR0BQXMnJoLBPioToO7FHzQc7lkfX7rrh2I1791z32kzGS+wXd9QOdd1/4+GPnD2S8aUPfhD3zwS/PgF0dJA5OYPhtnEo+CmF7OH2VsKzCs5IbAppNTqgBCnAbPgRBXU0t/hToB8lVktOtpmfgCgxmwHppxpnD41IiumMIPFye7sClZWlxUfN++ZHR2fYW0Xr7L5w08bYAH1s47IBCMeIdSHEitkGUkOWkU/L2S4qCt5spjOwfnAYYLurAeQoxCdGo7gPtg7zhvQoMRCd3gAawGgUNivk1OuV6A4JK00TSRqTAJkmvFIQjUff76WTspuS5mh9pKqiJFhcmJfrsJkMOoHU0BoT4OuKcIOO7lBSVhH3zKGkGnlysYXWaYlHG6YaMcurt161vONkaf1A33DTuhs33rLXV7dt8qoZrz/HW12/Zfcd18/vP1c3UbOxoq6+3NtV5G2qaQ7V7RifbdluFcNTq7YacsCBHukZWTc6Qh+ojjbWbo1y3boafl1kb4IfUCaHQRpoDs86onrv1bKjk5p757cGuL2AkCiK2gJdcq4lXpyf79jwgfkiX7SRvZoVe3XgI7Ej9FDY38/5uwV+/0Rw83P4VoWbHFq+cAKFbXRACbAxn4iuFSVzSe9OPm6xKP6dlRMFSWYDq/iTKj9wScDvmZ9nv2+vrGyveOc1ZiFs4ZcLYXU9G2m8gEGasmiOJjwTaMFHMYlkBvBwi+eUNyYf84cc6DLFQzl9Ys2cqmU185NXqKu+MpUv99HXY4UH9ggf5asrOp2f77/F4zvwqNT4TiEnpaMD8Jca4mGAh+ENjzCj4EZFJBvQ8anHL5x65MvsNfPFLOr9w29iLyt+Qw/oiEK4bybGSpTnwlHH9SZ5wSEfWtCgogBgg+yROsoKKitaOuY9lqn11p4ett188Wyptu9CJuicAjImZxpEpqMFdkZ02tGxQ6I6HZ3mVn50QC8y9eA4jyMhxXNyk/HPJmWT3+q3+nyWHDwLx6jZhUo8mU0S7LLX2DGxpbB74rb5/KJo1by7sKmKWdpHRkaQcQ6UBfpit9KDpf6+JB4tBh4dkTNMsF167o8pkNqQ7ByW0QGdqCTH3GAU1VS1qja1TyblLMXV9lmsfvRmvXHIIgqo9AhyMQDYNfMBzsKx0wgZwKXpatjfYnB7LGqeSDVrSWGY3W/1KnkitF91QS0z7wvR+w4c/HXs7pMHrz52/PXj1Pj44088cfSB++Zvuu8e7g+EwB8o5v7AVtkuajY/i9t8QJn1JJt89J6V2hDNIqDJx/fwuEoR3ORPk0y+32dFk++SFKwVqx9NmPz5fdLyjV/fu2Vt7cxebvO/ZWa/XTmMRn9ZyeNbxnp+H+V2NwR2txhUo4ucVv0XJ6gPCcI1kgm2Q+g3QVjf4+Zvi+lvTyYZZWEa+CjNvoFRRsOHKMb3MeljMCpGIyVGl9HlsGVngZI1UINmlLlNjlrCloQ3EQWbvLOtPPyp+YYN22cPzk7US2CSH+96q2HkosNMWdfdx2/4kFyLvijw2ylWBPswO3DeCiBmo2LMMjLUjAZKwSHLhhcWf1fon1S+aCGaAzaqRh9u9HTx/+L+j/L+5ON+n0VTpoqkoCWUvj2/P7N8ypPrzHWtK2KWrQekG/THAKZskP+vAa2LFd+K0SIzI+DeCuhbqQkOxbfSuJASjxu9K1JMi9G3iipBcWhRTOxQo+afl0eqh84d3LxrVWNrV7iyumfN6M3T82PtncN+j9drD1/TOdE0XOrJdXscrt7u4cmBvgZFNxkBtqPsHmLHeJ1iZoBvcK9IMXeqiCbR6eLROgSSVuVoF3QVqCq0+lEHegBoHelIZcPqB0dG5m8yX+X2FO4eLaGfp44NV2cf3xD7bdinxNL030HT55A+OQOPsjMxJ6LqAx4Aj3Jx3Bz37pzqm5pft1n1655ANcCTWTYl1o6CzudOXEP/fK6vrXp+r9S69U5miX0wWNpOD1/8ffvIxzjOoPTofwIMEsbzOhqPOkcTUSfPzitRpxIt0//8/L3nT+8Xr2KWi7+He26gn+D3wtzCj+BeS8Tgo+8tBmc/uurBNeLohw/d1CNuOrZOHMQV6F2xPbDKOP10bJJ+CmLlP8Nif4J1eAxukkRBOVHlZklZxWqzKudleJoQ5nG4ZPP/h3jF7ef/7s4JcfzM/efv/va3qevt8+f/I/Yap8NCiNPBjCcVmZwOoGtJTzoxzMRsyVWIYYbwbQWNajT5++Kb9+YM9drLP3XLPvFqAPzftlxpmMqMLgPYB+mjsAaoePoZWOMS8fjoZeJxP4SSn1wgVMyKHaLkdXqEPhb7/NaNdGQr3NeycIgGhG5SRJrkhhxwtDHjiQ4BA3dAT0GjgL8ngOs9rp6YCSKYIvh6kcVjcVgkZJuGusbltL4x6kAnVjkDgVdnxFFF4f2QpcS9eV9tKNTQEArV7tvspmU7/OXPznTRjQWB8/2dmWJmZ//5QMFG2jXzbLkfVj+1cD+5KJSC/4Bn3mjdxzh26I7TIX6cLVgETDYDp546tEP44Dt7cR+8gEt9AheUQSISAbhoDjABBtOBT4VFJOOqtmA0HReq4aDh1KDg4G9QcKL16cjceVlkOG83kj/Qt+kZ2MM2HvfXWy1MwPCMYHyDB5PjcRcMs7OgwQSyGvRdlskIG6DGhZgWCPowjannEXghxeSmS0+3B1ZUW10e80B0Svur8Q8eT35++EpPQV5+yR602TyfIzwE/JNDmuXGBAdhQZYo9uLGHsMcCcEcSYLmSvUScpROn5eU4Qm6oi7JH05L9MQeOnZzzemRM/GEz5ujo03XXQd35fwrBP826yNHq+unMHbsuZtvqj0zfCbO4NQ+NRU9fpyf50fV8/wsMqWd56v+N3eyuRiNgaIcOO/hLhXGwuiEJ30k5ybeBc00pn7GhKFJcNDVKlpbvMpRitj8LynHwyd2WG+jn/bW1Hh91dXfjbUpZ+oLW+hv2HmSh/xqs5jhlnbMFkCwhEzRz7ME6kk/RlnDaNBcjpxsSY+nSfFkARaMplWJOuy0oz7aEu3ZMr19x6aZnqiaNKg03X1vzh1799xjue8eUxVPHlBSBjjZ2VdIIWmRm7TI28WrYCQKjqYAbsk2zcnmlZ/8hG5EN2hBt9bm96G3a0vYVAhlHX6HXXIoxVPLYcMiN+zferRrpHRlfdmXv9xMu7JjdU35Q0P0nfG9061NK7qG+zZvLBK3Ttuahwb6YL8ySS8LsFl+jn+FXJwv6SC6JXkOE/jpAjhwmSJwUL+ekl5bFqPgE4Zw00SMUxmd1Q45JgVe5QcaA8g6B5+i8MOLJv3gChe4vUXuQEGg3KfDAkruhQBrOe1Yc8gTQWEMUaNhWtfIj8DtzsGx2p6uurXyGp9/VF4b6eyOrJXXeovX0MyGpqaGxuZmNjtWVLRWHm24JbpGHi0shI/ruzsb1sYebz+0cuWhdtxVoHk1uwBeI0iDqNhOSjKoqCPidiPVGahe0um3oWUaxhP8EWkQzxKV8mWbJcdk8oC9VoyfgNRWyxPBjfAP73zy9Fnx9hNP7j59+vTNp06dolN0XeyHtDT2md7B3ptu6h1UzlYSelbCU3BCwFkB+m1LYm4s/xKG+FmcBM6rLuksLmIRuPo9dIg+R3fG7rv4Mv7G+3YtPEJfB34qJXV4XyNwTl1lkSuD6QVayP14XqsCu6vxFB30V/l5MY9NSwikemdqFVLyuUajWnwU7lrVsH9y+5q6Zb2hyqq+4f7BxoObdg/VtnWX1FYOjPQfbJorWjZHW1ZFyuTuddHBcFF+YTA3v2t5f235yu7xpuHyovwif25+x1X9AX/AFwj5EQc3u5WeFOxAGQup4Frbi0k8Qsex0B10NEONvdpoMGcaLEaLLUenZm6tGCjXOe0utfTZrp9vLS1tLbnPU1bmKSopYbeWLispWVaq/ObGbIDsYS+z/wDfsRBkcRtfbX167lCCwBQLsNU6HwPlBRF0zkhFvV4chxdRP51B9aJ+dXGR00FJKFBUVlzmznMUOgvVDKOd2k2qJaFLVQq44izuSiqmoucqQiXNPaunZvq7G8v9oWBl/xVnz16x6447dt367LO33vLMM7TV21K3feP6HVVN7mXLD525++V773357s5nTsFnt5x6BnGcAHD/HWL3POIjIbJaHnQCIziA3wqA5fXg56VkpyWil/QzWpL6igGDlqTeBdFEfigY8Bd58n1un98fCBuzeKL6EnnqRJoaM+ovFuUP5EWGO0f2ztWXVFV3esYGH/lqxB9eVkt9sQP0LNv8SDijX4q0DLR2DtiDHtdQUexsZMjrWx67cZrLTCXxMj/zQ+ybRQyPZRp1jNWA1pDCDdEihr9dnz+26oknVl15bNWTT66ivhfrfrD25ch3lBdem3yQvkr3Eh0Jyj5U78cFrpXGMERAc8e4h6MjOtVv5vWV9NU9se/TvX++Z/tfViMsgg/yUzbA3gT75yBeUkK2ci6bzKU6I+3HSkcGLutRgpErFXADDEbJMAdf14lG3TYT6AXCxuGFkWnMB5LVmAwuCQX93qJCT4E7P8+SneEwOZS0cGbcXdFkIKwWrKJA2+xYSe/nB8CSciRM2/d/6EP79z3wwL6x/fvH1h048LUVI4OdeSvX3dSxLM/d9NMHfn7u3M8faLlmfOLaayfGr6GmZsehnTupe11gkJ+NPESXswWgh3pGw7ikjqHyVKmS5DRy7sdS4eWxn7KFDRsUXRiln6F3AH9mgBTW87ugXsT0L5gNPKQc14qdCQPXzJKTaQJcM2iG5prZVNlx2Aupav8d9l/5Kip83oqK7afn5k7P0f+uGq6sDJdWrd4w0D+5vn+A18kR+iozExOENpVyWVK5rVp7NIraXz9F9PoR/aDWvoL2lmr6PuKIWHjp3N1777ln791YPEdz9u7deu5c7DZ+hlUGFniG/Q4wgxVyQO6yqVL+LPQnREyLH3aq5c9ZSvlzZFH589rVm75kiv34ylVFuWWBthXrO1az/ZG5VYMdszPBPE9FTV8P7zugjeCw/+791D5fET/O3hWvfc7KV6oT3rX2eWrD0KaW5pI6f7gvbHK7/cXu6rK6lWu6V5eESurpl5oHVtaX+wpau/LzcvNCjc1tNUW1GYK+OelsrS1xlmgLR10rQ99qYUfbb1Trx1cvhFkOxF8FSEMs2HPkZAkYcRe4wW/rSQTcauahxKqUbWBM7XJGGzGo5joKy+rCPr3f6aHS6nmfxRUNz+cdypGcK32NHvS7DkPM99wWi0EUWuh1sb8bn8guaAyWl9D2nqksBZZBgOUUP0culj2gMMFu96BLcRw5mTuKZDBg48feOszqSRalCsDLTh2YOXBo/uRhuuw7JqHqnZ+Y6G/pVRunDir3rSbvgI/8ETxDQudYKySdxnuvVpoJbOk1rHSIl4lWV/M+EYE6wL+3kiYuQZXgntFsYGazYvTjaW1gunE1GSSw1cBu3HFGKXLBzkYjjkRCJlL3aHmVabC2bmh5W6230B+9w5FzfaeuNlTXUtCWo8AdBf4uYq+BTgYPXQSHhZd8UroDmXonGbTnsCwn1iVgmwAt2ryh8v5huKSjTh7nemESD9FB9nVg6x28wwGcMJ04oyU2r4hv7C4BguuA32rhjFmfktkE28O17umnn469eGBmy/79W2b30XPcrNjOnLn99tkjN2zdfvj62NrpRXYkK0MvgB0JYoeLQ1JfqOfmm8GIxL4CL088MfridyIvr/1BnfLC4Y4uPCycYH+CvzLArq7mNO+0WbG5hlALiBkDn5L2YmU98ge49aBW9DpBPyaBc48RGIRaej2GMHphiBf1W+x21C24FUYaNmo0U1QNmDmlyv+F2K4Rem/sIU5Jtr1u+vHDa7YPm0br2Lff+VmJ4I15OXEvfnj9epnmFv5h69Y4vCdVeIvICIe3G6CFSNANGiIfGNkKCkFMgho2AizQnBp2bUsPu4B17HZea5MO8VKqKw3u9YsVWQr4sUPpag0gd8dpbiVRcpDjsLOCZpjKqTGjnhqMeZkmQTLkgvsOBlLQAy4mxAUk1EQyjKYMtKkGyWjgTg641KD+BCqOLeqzEOlQdWVZSQB8HD/fGnsmuPwJNFN25D31h6jo04zEfl384VJqUx5V1KZKjovb4tv4+8voUZ4Lp69AjJ1PgmTs8Zxsliha96DoC3iGqNZdc2XJNsNWjqk5e/VzEUgrYn9k/NPJJ+xlaoU2Brh2s6gcOKv+6wohqtWv1Tl/Ea/Qblo7cVyp0D5d7fNWV3VW/4vHH24LYIW2L9C+csemzkqs0H5TDcqJoNQcC+d5zXE29sFkm7ME1vt+a4+jWJmRUn98NPSL1uQa5DfaN87G1/vCX7teNY26UtfbFHqhJXm9z7Yf2Rpf7+N8PStplCNWizkLj736IbbQHUtZVx9fNyc7vrKUurIJa1AiLil1cXozpmBqU2quFzAL1ETiMNzBYfBgHFDgZgbJZmU6PcMgR69DkTBkUB3Dk+ZkkIwqSFmZhOS5nPYcc6YnyxMHzpS+Db6QlipzqpmyFDgbfe2ZOc6s7tI1/nYT/lGeDPJzlXZX8Q7+C8sMVbhPcLid4EE3yQ0YogOY+kuASUhhQa7LZsnKjIOYkQZiKBFlORN/poI50lpa5iksfay1rKzQU5YM4mMlhZ6SEk9hifqaBOc/czixj2afcuwbJgYgrUGfAFWSuNM1MZACtBuMn/ZNHZGYTloauUnZSYinINdps2abL4kfw5P7+hA2/moCmopcnbvC7a64t6e5qadnX28ycrS6zuOpc9dHursjtd3dvCfgDWAgJ6/Ts5FWuRlNg0HUbQOAid4AilNLk2FZAp0ySto+WPFYIVv1nTNMbgVGTCW6Ig4//PCOga/63mi+DczmH7JjP6/871erfh2LXP3USoRpy1e2vLCFdcf+gbar9WsCr9MPkxtkNx7mubLAj8mlouAGExageuKnOr0eVJ8ZSO+HbYFQYR+Yep1eN5tSiasV17jlgPIt/dHLfW1SzvCHbAF/yIo9cDr0ldLrOyNKQjDZgaJ7yquNe25MFP8PDnW3DV/LXao6X6GvCVyqGceT98W7AZYNr9KF4i4WU+r0QS+ilqqWK1BL6Xr/gnp9TKUl1ex3g1bU6vbnUSOSv+FaQXChktaK/QpUorbYClSH8bU+zrUhyDPXhjo9aEO9jp83XnpNJQ+Xg7uQjiDqw8S631SUobbyBzU9qK59IqFNjFQChcK13+VWLiywB9QgMIPPMEisHlhamyQR4dUUXaIB1bNYjzDwhAnNhX3A3GCe7ASXUuCFFov7AtDcvXLiRBvuZmIfMd+f956uR/MF1z+IG6RuDcj6q3B9P+wN+oo+uSjDqEePFfYGfKljSfexK+X8eCOV+nCvdpXqCXov/ALuNwT0hmAEfGV+XingDTH+TNwtgMTlvIQ3XFo9w/3vSqXjYgoygoMusB/FCrvL43os2ACNlFQvjn1ZU8q6XoulFH74BAWqNNRgOSo21Ui80YbvMpblz4bb1m9oeKan5xHeXHOGd9ycO9cxto1O8QYb2riOhrHHZhTbbp5f99298d6eYbC72QBPl9xeXMQkvcvJRB3vOeAFrjoRTRlwocgkcS6lCcGS43Hn59qtOcBm2JBgXKIhIbzI3ia3KPzTImub2rSwJsXeCkr/AtcDNuLCXJnL6UAOer99DAIwRXovgxdYdVE/A9uisO7fcm3QQelr/zew+eK1ixW2j6/9cb52PtYS5Oc5HSJEA/04luDYkjA4EAje8nAJAoBUpMPxoCIii0G5ShWZOCx3cFiCpFfuCviBa9z5wDUslWEoMMzSoNm9ReAGOe1BRxChNF6KVIuZJw3gnXEGCsj8j/LFsNcnM5Gown9C9YRKUQ7BYcMWb90lwAX5tyKYihwu0RWzpEZIB/XNFPWwGMzSRQqXkg1kL/0+fR1g1V8wCrSmvI0C96iTLzZcfXXfwYN9/PeTBw/2HzrUz/+X79H1gGMTzyN48SypmFLBiIcTThueHvQXFTKhF2BkPUmzWxJjG0r8QbWfLyygr2B32WAnlJybcvKlHYjRiy23ZTs/Hnu69Qy80G9/7LQ7P7ij9M6Pnc4rwFe6/hONsaBIhYea6U+F2MXPPKs/UnDz2n/7zLO6wwU3rQMdxPs/QK5yiB2rPOw2K0jV++0DQagSvSACtzpp/SCKEfobrYfmKbHe97mVSltP8yeU9T4Od3ORWrnKBc5xQnJ1iXU3a+s67OrK+kthipIbX/wGzaylra9ZOZRZBYYTcF83CZGIXJPgeMMSmPu96MRbLSocxqXgWNoMJsD6Tpo1TINuCfcC7DvvWYG9wfP4Ujmkda1kZZpgj95D7wrfFq1/5XfKriT1sGh+BLd7y3lfEOcBrZo87mMlt6lhnxr3I+t5Q2uiT82Bee9Hbh1eu7LzzB3zYydO9N1yF525MfbO8r5DV13HLhzYq+aI32Rd7C1SRc4qdVgZuZQJLgqWtN+t/Y8I/xPvWlA1z5oBro14gSZ2LSgxmzvxsY6C8zegqSze2JCnnWov+mxSKfCsIlXV/mpe4BmxqJtmZg57oZBylFolNNSvYDxb5LCsvmrXxE5vibekqblk37r+aIXfHy4L1NcHioJFgeBGZt91cKy9uL4wbHeGA5X9NWMz3nW20nBxxBdoCvjqC8rzCkoPX/w18CHvRRGqeC9KCemXe5bqRikJhwSh93+gJ8XGI43L9KX8Ovyzlsv1prAN7VtnSRyPyv+v8OBRzGXwMJW8cHk88tqPJ+ER5HiUkzXy6vKycEgU9IvR0YFpF3j8k4aNlIJNaUkCH8P72RceIF0GpW031YGWq7ssVtdNNR071pTAK5Pj1UD+Xi6sjzCjobyM6aXFqOnVPo5I4qBZMkwTg2FiwET1euM0MRq5LKoYZyRhjMMWDETSG6Q5YoRvC0YeqaXRKPmKSdkdCnoKaqurKkrDwYZQQ4Jgme+ZYL74e2oO63Kk+4hvZaY7r6tsxL8SXaSusssSsa66wrujCpylneArJdOxgjSSu2T7Upyu0K9cQ9xkYHq9NA2xqzRxSbqVwsf4RUF6DxSrqvQURGorG6say0pDwb+AYovrLy5LMhcWZ5Te6yktxeKMy9KrvgRLNtT/SJxmw5xmVaSJPHApmhUDzWrAikl6o5QggcHAB+gNX5JwVfFL9MQg6A3vSj2XpyDaWFeL/JagnOk9U07ty/EnDeq7LO0a8521+S7nvb37eroP9FyWdv+rzl2fV9BQ191dF+nqUuRW8LJiTrl6enTgvA8r571UT4rBYQlngjmzYFZNBMu5+G2DiDY0Ay4JmrCCAY+U57IygBmV9qzJgUwDQyJh9fM4L+rL5LNVjPDtcROWucIV2y5/hfn93N76vm/v44Kk49fMgd9Pmenyl8gNl/02iX93IJMaDPHrJvEf2V1THQrW1VbX19SXlwarQlXAGj6/1+41Y6ijeAdSvHnuEpU0IbWUxidFqij9RHR21zVC7FHTNe1t0XU7b2xbcXjdzE3Xa1xy7anu0ozcdd30ns0ZL7Fa+t2h24+6HR+oWd01MQEcMllcWwocEqsaLGkorRmmB2/r7ub9kwLvnwxquVUHcoGTikIeJaIPGMH77rnVyfeWW51cnFv1XSq3ytspFmVWl5VXGTfOak2Z19ZHWzrW1UZWJY6qt1jPXql2aZaubdSHdHVB7eBaUHoewUfCnkc3zkRLdD268/PQo/ib9D7y86gl+x894AWl9UC+qvo9CmyV/9Ow8bOrJWH7B/Bs0mD7uOrLKLAFOWyFmJco9OTngS+jgSioHowKoXQJCAvcCRgNl4FRzaAsDeas4q2kQUqZ4qCIKqyZHNYiUkpulTMSlNSsqQpoijXNWBLqNGuqXrj0d0HovcV2WyhQXOot9RTk5SbQzbw0ulV0sQFdEvNHUyxnGgGeSbWVDCwZodm8Xz81Hzy6ZD75W/PzHcCbzHI/Z0e4PgOuzwF+fPfrkaXg+nPAP8yyjrMMxJuvwPVtwDN6JZ+s1zGIxHgjPyPHlEY5pXfCZsN8suqoCnC/25QdXjk/z77Bd/XivcyC8ruATf0rYW8lXjcypOxmrh67G+k0lolOYMtPoj3YCe/hpzosgkl8MClbjAacTqyVkkqAyWI3BmFpSaH5EIB0czKhLx7F3k/en2cW7CC3JXiGkosFhv1unLqKEaaRaucpc8mZr5JANa9XCkdx9jBmfFRNp6WAQmFbfTh+ytT4/dH22pr8dct6upo3jJ7YN3fqurUj9ULBqmuE8r7q5ua6plaWE+6xGSdy8gZaly1//uyNHz151W7w63csi10IeJcN9q9ardbe8d5GoGMO8ZKvyPbiImaQXE6m02t9jqLa11RCUD6IIh46HXfd1wwkNT8ateZHZS8qlv5+altk/Bq4ffL5s2DgjtZSXwV7mmcFHsCkuMNm8Vq9Wjulaal2SmGRE5/UX/nhRT57SsMlm0946aruYx6QIz3nuaAMhsmGNQPvswcTTUJqH+Z1GBEnN2MyvyJ72pqVf+WaPJZNWfNBDF6Tl6S/UMQ1vmaQr5mLefBcl90mMp5NY+KxJdd24OLKoKFFi6s6PGX9/1YjzRSsV6qhZRyGTA6Dj9woZ3qLmaTPdfH8t8JhZSDH3Iuf4DXKnNnWDCwJnVsOLTpkWfKLk7LNZi0scOc5IZix+RAp49K7uIivUre0ZhFrpRD77eT4LxnXPOInMwp+PoOeYXkmdjtPXAqvYvgUv8d0l8TI4s4vLsz3u/02q4JP/hL4LBG6pSD06dRYLQWZd1IMjkAGSQF9lW2Av7CTuEIuxWoBCMpSS8nG1UiKCavtdrtNPUbGKr4lpnaqsyl/lTy8kxq3x2JqBRF9TiuF5LxzPfOwu/gpjlotwojHCb6slQ81kfSM9ILRoj1aPpZ7o1oOL1hW4lPaIbT0uyOeko8qOXqXkrEvP3nQnBuaKbnq+NXOHHg9eDy4w2A5+Hpge2bmAWo8ck68puBwz8Pz94uHC27oemR3Ce2lj20vjT3NiJqzpv8O+gRz5KvlnEQnKWbLSe/ftp8U1U5yTykd5kY+ubGUuVDraHBV/r8DF6qmZLhOcN8hGSz6fa6ZNLiCPMe/UbbwHD/RaeAJ8anzOqI7thR07uRP0kGUjQ4OpDJzPB1IRYUlw/k9RYGlUbBB0WCCCiva1VzQX/cv7hMuMkoM9ZeBogJbAlxFCfiX+loa7G7ZCx/jF8GEzl0Cv0nZmp9X5Mnz5ftsVo4pVuMswnSxHkhG+niKFkjbpj+k+528Nxf4yAweOGgBpTvXaskB7/F99ejyQCWtT/d5ziZpvbrc49TmGChzjdrkVqA5AWkXWCaXfpyn0psFeqhHpEuJf3xGQQDbilzKpBFlQoHDhtMJeKJm9XzTBB9QcEVrVaB1X+RHwrNmdSzRsv9kt/X8Pvr4zDqssuc0yATcnKSYbJVNST3Kyg7nG3QMQ2EM5iYGpGSauMGjpSJ+DjH4XMpHk7Ir14VekKs4FwKNnGyFesbF1Ast1uxptPxa2q6mUXV/2r4u/HlBz27n/XNunN1tBq7OBgBZP/A47cNxcFRPtvNaUnGWF4VJOq0eLD8PLnP5gxaLxYAzHNWKNX1KWWlj1EST5shu9HgCBZ7aZnmgvvrl+EjZhm5XQXZ7XltjqDtPLXXkc7j0rJIVkzISIWPymhCYnSAVxEqql5x2gJH7tZkYBWIPhAShnDLji85qrRCTAyhrWiBXUV5TVR6piGA2z1/CbSfP5+nVpIQK73uZ09W3zA9YNK3sj9YFs5t3pGX15FBlb5uaxyvtinDMSrrzbMGlpncpMyYjwnnwCfPIcnlZWsdaXq4LncS/Ym4t1k8sMbu2OPRCS9r8Wnavdt7H52+BvGPlxmKYsJAjAdP7n8PFfdj0WVwCqIGUeVzMrOgAhT4PAX0KsOYmDRYIyF288Rnd2TiVdCkQufMTdNJfmk5qL/RiUnUr7dhp1BL6lK7sBL2C3E9ZDGM+ECwdxsk0GPNyE3TTX4JuGoTppPMo/dqp1PuW0rOtzGnezHvWc0kRau+iAnd+vFd8qenEeTieWIkAlhhPrAKx5JTiWJ9CqqWmFdM/avQS+Jy1rwvNHKYycrPsKDVnCXpdyrw1LVwtBluvhzB2m8RbxwxLjFwLLPmVRaPX8ni3XdjjTh2/Zrzc+DXFsXY5JbMo+aOhpaaxfajUkx/CRIXBmpkvdrgLlpzP9oOCsBcAMHnCebWGgy4lZv//W30b7stqsLcSKSRPy3bsUcQcD3FRCbyynGwmqj5jQE+xmhJPzYcHjJzqGdrGSLABvNUaHJ8A5hsu+V34Fl7AMwrjBozt4Et6bF4Rtl3ui+ACeYwGSvJzledR4TA4Q6GxEEyxRCUT388cbTd5d59LmU6dNFRvp7KL99wz39eHO7l99iB9LnYn37ada1aZ5TUXP9u2Cif54HxhsEV+2Kd8fLaTGWDMpmD3+8G8gJWMF0FAWKrDwFuaAoB5QUS849DhDyR1HCrFpmmGJzGKewOYl4Lq5pX99VWxryhTub+1pb4nEreRFxSdY+Cz/nwkTAblPsyHOiF8pGbKxGzeAATbSKiEQRrGZrNoDFW7mCQWAX8o6A8HwgH47c1Bs6ilNFMtY/TS0wBXuIYQ4orW5jWb8jy7DqdMBiw3t7YC5K7mpqEG/YevwdSm9AROCUzUDj8U76TINmeJ+t53rxx2LF05rI3TSCrWfVQdpaFW6b6Z0EGL8t+JjHKhOz+Pw/Ee8t+egveY/1ZhWzIL/KqiwdPz35u1uRt8frpwH3gIQbJJ3rB4grrfV+gRpV4iGYEllZz2UhPVDcpEdXc+Jd6i/KA7mDpZPeOyk9UFn/I8tajLTJecsn6qZ1QasLd32gcNo4snrgtsYoW5t9e8YkLJTfG5i0Iun7vYTb4jO51UyIhPXxT6OzvaVogmdQBjuzqAMTN9imIWzcgwTROTCTB8t1mMHdosxr/iLpOyv7WFkna5pbu1e+nxjOa/bjxjNInM73lU4xSS3il3OAeksfc8tvFHm1aa16wxy0pPPnaH/Bp4DJ9j55Hz433FiRoymy0xZ6xReSpd3SsnTmRVdldWdrMLT2qzCymPAb/FLPE5+IvPF741P8/z/6DHcM48+L868AaK5AKjQYrXuF9q3jz6j8rM+dhWXrR28YvshOa76nG+ofAtkqlMyFYmHOZkmw2S7t2GHHJXOT7o8J/g1knDDtljuAJT5+I/DfC6yOBjTipSbM9zA5M6+bQ8gabBzp+Qhm+pCmRd8oeTT+T71UcoKMgJaQ6Hgufj3McAYdZ8DI5zFvoUGaZUnwLnO94iLMP5jlgT6DHgiGykAtMem7gtiQr5/pAy8DyZDrY0GOIkMaa7Osn0+Wg6NCzpGQLZfLa9SNC2z6Xvrj+VBCw+KFPF3l4Z8FdW+gOINA1rbKbieo7PsnRix3F8mqXQm8S+8WlxS6GaGMqZwPIT6nJJyNEGdVXK7cFF3jcekv34FD58Bp+BKc3SKWg5HCrTNkhhzMuAAXB46RuxQzXV0yfO1vwDtb/l6W+hE7G3J/quwaO1hQXApx/wseO945yrPuwvI4V9q5LYdzmmBAEfXABndTo4JuU1G+blmn3qxM573QNRutMceznc3/XL0ngvw3neBxaQvepTE8CbgtjuPT07AZuDkpsTYo+hLKb0I2g1vcrZlJKH3Kd4kDmJ8ZuYjGS97vS3BG0u9d98MCeKedLhUewVPEJJPTCaU89QNDo9BHRy4nMLVDo5gVBaTJdKLSSX+lCLVHIpDkAKxY6o3kkK0d5MxJUK3ZQ86VbZkqCPCwgk6rRh1ErjaYJI+jiRCohO0B1Lo5Q+TimIP5wOjVbSkrRS3ZZkcj2szgdLoZgQVJwVkugZ+JHa++FG2QSXCpwN/V/WAFJEl2gCealnclNT18zU4taA6qKnyh/xf6maw6KcyYyq5255CEtergviBv1fcvjGIUk9UPlk77pNrd2bplKPUt4seqb8gu/pamVu8cKbwkH2FXA3isi/Kpvmxawa+G/bMMtrmDZSgwHzFpTqpyXKgwY1b9yQ+kWC38M/jVPgqgwrl/Awg//J/ZRxHns5eI0m1qJe8mI8d1OuJUmXyrXaVSR+ERDpctdgcZS5qDDgtVgtVqvXx7vqkJVwA6nXiS2iegmc9EROw0v/q2/oQx9a3UOviP1LxPiP/6hvos2x/rK6Uw9+/ER9Of08XX/62otvX0uPdR7dcqx3S/bTD3/6uez4uaYwDbFPPo9+7lfKwLLtVC+iE5+hZ1i+4ubvGJLemVS+6ON1FEayLQNLRcRpjEyxMBfdehQgXiFSEf8S7Iz2HXKJr0/KNi2O8gV9WBKWg08ECy4qBVPGGAM36eqVaigbjw02xoOCG5tbrj547MSBw01Ne3dfE4tetX//Va/Gp6xv2nTPsaMPzMzcfjSDPfbY4/QAD6SUHM8U6HJ8tkoudk0oT1fJdTmVGqO/6BkrvPFq0XNWXsLWq/RnrdAjim/E592Cns8CWdutlPNZkybeWnKyDSIOvXWkDb2FD8AC/M1G3yLkKeNvB/gZgzICl/aiatdo9hCnmRvPFhWauYFoSbHf0pRzKKTj8edSpFO15mLqLRA1QZZOQVajzXjEeVa3gM7PArhuUCjiBHKJSeSyA73A+Lj5B2zxByohnUqz22Jq5iupyCVJ+oQTaYoGLI2mCkopZL1OMQQaZZlei1f5c3eAH70Qr9bLtWlP3gkG/Ck57b/o+TvcIlzmGTyxh4FRL/0gHvqSFi/wecjAs1hFy3PdKRORA35fUtPiXzkX2QIwX3I2MrDopccjM5fqj+AzjQT+TKMI5qJcQNlcCSgbDunxwY5UR6qpqNPxMUFKhRQO4ZmNE1sYjNRWVfjLglZ0jXiBZuiydFbHniSVazaXVxlPjnGqN63euyVO9aax7dsP7KirW9Uqa4WbUxmjnPzVef6ZFPKvn9iXUaKrDdW2xucPZS8IfC51HeLFOQbxCgURr2rAq+pyeE0Kg3U1leX+0qXxCr0HtKzY39/V3jlQHqlade7A5l2DDS1doYrq3pHR7auVNn9vsU/Bqq2vwe8pLnKUwlZFV4dxq+yuvu6eMY6UVpuqycFDfFZci9yUJgclIAiLzy6SpKEAxQFF8T2Ig6pxLicRZxTdc2mhYMc11zMuF0GQi7ByppEiF2EQDA57UjvtZGK+OpeOUDAhH/r3Ih+qjrmkiAQVfXMZMfm+5oQy5TlbQHuJmNHnM0MMpZ16LHrqliPxGEPlsVuas648fSt2reqnK0/h0hx0xueVf1joxHgNu0aDpgxBQgdd6eyVmF7adonR5fl+ZXg5ZoSXHF6engdInWVelJ4PSB9uzj69ODeg9TX+M69l8JMdioMZwKmYIk7FRO+G4Nn14iZHN3hN2tdEfMCzfolOyEnZTojP63FjmdllmyEXjzRJdEJ+LmWcyaJOyC+njzSJ12gMw5I46fZji2s0AvF5LOrEluGlCzWKeX3kpb67qFojlDzmheikS5dsZNpt/gAv1jDymbPpxRpLdI0kl2s8lNIkklaqMp3aFhLf5x/xeDsXn8cCTg1EjPq/qHFXCb7i2/OMGnYt2pghLepS9uOPEHMp66+RbYn9UCH5Hyg+4nAmE+12NTBLq255TYvMBLV/9gS4+naIzBrkOq2Dlj+1PFGrkeiiLciHmD7blKF00xpSumkv0eKr9de+lt7hm9Rpu8TsC2XWuNLbi3OF47O+sbtX6H2Pz5DjE1zSxot/D/M02mzxeI+vMlu88t3We5cZ+Xy91HHiv8bsijZLfF08r6Lgdx+sZ8EO66Rp/MrZxdySGNpsuCbGLAkcQ2ouOg3PM0peWkP0yaS8oYKr8lyfaTkjsbaiEYu0CpKJgSXRdsuedCBTPp+UjaDeU+H0czi1XGMKha5U841xIv1UATV13nwjNlwuOe99KTopw95Nf/mw+SQ6Bd/b+qOXW/99D5tXZ4reSOeFWrCl+XxGYDbvOOCPyj1oo+oYWrWk7zvY13+6hn13bfTw4agCv5vtp/nCDGhpKynjdyjS5tESPo6WxKfRgn6Oz8+0KuYpWRlfkV/hTihggdW53XVJKpfDejc9IhQCN6vPJ8jJZgLDCtXLP58gy5RhEBmxUIs2BJcunrnGfErxcalWhVzK7k6Z9UJJDuj8AvYWYJonO4FOpNcKu6QQq4MMWmiGozxqi1SBliyk4HThw1zDfiHnc5WurgHL0RsK6voab6prKxBvMDNTS1PmBsvua//5e8vLur7797HlAHkp3H8W4g4rcOUyOYr9fAblVAE8cpHotmnHotGBeDdTk6D0MOXacwM2n1Uy8tHkXnz8AqBXrB5+6eqi3kJaKtLPiaOrNvS3z9KCex44eeudtOC2jNiL4iBd7Qjt3SYPjV/4/Oe+/Pia7+/fmjq/maTNaf7LP8uHz954DzOh34hV0O8lrmEL734NW7joZq+p15TRX5BvsAWSQeofM/I0v6J4TJoErUGPKydxt2k+GWHyUXV+LFd4bTQiOZ8rl8tdK7sCHlZaVFq6ovqWD+MzFyroa+SbAp7k1T+WQZUBksr91eBiDeX3j0+nVZ4QMfmoI3k+bTYFxzNSIZfn8gWeggWKPLW4AkJTsbCZfJMchTXwmcva8zxT7qfcLbrU3RqTbsaQHvQMp4eTtD7uMLIESbLQF6BTeOjEiWJTBsiPKQPkcTgm0OVxhyPpsREKZVTZTaXS8xVymXNld7AwQa4wQlJYc8uH7YrOANrR2zntXACLM4MlyJcVX1QhoA0/A4zjICINARaHVa06j+O9JA2+WoFQITAJ0nJoCuo4NAxpTG/jNM7FMxqXAswSqzqCyprR1DUjSy1aVKzQIrEF4cKy0qLiKoV3Wsj/oT30X0Bnavw8nuBAO+fnRlUp2v98cHDw4OD/GWpeNjB4ECSgGnTES+Qublc9fI6w0sbFx7aM00E7/mPlD2yKNwQs9RdVGwMWiPLK1Nd2X3W1T20USH5F2CqJl9bxWcD6C2AltHny6iR5bYa8YleSv6uPzwlySJXJQ4LxubWATxh0ng8rUI0QveOzVPOpQXJTo0HsFzFjyAcCZ5qYPoNKBgj4kiJ5g4EPQxg3opPtg8iouLDAh5UrfvidhXFAgz8aWUG1HBvEfhj/4TNpog7UjGF/9Iox20Du2R1TffX1Tde4f2r9/vO2v8/sautv7x268qR9o5XWD/defVPtqO/u3uG+1b01Vwbnr+/j9bO0VOhSnjON+jo3xyAYUEbhFzHQoxIeAt0MdoI/MRhfBTLF0CYNOSAy5RGxUe+JR8QuvxMYycaf5GTzh/nz2unuA7PX0g2HwFeWNuTMD4odJ82bcCry4DDbGvsabVm9fnn18/T022/HDn01siz230j7LeA0+NhZJSqXuPIzGhjtRZPVk64/y3OYHvWn5CyikhFsll5yeQXfxXdoacfa8diPaWB8bUcp5kDtgqd/Yz/tol3w4hGUfb4ecMtgz8JaDtlq5qeogkTw2OegheodWEBnCeuzcRSwFA6F6cL1grt/YoD20t6BG/yFjF2Mgftf0jU8QktiL48cKC5X7pvAgT+ZI/4MRVNGKg5cPQ3hczCJmZoFvZ2bgig27BqB4xqjbPvFdwB4/+DIOA3Efjx+VXUhtV8h5I5O9Meeij3VfyRi43gs/BLweBDWA5nKNOJsaiqRHtSEB5Vye4b3trga26jLSKMupytqoQtCXt+GgdiTsScHbihzCezBiwu0VB4dib1CwyP7S/yU4TMIioBZLPyM3oR3xyoWplNmfxOKp4oHrU7chGAkGvZjqhvHkjrFa64Rr3nuzGOPnXlky3/+13/FPkUn6frYp9Tnc1uZFRjJIpv5E57hZgctfCMtXouXWS++gT/qc2KZCD6Li0zJGdlUr8uhoj7xnFi1Xm3NAOpdcUriz/BTU/BKE4he1Onnlvh0UjbZsKpArbnzciZWHwqbeL6Ol4k3fmp+dHTr3Ngq2I36EA2BH4qPhm0amgqN5flKGpX9NnHf5y3iJU8qYWu2p4BRSaL84QgGftaU9I5oELTpRD7tkCztWbcGA/cAeWpFQTd0iW/yuUT4dS0Rg/kayqTFj8dN/hqmHAKcAHxenCde9bD4IbnYGoWlEKzXXV61rDMUqQ1cad4MZNk2W9+1pzBz0wZrZwfLyvKXNCrPzW0a3GSzXPwAPnbl/wGOnsOvAAAAAAEAAAACAEJusQvBXw889QAfA+gAAAAAzg7u4QAAAADWN/0Z/9b/AwPCA9oAAAAIAAIAAAAAAAB42mNgZGBgkfrHw8DA/Of/tf9TmA8xAEWQAaMmAJgFBoEAAAB42m2UzUtUYRTGn3NeEs0pUxmYZgwza1KnaSYShRQpUGc0B/uYaCQiCgQXbVq0qHamtQoGFxa0MfAPaFXYNvoXglr1hauKNhapdHvO671i5sBvnnvfz3Pe57xXbqIN/EmJf6sbCJCTZRQ1jyQ56GZw2tVhUNIoyhBaSEpeYR/7xji2Qx6j2+ZoLSps6yAnSSeJk8MkHb7323rW5veAHzto65jKLxxw6zilpWBNb6GsA8hrlRpHWb5S7/N9gc9ZciJY0SnqOsouieO6yP4X7L8Q6iQ1h73ahJjOY1TPo8YVGXM/oAPBH66ZYB55i5l6VPcz1lrskX6ktB2tXGdcPiCjl5DVNDJyFfXagiYtsD2BPkkEnzTB5yMouMsYt3Yd4XjOszkyi5J8RoPcQZ2ewaj8huoyYvIjWJNVqLxGM/dtlBk8pLYx/x4fE9sjD8Kz6SIxIjaWOiTPkHLtOKsVnvc44zMf6IFOo0cqjD+PXt9WRRdp8TkNM64171dO8vSvyjEVTNh89xy9ISl6kPXnvwMuH3z3nsQ3PImgH42kWbLBF/JR59Cw6cd28rji1TzZinlykXMmGKed/w64EbR6T9L/Qj/qyG568o68pceZTT+2Y7VmSk+2Yp54z00tX9uTufr9Iq36+LI+v2tUy99iiNTqkzXCsxhmPGOszQzro8ZqVG6j4HUWBY1hlxSDwJ+RxRmpnQtjcwvocw+43qQfXwr1kNWz1dR/yhqXR6yz+TCfSKM6Z01tV3lKr7vJE9ZGnPdiDp3yDXDvWXuRFvk9+EkWQ+6RN6SHfXbnQ3hvkryDSaygixwzZIm1t0R9SaaZjyBnc4XnJteRtXXt++Cm6esMbpC7kbK9lTlBz/HOTaH+L6hoz3V42mNgYNCCwxCGEoZHjBaM05iEmLSYfJhymJYw3WFmYpZhtmL2YW5iXsf8gsWOpYBlBysXqx5rA+sxNjY2P7Y0ti62RWwf2NvYt3AwcDhwVHAs4TjFKcZpxxnCWcK5hPMA5y8uNa4Iri6uM9xs3AHcBdzzuPdwf+CR4XHjKeGZxrOC5xTPB14+XgXeKt5HfHJ8dXyH+CX49/C/E1ATSBGYILBDkE8wRLBJ8JaQm9AEoXvCYsIRwnXCm4TviPCJWIm0iCwQeSOqJ5onug4If4jZiLWJfRO3EE8RPyb+RyJP4pLEJ0kRST3JOZL7JH9J6UilSe2ROictIu0gnSA9R3qP9DcZCZkCmUuyCbIHZH/IGcgVyZ2TV5KfIH9FwUehSWGHwjdFN8U0xTbFdYrPlPSU2pSOKDMpeyivUP6nIqVSoLJC5YGqkmqZ6irVB2ppaqfU9dRnadhp3NAs02rS+qHtpj1F+5VOnk6fzjqdG7oqujV6Qno+em16J/Tt9JfpPzOwMmgzuGSoYbjK8JmRjtE0oyfGEcaLjF+YWJl0mFwyDTOdZ6ZlVmJ2zVzEPMv8isUci0MWNywZLA0sGyyPWX6zMrCKs5pidcpawzrN+pANh42XzSfbKtt9diJ2CXaH7CXsC+zvOLg5LHFkcTRz7HP85dTkdMhZzDnFeY7zFRchlzSXZS7PXNlcbVxrXNe4fsEO3ZjcBNzk3Czcgtya3La43XJXcE9zX+C+z/2P+x8PIQ81IGzxuODJ5mnkmeU5w/OA5zUvLa8dAEIzwdEAAQAAASkARwAFAAAAAAACAHIAhACLAAABoAF+AAAAAHjalVTLbtNQED1+8KgoUVmAUFdeoAqkYtJEohCxqSCpkApIJAIJsXFbN5g2cXESEFnxASxY8Qks+BIorNjBJ/AVnBmPoyRK1KCre33ueObM3OO5BnDZceHB8ZcAfOHMsYM17nLsooSfhj18wB/DPm47LwyfwarzyfBZBM5Xw+fQdU4Mn0fLvWN4CQ33o+ELuOf+MryMda9k+CJeejXDJbS8z4ZXcNX7a/gSlv2i/m+44hex31H2rxk+ob1l+AdW/Nc5/u1h1R/iARK0OfucQ8TYR8AZcR8R7SHFMd4jU69XtAa4TusNPisoY4PrTUNVrNPaolfM5yNGDhl1xCFM97nPyCVrpNlSdGmPuO5rXEzPGAdqT5hDopoIscXZoCUzi0T0iJ4wRvJIzQkG6OApcZtIMmbMKGtGvoT+0/ljbGOXEWuoMz5WzmN6xjjkzMgmebrMvo0a8yxWQW2kS3XBiGCq6meavTfSp8LTl5Wx4CvYhGucaX6+RLG86auHnLej2Q5pS6n5/363cErdYIa+gSkcUOPgFJUD1XkRztO5pEv7fFPDLY53OkLVaX5MqJ3emRO7N1FX4bujXZpz5vdmoL0svKJ0rucW2SL65bvJGLkvs7/37DqiMa5QVWnz7dEEZ4+WHTykdnU8ZifU9X4K57z+GO+h58S7dgflrm9oZFNPFpAvxVu13tVKK6yvyp2sm6PO39TaD5hjwGfKahNl66lumeo/4K4xytLEG1oS1Zh/gX/xR+EOAAB42m3QV2xbVRzH8e+vdezGrbv33m06bSdO4m4ntjsIKaQNI8xb27FNnetw40to2AJatkBI8ARivQBibxDwAIi9xEaCB/Yq4gEQs+D4XBCVONI9n3P////533MPI6iNQweJ8j9DDdVnhEbKx0h81OEnwCjqCTKaMYQYyzjGM4GJTGIyU5jKNKYzg5nMYjZzmMs85rOAhSxiMUtYyjKW08AKVrKK1axhLWEi1a830kSMZlpoJc461rOBjWxiM1tI0EY7SVKk2co2trODI+jgSDrZyVEcTRe72E03x3Asx3E8PZzAiZzEyZzCqViqk18BbuUiLuZJruMr9nMVl3MDt3ObRnEZH3Ih16peQa7kei7hGT7WaG7kDn7iR37mFu7iRZ7nbvaQ4WqyvEyOF3iJ13mFV3mNr+nlLd7gTe4hzw9cw7u8zTsU+JaDXMppFNlLHyVsbqLM6fTjMIBLhTMY5BvOZIh9nMU5nM2j3Mx5nMv5XMB3fM/jGqMQf3KIv4TGapzGS5qgiZqkyfzCr/zGe5qiqZqm6ZqhmXzCp5ql2ZqjuZqn+dzLfVqghVqkxVqipfzOH3zG51qm5WrQCq3UKp7Qaq3RWoX5gi95n4/4QBFF1agmxdSsFrUqrnVarw3aqE3arC3czwM8zCM8y4M8xHMc4E4leIqn1aZ2rlBSKaW1lce0Tdu1w58v7esvRAzRgGsXw+Fw0tiaMsY9E2FPL9/m1bc1esYDiXK+bOf2BiyjP5mxnLLtzxqSGadsVQIpryjnFaVMNmfosDJuJecvGTpMsFTD15EtV3yl6uTvNGnb0Gmq7BqhnQXXzluO21ey3Eqo/N83f5fZ4Bi6zD7HsMsEBwy7TbBSo67bKdr5Ond4DnUf1t89rH+P2TxUI9hTPaqVyeTsSnDo32X11/r2ZK3anTUlW4eNVi/dM+IZ9Wz0bPKMeTZ7tnj+0yfumTBGvL6RSLC3mHedXNYaKJhQNG2MpX0p1ynXW45THizleiuB2srtD9Z0ivlCxSSz5UG7tieWbh823WaOWzX6N88BNdMAeNpj8N7BcCIoYiMjY1/kBsadHAwcDMkFGxnYnRw4GRgiPS21GdgZtMB8gTSWOBY/DjsOA3Y1VjkWdg6ocBZTElMYmxubOas2sxITWJjPyZFT8oD4AeED/Ad4HDgPsB8AmsIJlBAFSjA4oECwBDODy0YVxo7AiA0OHREbmVNcNmqAeDs4GEBcBpdI6Y3qIIFdHA0MjCwOHckhEGEQcBDIYEpgCmBzYDNi1WBWYGLn0drB+L91A0vvRiYGl82sKWwMLi4ABPo1hQAAAVoSTJkAAA==') format('woff'); +} + + + +@font-face { +font-family: Fira; +font-style: italic; +font-weight: 300; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} +@font-face { +font-family: Fira; +font-style: italic; +font-weight: 400; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} + + +@font-face { +font-family: Fira-Mono; +font-style: normal; +font-weight: normal; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} +@font-face { +font-family: Fira-Mono; +font-style: normal; +font-weight: 500; +font-stretch: normal; +src: url('data:application/font-woff;charset=utf-8;base64,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') format('woff'); +} + + + +/************* Start Fira license ******************* +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +************** End Fira license *********************/ + + diff --git a/clones/download.racket-lang.org/releases/8.6/doc/manual-racket.css b/clones/download.racket-lang.org/releases/8.6/doc/manual-racket.css new file mode 100644 index 00000000..19768b1a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/manual-racket.css @@ -0,0 +1,326 @@ +/* See the beginning of "manual.css". */ + +/* Monospace: */ + +.RktIn, .RktRdr, .RktPn, .RktMeta, +.RktMod, .RktKw, .RktVar, .RktSym, +.RktRes, .RktOut, .RktCmt, .RktVal, +.RktBlk, .RktErr { + font-family: 'Fira-Mono', monospace; + white-space: inherit; + font-size: 1rem; + line-height: 1.5; + +} + +/* this selctor grabs the first linked Racket symbol +in a definition box (i.e., the symbol being defined) */ +a.RktValDef, a.RktStxDef, a.RktSymDef, +span.RktValDef, span.RktStxDef, span.RktSymDef +{ + font-size: 1.1rem; + color: black; + font-weight: 500; +} + + +.inheritedlbl { + font-family: 'Fira', sans-serif; +} + +.RBackgroundLabelInner { + font-family: inherit; +} + +/* ---------------------------------------- */ +/* Inherited methods, left margin */ + +.inherited { + width: 95%; + margin-top: 0.5em; + text-align: left; + background-color: inherit; +} + +.inherited td { + font-size: 82%; + padding-left: 0.5rem; + line-height: 1.3; + text-indent: 0; + padding-right: 0; +} + +.inheritedlbl { + font-style: normal; +} + +/* ---------------------------------------- */ +/* Racket text styles */ + +.RktIn { + color: #cc6633; + background-color: #eee; + white-space: pre; +} + +.RktInBG { + background-color: #eee; +} + + +.refcolumn .RktInBG { + background-color: white; +} + +.RktRdr { +} + +.RktPn { + color: #843c24; +} + +.RktMeta { + color: black; +} + +.RktMod { + color: inherit; +} + +.RktOpt { + color: black; + font-style: italic; +} + +.RktKw { + color: black; +} + +.RktErr { + color: red; + font-style: italic; + font-weight: 400; +} + +.RktVar { + position: relative; + left: -1px; font-style: italic; + color: #444; +} + +.SVInsetFlow .RktVar { + font-weight: 400; + color: #444; +} + + +.RktSym { + color: inherit; +} + + + +.RktValLink, .RktStxLink, .RktModLink { + text-decoration: none; + color: #07A; + font-size: 1rem; +} + +/* for syntax links within headings */ +h2 a.RktStxLink, h3 a.RktStxLink, h4 a.RktStxLink, h5 a.RktStxLink, +h2 a.RktValLink, h3 a.RktValLink, h4 a.RktValLink, h5 a.RktValLink, +h2 .RktSym, h3 .RktSym, h4 .RktSym, h5 .RktSym, +h2 .RktMod, h3 .RktMod, h4 .RktMod, h5 .RktMod, +h2 .RktVal, h3 .RktVal, h4 .RktVal, h5 .RktVal, +h2 .RktPn, h3 .RktPn, h4 .RktPn, h5 .RktPn { + color: #333; + font-size: 1.50rem; + font-weight: 400; +} + +.toptoclink .RktStxLink, .toclink .RktStxLink, +.toptoclink .RktValLink, .toclink .RktValLink, +.toptoclink .RktModLink, .toclink .RktModLink { + color: inherit; +} + +.tocset .RktValLink, .tocset .RktStxLink, .tocset .RktModLink, .tocset .RktSym { + color: black; + font-weight: 400; + font-size: 0.9rem; +} + +.tocset td a.tocviewselflink .RktValLink, +.tocset td a.tocviewselflink .RktStxLink, +.tocset td a.tocviewselflink .RktMod, +.tocset td a.tocviewselflink .RktSym { + font-weight: lighter; + color: white; +} + + +.RktRes { + color: #0000af; +} + +.RktOut { + color: #960096; +} + +.RktCmt { + color: #c2741f; +} + +.RktVal { + color: #228b22; +} + +/* ---------------------------------------- */ +/* Some inline styles */ + +.together { /* for definitions grouped together in one box */ + width: 100%; + border-top: 2px solid white; +} + +tbody > tr:first-child > td > .together { + border-top: 0px; /* erase border on first instance of together */ +} + +.RktBlk { + white-space: pre; + text-align: left; +} + +.highlighted { + font-size: 1rem; + background-color: #fee; +} + +.defmodule { + font-family: 'Fira-Mono', monospace; + padding: 0.25rem 0.75rem 0.25rem 0.5rem; + margin-bottom: 1rem; + width: 100%; + background-color: #ebf0f4; +} + +.defmodule a { + color: #444; +} + + +.defmodule td span.hspace:first-child { + position: absolute; + width: 0; + display: inline-block; +} + +.defmodule .RpackageSpec .Smaller, +.defmodule .RpackageSpec .stt { + font-size: 1rem; +} + +/* make parens ordinary color in defmodule */ +.defmodule .RktPn { + color: inherit; +} + +.specgrammar { + float: none; + padding-left: 1em; +} + + +.RBibliography td { + vertical-align: text-top; + padding-top: 1em; +} + +.leftindent { + margin-left: 2rem; + margin-right: 0em; +} + +.insetpara { + margin-left: 1em; + margin-right: 1em; +} + +.SCodeFlow .Rfilebox { + margin-left: -1em; /* see 17.2 of guide, module languages */ +} + +.Rfiletitle { + text-align: right; + background-color: #eee; +} + +.SCodeFlow .Rfiletitle { + border-top: 1px dotted gray; + border-right: 1px dotted gray; +} + + +.Rfilename { + border-top: 0; + border-right: 0; + padding-left: 0.5em; + padding-right: 0.5em; + background-color: inherit; +} + +.Rfilecontent { + margin: 0.5em; +} + +.RpackageSpec { + padding-right: 0; +} + +/* ---------------------------------------- */ +/* For background labels */ + +.RBackgroundLabel { + float: right; + width: 0px; + height: 0px; +} + +.RBackgroundLabelInner { + position: relative; + width: 25em; + left: -25.5em; + top: 0.20rem; /* sensitive to monospaced font choice */ + text-align: right; + z-index: 0; + font-weight: 300; + font-family: 'Fira-Mono', monospace; + font-size: 0.9rem; + color: gray; +} + + +.RpackageSpec .Smaller { + font-weight: 300; + font-family: 'Fira-Mono', monospace; + font-size: 0.9rem; +} + +.RForeground { + position: relative; + left: 0px; + top: 0px; + z-index: 1; +} + +/* ---------------------------------------- */ +/* For section source modules & tags */ + +.RPartExplain { + background: #eee; + font-size: 0.9rem; + margin-top: 0.2rem; + padding: 0.2rem; + text-align: left; +} diff --git a/clones/download.racket-lang.org/releases/8.6/doc/manual-racket.js b/clones/download.racket-lang.org/releases/8.6/doc/manual-racket.js new file mode 100644 index 00000000..1ca41162 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/manual-racket.js @@ -0,0 +1,247 @@ +/* For the Racket manual style */ + +AddOnLoad(function() { + /* Look for header elements that have x-source-module and x-part tag. + For those elements, add a hidden element that explains how to + link to the section, and set the element's onclick() to display + the explanation. */ + var tag_names = ["h1", "h2", "h3", "h4", "h5"]; + for (var j = 0; j < tag_names.length; j++) { + elems = document.getElementsByTagName(tag_names[j]); + for (var i = 0; i < elems.length; i++) { + var elem = elems.item(i); + AddPartTitleOnClick(elem); + } + } +}) + +// cache of source urls +var cache = {}; + +function ParseSource(source, mod_path, single_collection) { + + var source_url = new URL(source); + + if (source_url.protocol == "github:") { + // browser URL parser only works with http(s) URLs + source_url = new URL("https" + source.substring(6)); + var host = source_url.host; + var url_path = source_url.pathname.substring(1).split("/"); + if (!(url_path.length >= 2)) return null; + var user = url_path.shift(); + var repo = url_path.shift(); + var branch = url_path.shift(); + var source_path = url_path.join("/"); + } + else if (("https:" == source_url.protocol) || ("git:" == source_url.protocol)) { + // browser URL parser only works with http(s) URLs + if ("git:" == source_url.protocol) + source_url = new URL("https" + source.substring(3)); + + var host = source_url.host; + var source_path = source_url.searchParams.get("path"); + var branch = (source_url.hash || "#master").substring(1); + var url_path = source_url.pathname.substring(1).split("/"); + if (url_path.length < 2) throw [source_url.pathname, url_path]; + var user = url_path.shift(); + var repo = url_path.shift(); + var mtch = repo.match(/(.*)\.git$/); + if (mtch) repo = mtch[1]; + + } + else return null; + + var mod_path_re = /^\(lib "(.+)"\)$/; + + var mod_path_elems = mod_path && mod_path.match(mod_path_re)[1].split("/"); + + if (!user || !repo || !mod_path_elems) + return null; + if (single_collection) + mod_path_elems.shift(); + + var file_path = mod_path_elems.join("/"); + + + if (source_path) { + file_path = source_path + "/" + file_path; + } + + return { user: user, + repo: repo, + file_path: file_path, + branch: branch, + host: host }; +} + +function AddSourceElement(pkg_url, info) { + info.appendChild(document.createTextNode("Document source ")); + var url_line = document.createElement("div"); + var a = document.createElement("a"); + a.href = pkg_url; + a.style.whiteSpace = "nowrap"; + a.appendChild(document.createTextNode(pkg_url)); + addSpan(url_line, "\xA0", "RktRdr"); + url_line.appendChild(a); + info.appendChild(url_line); +} + +var prefixes = { "github.com": "tree", + "gitlab.com": "-/blob" }; + + +function AddSourceUrl(source, mod_path, collection, info) { + // multi is encoded as an array, empty as false + single_collection = (typeof collection === "string"); + + var parsed = source && mod_path && ParseSource(source, mod_path, single_collection); + + if (!parsed) return; + + prefix = prefixes.hasOwnProperty(parsed.host) && prefixes[parsed.host]; + if (!prefix) return; + + var correct_url = "https://" + [parsed.host, parsed.user, parsed.repo, prefix, parsed.branch, parsed.file_path].join("/"); + + if (info) AddSourceElement(correct_url, info); +} + +function addSpan(dest, str, cn) { + var s = document.createElement("span"); + s.className = cn; + s.style.whiteSpace = "nowrap"; + s.appendChild(document.createTextNode(str)); + dest.appendChild(s); +} + + +// test cases +if (false) { + console.log(ParseSource("git://gitlab.com/benn/foo?path=xxx", + '(lib "asn1/scribblings/asn1.scrbl")', + false)) + console.log(ParseSource("github://github.com/carl-eastlund/mischief/master", + '(lib "asn1/scribblings/asn1.scrbl")', + false)) + console.log(ParseSource("github://github.com/carl-eastlund/mischief/stable/dir", + '(lib "asn1/scribblings/asn1.scrbl")', + false)) + + console.log(ParseSource("git://github.com/racket/racket/?path=pkgs/racket-doc", + '(lib "asn1/scribblings/asn1.scrbl")', + false)); + + console.log(ParseSource("git://github.com/rmculpepper/asn1.git?path=asn1-doc", + '(lib "asn1/scribblings/asn1.scrbl")', + true)); + console.log(ParseSource("git://github.com/rmculpepper/asn1", + '(lib "asn1/scribblings/asn1.scrbl")', + true)); + console.log(ParseSource("git://github.com/rmculpepper/asn1", + '(lib "asn1/scribblings/asn1.scrbl")', + false)); +} + +function AddPartTitleOnClick(elem) { + var mod_path = elem.getAttribute("x-source-module"); + var tag = elem.getAttribute("x-part-tag"); + var source_pkg = elem.getAttribute("x-source-pkg"); + + // create here to share + var info = document.createElement("div"); + + + // tag is not needed, but this way we can add the element in only one place + // avoid failing on browser that don't have `fetch` + if (mod_path && source_pkg && tag && window.fetch) { + + var cached = cache[mod_path] + if (cached) { + AddSourceElement(cached[0], mod_path, cached[1], info); + } + else { + fetch("https://pkgs.racket-lang.org/pkg/" + source_pkg + ".json") + .then(function (response) { return response.json(); }) + .then(function (data) { + var vers = data["versions"] || {}; + var def = vers["default"] || {}; + var source = def["source"] || undefined; + var collection = data["collection"]; + if (source) { + cache[mod_path] = [source, collection]; + AddSourceUrl(source, mod_path, collection, info); + } + }); + } + } + + if (mod_path && tag) { + // Might not be present: + var prefixes = elem.getAttribute("x-part-prefixes"); + + info.className = "RPartExplain"; + + /* The "top" tag refers to a whole document: */ + var is_top = (tag == "\"top\""); + info.appendChild(document.createTextNode("Link to this " + + (is_top ? "document" : "section") + + " with ")); + + /* Break `secref` into two lines if the module path and tag + are long enough: */ + var is_long = (is_top ? false : ((mod_path.length + + tag.length + + (prefixes ? (16 + prefixes.length) : 0)) + > 60)); + + var line1 = document.createElement("div"); + var line1x = ((is_long && prefixes) ? document.createElement("div") : line1); + var line2 = (is_long ? document.createElement("div") : line1); + + /* Construct a `secref` call with suitable syntax coloring: */ + addSpan(line1, "\xA0@", "RktRdr"); + addSpan(line1, (is_top ? "other-doc" : "secref"), "RktSym"); + addSpan(line1, "[", "RktPn"); + if (!is_top) + addSpan(line1, tag, "RktVal"); + if (is_long) { + /* indent additional lines: */ + if (prefixes) + addSpan(line1x, "\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0", "RktPn"); + addSpan(line2, "\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0", "RktPn"); + } + if (prefixes) { + addSpan(line1x, " #:tag-prefixes ", "RktPn"); + addSpan(line1x, "'", "RktVal"); + addSpan(line1x, prefixes, "RktVal"); + } + if (!is_top) + addSpan(line2, " #:doc ", "RktPn"); + addSpan(line2, "'", "RktVal"); + addSpan(line2, mod_path, "RktVal"); + addSpan(line2, "]", "RktPn"); + + info.appendChild(line1); + if (is_long) + info.appendChild(line1x); + if (is_long) + info.appendChild(line2); + + info.style.display = "none"; + + /* Add the new element afterthe header: */ + var n = elem.nextSibling; + if (n) + elem.parentNode.insertBefore(info, n); + else + elem.parentNode.appendChild(info); + + /* Clicking the header shows the explanation element: */ + elem.onclick = function () { + if (info.style.display == "none") + info.style.display = "block"; + else + info.style.display = "none"; + } + } +} diff --git a/clones/download.racket-lang.org/releases/8.6/doc/manual-style.css b/clones/download.racket-lang.org/releases/8.6/doc/manual-style.css new file mode 100644 index 00000000..340290bb --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/manual-style.css @@ -0,0 +1,784 @@ + +/* See the beginning of "scribble.css". + This file is used by the `scribble/manual` language, along with + "manual-racket.css". */ + +@import url("manual-fonts.css"); + +* { + margin: 0; + padding: 0; +} + +@media all {html {font-size: 15px;}} +@media all and (max-width:940px){html {font-size: 14px;}} +@media all and (max-width:850px){html {font-size: 13px;}} +@media all and (max-width:830px){html {font-size: 12px;}} +@media all and (max-width:740px){html {font-size: 11px;}} + +/* CSS seems backward: List all the classes for which we want a + particular font, so that the font can be changed in one place. (It + would be nicer to reference a font definition from all the places + that we want it.) + + As you read the rest of the file, remember to double-check here to + see if any font is set. */ + +/* Monospace: */ +.maincolumn, .refpara, .refelem, .tocset, .stt, .hspace, .refparaleft, .refelemleft { + font-family: 'Fira-Mono', monospace; + white-space: inherit; + font-size: 1rem; +} + +/* embolden the "Racket Guide" and "Racket Reference" links on the TOC */ +/* there isn't an obvious tag in the markup that designates the top TOC page, which is called "start.scrbl" */ +/* nor a tag that designates these two links as special */ +/* so we'll use this slightly tortured sibling selector that hooks onto the h2 tag */ +h2[x-source-module='(lib "scribblings/main/start.scrbl")'] ~ table a[href="guide/index.html"], +h2[x-source-module='(lib "scribblings/main/start.scrbl")'] ~ table a[href="reference/index.html"] { + font-weight: bold; +} + + +h2 .stt { + font-size: 2.3rem; + /* prevent automatic bolding from h2 */ + font-weight: 400; +} + +.toptoclink .stt { + font-size: inherit; +} +.toclink .stt { + font-size: 90%; +} + +.RpackageSpec .stt { + font-weight: 300; + font-family: 'Fira-Mono', monospace; + font-size: 0.9rem; +} + +h3 .stt, h4 .stt, h5 .stt { + color: #333; + font-size: 1.65rem; + font-weight: 400; +} + + +/* Serif: */ +.main, .refcontent, .tocview, .tocsub, .sroman, i { + font-family: 'Charter-Racket', serif; + font-size: 1.18rem; +/* Don't use font-feature-settings with Charter, +it fouls up loading for reasons mysterious */ +/* font-feature-settings: 'tnum' 1, 'liga' 0; */ +} + + +/* Sans-serif: */ +.version, .versionNoNav, .ssansserif { + font-family: 'Fira', sans-serif; +} + +/* used mostly for DrRacket menu commands */ +.ssansserif { + font-family: 'Fira', sans-serif; + font-size: 0.9em; +} + +.tocset .ssansserif { + font-size: 100%; +} + +/* ---------------------------------------- */ + +p, .SIntrapara { + display: block; + margin: 0 0 1em 0; + line-height: 1.4; +} + +.compact { + padding: 0 0 1em 0; +} + +li { + list-style-position: outside; + margin-left: 1.2em; +} + +h1, h2, h3, h4, h5, h6, h7, h8 { + font-family: 'Fira', sans-serif; + font-weight: 300; + font-size: 1.6rem; + color: #333; + margin-top: inherit; + margin-bottom: 1rem; + line-height: 1.25; + +} + +h3, h4, h5, h6, h7, h8 { + border-top: 1px solid black; +} + + + +h2 { /* per-page main title */ + font-family: 'Cooper-Hewitt'; + margin-top: 4rem; + font-size: 2.3rem; + font-weight: bold; + line-height: 1.2; + width: 90%; + /* a little nudge to make text visually lower than 4rem rule in left margin */ + position: relative; + top: 6px; +} + +h3, h4, h5, h6, h7, h8 { + margin-top: 2em; + padding-top: 0.1em; + margin-bottom: 0.75em; +} + +/* ---------------------------------------- */ +/* Main */ + +body { + color: black; + background-color: white; +} + +.maincolumn { + width: auto; + margin-top: 4rem; + margin-left: 17rem; + margin-right: 2rem; + margin-bottom: 10rem; /* to avoid fixed bottom nav bar */ + max-width: 700px; + min-width: 370px; /* below this size, code samples don't fit */ +} + +a { + text-decoration: inherit; +} + +a, .toclink, .toptoclink, .tocviewlink, .tocviewselflink, .tocviewtoggle, .plainlink, +.techinside, .techoutside:hover, .techinside:hover { + color: #07A; +} + +a:hover { + text-decoration: underline; +} + + +/* ---------------------------------------- */ +/* Navigation */ + +.navsettop, .navsetbottom { + left: 0; + width: 15rem; + height: 6rem; + font-family: 'Fira', sans-serif; + font-size: 0.9rem; + border-bottom: 0px solid hsl(216, 15%, 70%); + background-color: inherit; + padding: 0; +} + +.navsettop { + position: fixed; + z-index: 2; + background: #a7b0be; + top: 0; + left: 0; + margin-bottom: 0; + border-bottom: 0; +} + +.navsettop a, .navsetbottom a { + color: black; +} + +.navsettop a:hover, .navsetbottom a:hover { + background: hsl(216, 78%, 95%); + text-decoration: none; +} + +.navleft, .navright { + position: static; + float: none; + margin: 0; + white-space: normal; +} + + +.navleft a { + display: inline-block; +} + +.navright a { + display: inline-block; + text-align: center; +} + +.navleft a, .navright a, .navright span { + display: inline-block; + padding: 0.5rem; + min-width: 1rem; +} + + +.navright { + white-space: nowrap; +} + + +.navsetbottom { + display: none; +} + +.nonavigation { + color: #889; +} + +.searchform { + display: block; + margin: 0; + padding: 0; + border-bottom: 1px solid #eee; + height: 4rem; +} + +.nosearchform { + margin: 0; + padding: 0; + height: 4rem; +} + +.searchbox { + font-size: 0.9rem; + width: 12rem; + margin: 1rem; + padding: 0.25rem 0.4rem ; + vertical-align: middle; + background-color: white; + font-family: 'Fira-Mono', monospace; +} + + +#search_box { + font-family: 'Fira-Mono', monospace; + font-size: 1rem; + padding: 0.25rem 0.3rem ; +} + +/* Default to local view. Global will specialize */ +.plt_global_only { display: none; } +.plt_local_only { display: block; } + +/* ---------------------------------------- */ +/* Version */ + +.versionbox { + position: absolute; + float: none; + top: 0.25rem; + left: 17rem; + z-index: 11000; + height: 2em; + font-size: 70%; + font-weight: lighter; + width: inherit; + margin: 0; +} +.version, .versionNoNav { + font-size: inherit; +} +.version:before, .versionNoNav:before { + content: "v."; +} + + +/* ---------------------------------------- */ +/* Margin notes */ + +/* cancel scribble.css styles: */ +.refpara, .refelem { + position: static; + float: none; + height: auto; + width: auto; + margin: 0; +} + +.refcolumn { + position: static; + display: block; + width: auto; + font-size: inherit; + margin: 2rem; + margin-left: 2rem; + padding: 0.5em; + padding-left: 0.75em; + padding-right: 1em; + background: hsl(60, 29%, 94%); + border: 1px solid #ccb; + border-left: 0.4rem solid #ccb; +} + + +/* slightly different handling for margin-note* on narrow screens */ +@media all and (max-width:1340px) { + span.refcolumn { + float: right; + width: 50%; + margin-left: 1rem; + margin-bottom: 0.8rem; + margin-top: 1.2rem; + } + +} + +.refcontent, .refcontent p { + line-height: 1.5; + margin: 0; +} + +.refcontent p + p { + margin-top: 1em; +} + +.refcontent a { + font-weight: 400; +} + +.refpara, .refparaleft { + top: -1em; +} + + +@media all and (max-width:600px) { + .refcolumn { + margin-left: 0; + margin-right: 0; + } +} + + +@media all and (min-width:1340px) { + .refcolumn { + margin: 0 -22.5rem 1rem 0; + float: right; + clear: right; + width: 18rem; + } +} + +.refcontent { + font-family: 'Fira', sans-serif; + font-size: 1rem; + line-height: 1.6; + margin: 0 0 0 0; +} + + +.refparaleft, .refelemleft { + position: relative; + float: left; + right: 2em; + height: 0em; + width: 13em; + margin: 0em 0em 0em 0em; + display: contents; +} + +.refcolumnleft { + background-color: hsl(60, 29%, 94%); + display: block; + position: relative; + width: 13em; + font-size: 85%; + border: 0.5em solid hsl(60, 29%, 94%); + margin: 0 0 0 0; +} + + +/* ---------------------------------------- */ +/* Table of contents, left margin */ + +.tocset { + position: fixed; + z-index: 2; + overflow-y: scroll; + float: none; + left: 0; + top: 0rem; + bottom: 0; + width: 14rem; + padding: 0rem 0.5rem 0.5rem 0.5rem; + background-color: hsl(216, 15%, 70%); + border-top: 6rem solid hsl(216, 15%, 70%); +} + +.tocset td { + vertical-align: text-top; + padding-bottom: 0.4rem; + padding-left: 0.2rem; + line-height: 1.1; + font-family: 'Fira', sans-serif; +} + +.tocset td a { + color: black; + font-weight: 400; +} + + +.tocview { + text-align: left; + background-color: inherit; + margin-top: 1em; +} + + +.tocview td, .tocsub td { + line-height: 1.3; +} + + +.tocview table, .tocsub table { + width: 90%; +} + +.tocset td a.tocviewselflink { + font-weight: lighter; + font-size: 110%; /* monospaced styles below don't need to enlarge */ + color: white; +} + +.tocviewselflink { + text-decoration: none; +} + +.tocsub { + text-align: left; + margin-top: 0.5em; + background-color: inherit; +} + +.tocviewlist, .tocsublist { + margin-left: 0.2em; + margin-right: 0.2em; + padding-top: 0.2em; + padding-bottom: 0.2em; +} +.tocviewlist table { + font-size: 82%; +} + +.tocviewlisttopspace { + margin-bottom: 1em; +} + +.tocviewsublist, .tocviewsublistonly, .tocviewsublisttop, .tocviewsublistbottom { + margin-left: 0.4em; + border-left: 1px solid #99a; + padding-left: 0.8em; +} +.tocviewsublist { + margin-bottom: 1em; +} +.tocviewsublist table, +.tocviewsublistonly table, +.tocviewsublisttop table, +.tocviewsublistbottom table, +table.tocsublist { + font-size: 1rem; +} + +.tocviewsublist td, +.tocviewsublistbottom td, +.tocviewsublisttop td, +.tocsub td, +.tocviewsublistonly td { + font-size: 90%; +} + +/* shrink the monospaced text (`stt`) within nav */ +.tocviewsublist td .stt, +.tocviewsublistbottom td .stt, +.tocviewsublisttop td .stt, +.tocsub td .stt, +.tocviewsublistonly td .stt { + font-size: 95%; +} + + +.tocviewtoggle { + font-size: 75%; /* looks better, and avoids bounce when toggling sub-sections due to font alignments */ +} + +.tocsublist td { + padding-left: 0.5rem; + padding-top: 0.25rem; + text-indent: 0; +} + +.tocsublinknumber { + font-size: 100%; +} + +.tocsublink { + font-size: 82%; + text-decoration: none; +} + +.tocsubseclink { + font-size: 100%; + text-decoration: none; +} + +.tocsubnonseclink { + font-size: 82%; + text-decoration: none; + margin-left: 1rem; + padding-left: 0; + display: inline-block; +} + +/* the label "on this page" */ +.tocsubtitle { + display: block; + font-size: 62%; + font-family: 'Fira', sans-serif; + font-weight: bolder; + font-style: normal; + letter-spacing: 2px; + text-transform: uppercase; + margin: 0.5em; +} + +.toptoclink { + font-weight: bold; + font-size: 110%; + margin-bottom: 0.5rem; + margin-top: 1.5rem; + display: inline-block; +} + +.toclink { + font-size: inherit; +} + +/* ---------------------------------------- */ +/* Some inline styles */ + +.indexlink { + text-decoration: none; +} + +pre { + margin-left: 2em; +} + +blockquote { + margin-left: 2em; + margin-right: 2em; + margin-bottom: 1em; +} + +.SCodeFlow { + border-left: 1px dotted black; + padding-left: 1em; + padding-right: 1em; + margin-top: 1em; + margin-bottom: 1em; + margin-left: 0em; + margin-right: 2em; + white-space: nowrap; + line-height: 1.5; +} + +.SCodeFlow img { + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +/* put a little air between lines of code sample */ +/* Fira Mono appears taller than Source Code Pro */ +.SCodeFlow td { + padding-bottom: 1px; +} + +.boxed { + margin: 0; + margin-top: 2em; + padding: 0.25em; + padding-top: 0.3em; + padding-bottom: 0.4em; + background: #f3f3f3; + box-sizing:border-box; + border-top: 1px solid #99b; + background: hsl(216, 78%, 95%); + background: -moz-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%); + background: -webkit-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%); + background: -o-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%); + background: -ms-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%); + background: linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%); +} + +blockquote > blockquote.SVInsetFlow { +/* resolves issue in e.g. /reference/notation.html */ + margin-top: 0em; +} + +.leftindent .SVInsetFlow { /* see e.g. section 4.5 of Racket Guide */ + margin-top: 1em; + margin-bottom: 1em; +} + +.SVInsetFlow a, .SCodeFlow a { + color: #07A; +} + +.SubFlow { + display: block; + margin: 0em; +} + +.boxed { + width: 100%; + background-color: inherit; +} + +.techoutside { text-decoration: none; } + +.SAuthorListBox { + position: static; + float: none; + font-family: 'Fira', sans-serif; + font-weight: 300; + font-size: 110%; + margin-top: 1rem; + margin-bottom: 2rem; + width: 30rem; + height: auto; +} + +.author > a { /* email links within author block */ + font-weight: inherit; + color: inherit; +} + +.SAuthorList { + font-size: 82%; +} +.SAuthorList:before { + content: "by "; +} +.author { + display: inline; + white-space: nowrap; +} + +/* phone + tablet styles */ + +@media all and (max-width:720px){ + + + @media all and (max-width:720px){ + + @media all {html {font-size: 15px;}} + @media all and (max-width:700px){html {font-size: 14px;}} + @media all and (max-width:630px){html {font-size: 13px;}} + @media all and (max-width:610px){html {font-size: 12px;}} + @media all and (max-width:550px){html {font-size: 11px;}} + @media all and (max-width:520px){html {font-size: 10px;}} + + .navsettop, .navsetbottom { + display: flex; + position: absolute; + width: 100%; + height: 4rem; + border: 0; + background-color: hsl(216, 15%, 70%); + align-items: center; + } + + .tocsetoverlay .navsettop { + position: fixed; + } + + .navleft { + flex: 1; + } + + .searchform { + display: inline; + border: 0; + } + + .searchbox { + margin-top: 0; + margin-bottom: 0; + } + + .navleft .tocsettoggle { + display: initial; + } + + .navright { + margin-right: 1.3rem; + border: 0px solid red; + } + + .navsetbottom { + display: block; + margin-top: 8rem; + } + + .tocset { + display: none; + border-top-width: 4rem; + } + + .tocsetoverlay .tocset { + display: block; + } + + .versionbox { + top: 4.5rem; + left: 1rem; /* same distance as main-column */ + z-index: 1; + height: 2em; + font-size: 70%; + font-weight: lighter; + } + + + .maincolumn { + margin-left: 1em; + margin-top: 7rem; + margin-bottom: 0rem; + } + + } + +} + +/* print styles : hide the navigation elements */ +@media print { + .tocset, + .navsettop, + .navsetbottom { display: none; } + .maincolumn { + width: auto; + margin-right: 13em; + margin-left: 0; + } +} diff --git a/clones/download.racket-lang.org/releases/8.6/doc/racket.css b/clones/download.racket-lang.org/releases/8.6/doc/racket.css new file mode 100644 index 00000000..85dec2f6 --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/racket.css @@ -0,0 +1,251 @@ + +/* See the beginning of "scribble.css". */ + +/* Monospace: */ +.RktIn, .RktRdr, .RktPn, .RktMeta, +.RktMod, .RktKw, .RktVar, .RktSym, +.RktRes, .RktOut, .RktCmt, .RktVal, +.RktBlk { + font-family: monospace; + white-space: inherit; +} + +/* Serif: */ +.inheritedlbl { + font-family: serif; +} + +/* Sans-serif: */ +.RBackgroundLabelInner { + font-family: sans-serif; +} + +/* ---------------------------------------- */ +/* Inherited methods, left margin */ + +.inherited { + width: 100%; + margin-top: 0.5em; + text-align: left; + background-color: #ECF5F5; +} + +.inherited td { + font-size: 82%; + padding-left: 1em; + text-indent: -0.8em; + padding-right: 0.2em; +} + +.inheritedlbl { + font-style: italic; +} + +/* ---------------------------------------- */ +/* Racket text styles */ + +.RktIn { + color: #cc6633; + background-color: #eeeeee; + white-space: pre; +} + +.RktInBG { + background-color: #eeeeee; +} + +.RktRdr { +} + +.RktPn { + color: #843c24; +} + +.RktMeta { + color: black; +} + +.RktMod { + color: black; +} + +.RktOpt { + color: black; + font-style: italic; +} + +.RktKw { + color: black; +} + +.RktErr { + color: red; + font-style: italic; +} + +.RktVar { + color: #262680; + font-style: italic; +} + +.RktSym { + color: #262680; +} + +.RktSymDef { /* used with RktSym at def site */ +} + +.RktValLink { + text-decoration: none; + color: blue; +} + +.RktValDef { /* used with RktValLink at def site */ +} + +.RktModLink { + text-decoration: none; + color: blue; +} + +.RktStxLink { + text-decoration: none; + color: black; +} + +.RktStxDef { /* used with RktStxLink at def site */ +} + +.RktRes { + color: #0000af; +} + +.RktOut { + color: #960096; +} + +.RktCmt { + color: #c2741f; +} + +.RktVal { + color: #228b22; +} + +/* ---------------------------------------- */ +/* Some inline styles */ + +.together { + width: 100%; +} + +.prototype, .argcontract, .RBoxed { + white-space: nowrap; +} + +.prototype td { + vertical-align: text-top; +} + +.RktBlk { + white-space: inherit; + text-align: left; +} + +.RktBlk tr { + white-space: inherit; +} + +.RktBlk td { + vertical-align: baseline; + white-space: inherit; +} + +.argcontract td { + vertical-align: text-top; +} + +.highlighted { + background-color: #ddddff; +} + +.defmodule { + width: 100%; + background-color: #F5F5DC; +} + +.specgrammar { + float: right; +} + +.RBibliography td { + vertical-align: text-top; +} + +.leftindent { + margin-left: 1em; + margin-right: 0em; +} + +.insetpara { + margin-left: 1em; + margin-right: 1em; +} + +.Rfilebox { +} + +.Rfiletitle { + text-align: right; + margin: 0em 0em 0em 0em; +} + +.Rfilename { + border-top: 1px solid #6C8585; + border-right: 1px solid #6C8585; + padding-left: 0.5em; + padding-right: 0.5em; + background-color: #ECF5F5; +} + +.Rfilecontent { + margin: 0em 0em 0em 0em; +} + +.RpackageSpec { + padding-right: 0.5em; +} + +/* ---------------------------------------- */ +/* For background labels */ + +.RBackgroundLabel { + float: right; + width: 0px; + height: 0px; +} + +.RBackgroundLabelInner { + position: relative; + width: 25em; + left: -25.5em; + top: 0px; + text-align: right; + color: white; + z-index: 0; + font-weight: bold; +} + +.RForeground { + position: relative; + left: 0px; + top: 0px; + z-index: 1; +} + +/* ---------------------------------------- */ +/* History */ + +.SHistory { + font-size: 82%; +} diff --git a/clones/download.racket-lang.org/releases/8.6/doc/scribble-common.js b/clones/download.racket-lang.org/releases/8.6/doc/scribble-common.js new file mode 100644 index 00000000..ceab368a --- /dev/null +++ b/clones/download.racket-lang.org/releases/8.6/doc/scribble-common.js @@ -0,0 +1,196 @@ +// Common functionality for PLT documentation pages + +// Page Parameters ------------------------------------------------------------ + +var page_query_string = location.search.substring(1); + +var page_args = + ((function(){ + if (!page_query_string) return []; + var args = page_query_string.split(/[&;]/); + for (var i=0; i= 0) args[i] = [a.substring(0,p), a.substring(p+1)]; + else args[i] = [a, false]; + } + return args; + })()); + +function GetPageArg(key, def) { + for (var i=0; i= 0 && cur.substring(0,eql) == key) + return unescape(cur.substring(eql+1)); + } + return def; + } +} + +function SetCookie(key, val) { + try { + localStorage[key] = val; + } catch(e) { + var d = new Date(); + d.setTime(d.getTime()+(365*24*60*60*1000)); + try { + document.cookie = + key + "=" + escape(val) + "; expires="+ d.toGMTString() + "; path=/"; + } catch (e) {} + } +} + +// note that this always stores a directory name, ending with a "/" +function SetPLTRoot(ver, relative) { + var root = location.protocol + "//" + location.host + + NormalizePath(location.pathname.replace(/[^\/]*$/, relative)); + SetCookie("PLT_Root."+ver, root); +} + +// adding index.html works because of the above +function GotoPLTRoot(ver, relative) { + var u = GetCookie("PLT_Root."+ver, null); + if (u == null) return true; // no cookie: use plain up link + // the relative path is optional, default goes to the toplevel start page + if (!relative) relative = "index.html"; + location = u + relative; + return false; +} + +// Utilities ------------------------------------------------------------------ + +var normalize_rxs = [/\/\/+/g, /\/\.(\/|$)/, /\/[^\/]*\/\.\.(\/|$)/]; +function NormalizePath(path) { + var tmp, i; + for (i = 0; i < normalize_rxs.length; i++) + while ((tmp = path.replace(normalize_rxs[i], "/")) != path) path = tmp; + return path; +} + +// `noscript' is problematic in some browsers (always renders as a +// block), use this hack instead (does not always work!) +// document.write(""); + +// Interactions --------------------------------------------------------------- + +function DoSearchKey(event, field, ver, top_path) { + var val = field.value; + if (event && event.key === 'Enter') { + var u = GetCookie("PLT_Root."+ver, null); + if (u == null) u = top_path; // default: go to the top path + u += "search/index.html?q=" + encodeURIComponent(val); + u = MergePageArgsIntoUrl(u); + location = u; + return false; + } + return true; +} + +function TocviewToggle(glyph, id) { + var s = document.getElementById(id).style; + var expand = s.display == "none"; + s.display = expand ? "block" : "none"; + glyph.innerHTML = expand ? "▼" : "►"; +} + +function TocsetToggle() { + document.body.classList.toggle("tocsetoverlay"); +} + +// Page Init ------------------------------------------------------------------ + +// Note: could make a function that inspects and uses window.onload to chain to +// a previous one, but this file needs to be required first anyway, since it +// contains utilities for all other files. +var on_load_funcs = []; +function AddOnLoad(fun) { on_load_funcs.push(fun); } +window.onload = function() { + for (var i=0; i + .techinside doesn't work with IE, so use both (and IE doesn't + work with inherit in the second one, so use blue directly) */ +.techinside { color: black; } +.techinside:hover { color: blue; } +.techoutside:hover>.techinside { color: inherit; } + +.SCentered { + text-align: center; +} + +.imageleft { + float: left; + margin-right: 0.3em; +} + +.Smaller { + font-size: 82%; +} + +.Larger { + font-size: 122%; +} + +/* A hack, inserted to break some Scheme ids: */ +.mywbr { + display: inline-block; + height: 0; + width: 0; + font-size: 1px; +} + +.compact li p { + margin: 0em; + padding: 0em; +} + +.noborder img { + border: 0; +} + +.SVerbatim { + white-space: nowrap; +} + +.SAuthorListBox { + position: relative; + float: right; + left: 2em; + top: -2.5em; + height: 0em; + width: 13em; + margin: 0em -13em 0em 0em; +} +.SAuthorList { + font-size: 82%; +} +.SAuthorList:before { + content: "by "; +} +.author { + display: inline; + white-space: nowrap; +} + +/* print styles : hide the navigation elements */ +@media print { + .tocset, + .navsettop, + .navsetbottom { display: none; } + .maincolumn { + width: auto; + margin-right: 13em; + margin-left: 0; + } +} diff --git a/clones/download.racket-lang.org/robots.txt b/clones/download.racket-lang.org/robots.txt new file mode 100644 index 00000000..eb053628 --- /dev/null +++ b/clones/download.racket-lang.org/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/clones/llthw.common-lisp.dev/1-0-0-overview.html b/clones/llthw.common-lisp.dev/1-0-0-overview.html new file mode 100644 index 00000000..ecdeb471 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-0-0-overview.html @@ -0,0 +1,1863 @@ + + + + + + + Grokking Lisp ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+ +
+ + + + + + + + +
+
+ +
+
+ +
+ +

PART ONE

+

Grokking Lisp

+
+

"'Grok' means to understand so thoroughly that the observer becomes a part of the process being observed—to merge, to blend, to intermarry, to lose personal identity in group experience. It means almost everything that we mean by religion, philosophy, and science—and it means as little to us as color means to a blind man."

+
Robert A. Heinlein, Stranger in a Strange Land
+ +
+

Lisp isn't a language you just learn. It changes you, as a programmer and a person.

+

In Part One, we focus on the core of the Common Lisp language, features that you will use every day, and techniques that will change the way you see programming.

+

We'll start with a high-level overview of the whole language, working through the details of syntax, semantics, style, and configuration of your development environment.

+

From there we'll move on to strings, characters, writing, and printing; prompting for user input; lists, trees, and special lists like alists and plists; math, vectors and arrays; lexical scope and variables; and functions.

+

Then we'll build our first application, a straight-forward text-adventure, using everything you've learned up to that point; extend this knowlege to a simple web application and command-line utilities, explore more advanced features of the language, and writing domain-specific languages for even more control over syntax.

+

Chapters

+
    +
  1. Common Lisp Bootcamp
  2. +
  3. Printing, Strings and Streams
  4. +
  5. Getting Input From Users
  6. +
  7. Lists and List-Operations
  8. +
  9. Look-up Lists and Trees
  10. +
  11. Numbers and Math
  12. +
  13. Arrays and Vectors
  14. +
  15. Variables, Parameters, and Constants
  16. +
  17. Closures
  18. +
  19. Functions and Macros
  20. +
  21. A Simple Text Adventure
  22. +
  23. Namespaces, Symbols, Packages, and Systems
  24. +
  25. A Simple Web Application
  26. +
  27. Conditionals
  28. +
  29. Command-Line Utilities
  30. +
  31. Mapping and Looping
  32. +
  33. Revisiting Loops with Iterate
  34. +
  35. Format Strings
  36. +
  37. Domain Specific Languages
  38. +
  39. Part One in Review
  40. +
+ + +
+ +
+
+
+ +

results matching ""

+
    + +
    +
    + +

    No results matching ""

    + +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-00-lisp-bootcamp.html b/clones/llthw.common-lisp.dev/1-01-00-lisp-bootcamp.html new file mode 100644 index 00000000..a540ae65 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-00-lisp-bootcamp.html @@ -0,0 +1,1847 @@ + + + + + + + Common Lisp Bootcamp ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + +
    + +
    + +
    + + + + + + + + +
    +
    + +
    +
    + +
    + +

    Chapter 1

    +

    Common Lisp Bootcamp

    +
    +

    "I made a very important discovery at Camp Currie. Happiness consists in getting enough sleep. Just that, nothing more. All the wealthy, unhappy people you've ever met take sleeping pills; Mobile Infantrymen don't need them."

    +
    Robert A. Heinlein, Starship Troopers
    + +
    +

    It's time to dive head-first into Lisp, no mercy. You'll need discipline to apply the five steps of learning the hard way, and this is where you'll get a feel for it. But one thing you need to remember, which many programmers often forget before working themselves to burn-out, the most important thing you need to learn is to get a good night's sleep, every night, on time, so you can wake up fully refreshed to tackle Lisp again the next day. Make yourself a schedule, a strict one, and follow it like you have a Sergeant throwing you out of your cot every morning, screaming at you all day to push yourself harder. Eat right, take regular breaks from the computer, work hard, and sleep, and you'll find the learning process far more successful and rewarding.

    +

    There is a reason, after all, the military uses this methodology for training---it's an application of the metaphor of alchemy, realized in nuclear physics: given enough heat and pressure, you can in fact turn lead into gold. But now, on to Lisp. Here is everything you need to know to get hacking in Lisp right this second.

    + + + +
    + +
    +
    +
    + +

    results matching ""

    +
      + +
      +
      + +

      No results matching ""

      + +
      +
      +
      + +
      +
      + +
      + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-01-syntax-overview.html b/clones/llthw.common-lisp.dev/1-01-01-syntax-overview.html new file mode 100644 index 00000000..8a82828b --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-01-syntax-overview.html @@ -0,0 +1,1891 @@ + + + + + + + Syntax Overview in 5 Minutes ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + +
      + +
      + +
      + + + + + + + + +
      +
      + +
      +
      + +
      + +

      Exercise 1.1.1

      +

      Syntax Overview in 5 Minutes

      +

      What makes the Lisp family of languages so simple, expressive, and concise, is the syntax. First of all, everything in Lisp is an object---and all objects are represented by S-Expressions.

      +

      While other programming languages generally have unique syntactic forms for statements, which change a value in memory and return nothing, and for expressions which return a value, Lisp uses the S-Expression to represent all objects---all code and data, a property known as 'homoiconicity'. As a result, all objects in Lisp have a return value when evaluated.

      +

      S-Expressions come from the Lambda Calculus, where they are formally defined to be either an Atom or a List. In Lisp, lists of one or more elements are implemented as Cons-Cells, and atoms are thus any object which is not a cons. Cons-Cells will be discussed more in Exercise 1.1.2.

      +

      Below are some examples of atoms---try them out at the REPL yourself! And remember, type exactly what I've typed (even if you think it's wrong), pressing Enter at the end of each line. This tells the Lisp REPL to evaluate the expression you've entered.

      +
      94
      +
      +'a-quoted-symbol
      +
      +#\greek_small_letter_lamda
      +
      +"This is a string"
      +
      +nil
      +
      +'()
      +
      +()
      +
      +t
      +
      +

      As you can see, an Atom can be a lot of things in Lisp---numbers, symbols, character literals, strings, and even the empty list. As you may have noticed, nil, '(), and () all return the same thing: NIL. That is because nil is defined as the empty list, which itself is treated atomically as it doesn't require any consing. But there's other trickery going on behind the scenes here too---strings, for example, while treated as Atoms, are actually sequences of character literals; lists are also a sub-type of sequences.

      +

      To really understand what's going on here, you have to remember that there's an object hierarchy---every object in Lisp descends from t---and again, everything is an object. The symbol nil is a special case, because it's the only member of the system class null. Only nil and its alternate representation, the empty list, represents logical falsity. Every other object is truthy. You don't have to return t to say that a function returns true, because any value other than nil is logically truthy, but it is useful when you need to return true and don't have any specific value to return.

      +

      A few of the examples above have a single quote prepended to them; this is just called quoting, and tells Lisp not to evaluate the quoted form. You can think of this as switching an expression from code to data. The prepended single quote is just a short form for a full quote expression. Let's look at some more specific examples of quoting expressions:

      +
      '()
      +
      +'(this is a list of symbols)
      +
      +(quote (this is another list of symbols))
      +
      +'another-quoted-symbol
      +
      +

      Lists in Lisp are enclosed in a pair of parentheses. If you've ever looked at Lisp source code before, and wondered, "What's up with all these parentheses?", you now have your answer. Each nested object inside a list is a full S-Expression too, so in a given block of code, you can easily get a lot of parentheses at the end closing off all the nested objects represented as lists.

      +

      By default, as in "not-quoted", lists are automatically treated as code by Lisp when evaluated. We call these lists forms. Let's try it out:

      +
      (+ 10 20 (* 30 2))
      +
      +(princ "Hello, from Lisp!")
      +
      +(loop for item in '(this list will get printed in titlecase) do (format t "~@(~A~) " item))
      +
      +

      Don't worry too much about what you're typing at the moment---just make sure you type it exactly as I've typed it, and that it evaluates correctly. What you should see is this:

      +
      * (+ 10 20 (* 30 2))
      +
      +90
      +* (princ "Hello, from Lisp!")
      +Hello, from Lisp!
      +"Hello, from Lisp!"
      +* (loop for item in '(this list will get printed in titlecase) do (format t "~@(~A~) " item))
      +This List Will Get Printed In Titlecase
      +NIL
      +*
      +
      +

      Take a look at what you've typed and ponder it for a moment. You should notice a few things right away:

      +
        +
      • A form starts off with a function, macro, or special operator, typically represented by a symbol.
      • +
      • The rest of the form is made up of parameters passed to that function, macro, or special operator.
      • +
      • You can have other forms as parameters, and the innermost seem to get evaluated first; their results are then used as parameters to the form the next level up the hierarchy.
      • +
      +

      This syntax is called "Polish prefix-notation"---the operator comes first. In the first example, (+ 10 20 (* 30 2)), it's pretty clear what's happening: you pass an arbitrary set of numbers to the addition function, and you get back the sum. In this case, you also passed the return result of (* 30 2), which is 30 multiplied by 2. So instead of having to write something like 10 + 20 + 30 * 2 as you would in the algebraic notation of other programming languages, you just have to type the addition symbol once, and order of operation is clear. For a simple example like this, it may not seem like a big deal yet, but for real-world applications, it greatly simplifies your code.

      +

      Typically the expression in the operator position of a form is a symbol that represents a named function; but it can also be an anonymous function, a macro, or special form. Special forms have their own rules, and there's no means provided to define new special forms. Macros, among other things, allow you to create custom syntax, allowing you to arbitrarily extend and change the Lisp language. Typically, however, you will write functions, classes, and methods in your day-to-day code, which simply extend the semantics of the language.

      +

      There are also reader macros, which let you define convenient forms for expressing, among other things, new data types. You've seen some reader macros already---like the short form of quote, represented by the single quotation mark prepending an expression to prevent it from being evaluated.

      +

      From this amazingly simple syntax, you can express any program you can imagine, using any programming paradigm you choose.

      + + +
      + +
      +
      +
      + +

      results matching ""

      +
        + +
        +
        + +

        No results matching ""

        + +
        +
        +
        + +
        +
        + +
        + + + + + + + + + + + + + + +
        + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-02-repl.html b/clones/llthw.common-lisp.dev/1-01-02-repl.html new file mode 100644 index 00000000..29eab79c --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-02-repl.html @@ -0,0 +1,1854 @@ + + + + + + + The REPL ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        + + + + + + + + +
        + +
        + +
        + + + + + + + + +
        +
        + +
        +
        + +
        + +

        Exercise 1.1.2

        +

        The REPL

        +

        The Lisp REPL---a READ-EVAL-PRINT Loop---is the core of the interactive approach to Lisp development. You type in an expression, the expression is read, evaluated, the return result is printed, and then it waits for more input. The REPL is marked by a prompt, like the command line for your operating system, and it is the main interface to your current running Lisp image. Depending on the implementation of Lisp you are using, you may see different prompts. You can also customize your prompt, but the means of doing so are implementation-dependent.

        +

        Typically, imagining that the underscore character below is your blinking cursor, you'll see something to the effect of:

        +
        CL-USER> _
        +
        +

        But in SBCL, the default prompt is much less informative:

        +
        * _
        +
        +

        For convenience sake, when you should enter a piece of code in the REPL for immediate evaluation, each line of code will be marked by the SBCL prompt character. When you should enter all the code given in a file, there will be no prompt character preceding each line, and you will be provided with a file name to enter it in.

        +

        Remember, you don't type in the prompt character * at the REPL; even if your prompt looks different, the * represents all Common Lisp REPL prompts. For example, you'll often see code examples like this:

        +
        * (+ 1 1)
        +
        +2
        +* (apply #'+ 1 2 3 4 '(5 6))
        +
        +21
        +
        +

        The example above means, you first enter the expression (+ 1 1) in the REPL; evaluating it returns the result 2, exactly what you would expect to get back for 1 + 1. Then, you get back to the prompt, and can enter the expression, (apply #'+ 1 2 3 4 '(5 6)), which returns 21. If you're using SBCL from the command-line, this shows a direct transcript of the session---extra line-break between the evaluated expression and return result and all. If you are using Emacs+SLIME, you won't see that extra line-break.

        +

        A lot of Lisp literature and reference works explicitly mark the return value with an ASCII-formatted fat arrow: =>. This can make spotting the return value of a form much easier in examples. We will adopt this convention herein as well, when it is necessary for visual clarity. In such a case, the examples above would then look like this:

        +
        * (+ 1 1)
        +=> 2
        +* (apply #'+ 1 2 3 4 '(5 6))
        +=> 21
        +
        +

        In most exercises, we will separate the code examples into two copies: first, just the code you are meant to type, and then again with the correct return results for you to compare your work.

        + + +
        + +
        +
        +
        + +

        results matching ""

        +
          + +
          +
          + +

          No results matching ""

          + +
          +
          +
          + +
          +
          + +
          + + + + + + + + + + + + + + +
          + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-03-expressions.html b/clones/llthw.common-lisp.dev/1-01-03-expressions.html new file mode 100644 index 00000000..2fef81b0 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-03-expressions.html @@ -0,0 +1,1901 @@ + + + + + + + Expressions, Parentheses, and Return Values ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          + + + + + + + + +
          + +
          + +
          + + + + + + + + +
          +
          + +
          +
          + +
          + +

          Exercise 1.1.3

          +

          Expressions, Parentheses, and Return Values

          +

          In the pedantic spirit of programming, it is worth reminding you that everything you type at the REPL or in your Lisp source code files will be read as or expanded into an S-Expression and evaluated if possible. Quoting is one way you can disable evaluation for a nested S-Expression, but some S-Expressions are never evaluated. If your Lisp implementation can't read what you've entered as a valid S-Expression, you will normally be dropped into the debugger, the same way that it would if it tried and failed to evaluate.

          +
          * (+ 1 1)
          +=> 2 ;; as expected, because it's a valid S-Expression
          +* {+ 1 1}
          +;; this won't evaluate, because the Lisp reader doesn't recognize braces
          +
          +

          Common Lisp only has S-Expressions; imperative programming languages, for example, differentiate between 'statements' and 'expressions', by ruling that statements cause changes to the environment and return nothing, while expressions are used for their return values. In the tradition of the Lisp-family of programming languages, the syntax is minimalist by design---so in Lisp, even a destructive, in-place operation is represented as an S-Expression. Destructive, in-place operations are by convention named with a prepended "N", to make it obvious that they have side-effects:

          +
          ;; first lets define a couple variables
          +* (defvar *test-list-a* (list 1 2 3))
          +* (defvar *test-list-b* (list 'd 'e 'f))
          +;; append returns a new list from its arguments
          +* (append *test-list-a* *test-list-b*)
          +=> (1 2 3 D E F)
          +;; you can see that the original lists haven't changed
          +* *test-list-a*
          +=> (1 2 3)
          +* *test-list-b*
          +=> (D E F)
          +;; but now lets do a destructive operation, NCONC (ie, in-place list concatenation)
          +* (nconc *test-list-a* *test-list-b*)
          +=> (1 2 3 D E F)
          +;; the variable's binding and assignment haven't changed, but the last cons-cell
          +;; now points to *test-list-b* instead of terminating at NIL
          +* *test-list-a*
          +=> (1 2 3 D E F)
          +
          +

          Expressions, in an abstract sense, are expected to return a value; S-Expressions in Common Lisp almost always do, as well, but there are some exceptions. A function call, for example, is expected to return the value of the last form in its body as the value of the entire function:

          +
          ;; this is a typical anonymous function call; the last form in its body is (+ x x)
          +;; so the function call returns (+ 2 2) => 4
          +* ((lambda (x) (+ x x)) 2)
          +=> 4
          +;; in this function, the return result of (+ x x) is not assigned so it is essentially
          +;; lost; the function body moves on to the next form, (* x x), which is the last form
          +;; of this function body. So the function call only returns (* 10 10) => 100
          +* ((lambda (x) (+ x x) (* x x)) 10)
          +=> 100
          +;; in this function, we capture the return values of both (+ x x) and (* x x), as the
          +;; lexical variables SUM and PRODUCT; using VALUES, we can return multiple values from
          +;; a form instead of just one
          +* ((lambda (x) (let ((sum (+ x x)) (product (* x x))) (values sum product))) 10)
          +=> 20 100
          +;; but calling VALUES without anything gives us... an expression with no return result!
          +* (values)
          +=> ; No value
          +
          +

          As was introduced in the previous exercise, an S-Expression can either be an Atom or a Cons-Cell. Cons-Cells are represented by Lists to the Reader and by the Printer---but the empty list is treated as an Atom because it requires no consing.

          +

          A subset of Atoms are called self-evaluating objects. Since expressions are expected to return a value, these particular objects simply return themselves. By quoting an expression, you are effectively turning the quoted expression into a self-evaluating object.

          +
          ;; these are some self-evaluating objects:
          +;; strings---
          +* "a string"
          +;; characters---
          +* #\greek_small_letter_lamda
          +;; numbers
          +* 42
          +* #x2A
          +;; bit-vectors---
          +* #*1001
          +
          +

          Note: #x2A looks like it returns something different, but it doesn't---the underlying integer of both the decimal representation 42 and the hexadecimal representation #x2A are the same number. This can be proved with (eq 42 #x2A).

          +

          Lists are ordered collections of S-Expressions surrounded in a pair of parentheses, with the items separated by whitespace---the amount of whitespace does not matter to the Lisp reader, but there are fairly strict style conventions on how to format your code which will be detailed in the next exercise. Again, non-empty lists are read as cons-cells, and cons-cells are printed as lists. But lists are also a proper data type in Lisp, so it's important to remember the distinction between representation and the actual implementation.

          +
          ;; this:
          +'(a b c)
          +;; is the same as this:
          +'(a
          +  b
          +  c)
          +;; and this:
          +(list 'a 'b 'c)
          +
          +

          When a list is evaluated, it is treated as code unless it is quoted. The positions of items in the list are both syntactically and semantically meaningful when the list is evaluated as code. These positions will be discussed below, in the section "Prefix Notation."

          +

          Lisp code is meant to be simple and elegant; if you find yourself staring into an impenetrable confusion of parenthesis-chaos, your code is too complex for you to manage. Using techniques for decomposition and refactoring also presented in this book, you will learn how to write beautiful and elegant programs as well as the Common Lisp language itself.

          + + +
          + +
          +
          +
          + +

          results matching ""

          +
            + +
            +
            + +

            No results matching ""

            + +
            +
            +
            + +
            +
            + +
            + + + + + + + + + + + + + + +
            + + +
            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-04-lists-cons-cells.html b/clones/llthw.common-lisp.dev/1-01-04-lists-cons-cells.html new file mode 100644 index 00000000..6f074ccb --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-04-lists-cons-cells.html @@ -0,0 +1,1877 @@ + + + + + + + Lists, Cons-Cells, and Memory ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            +
            + + + + + + + + +
            + +
            + +
            + + + + + + + + +
            +
            + +
            +
            + +
            + +

            Exercise 1.1.4

            +

            Lists, Cons-Cells, and Memory

            +

            It is significant to separate the representation and implementation of S-Expressions in your mind as you learn Lisp---since McCarthy's first paper on LISP, S-Expressions have been defined by their representation, but in Common Lisp, S-Expressions are defined by their implementation and their representation is only treated as an interface to the underlying objects.

            +

            Lists are a proper type, descending from Sequences in Lisp's type hierarchy. A list only conses as long as there are values to be consed. For example, consider the following:

            +
            * (list)
            +=> NIL
            +* (list 'a)
            +=> (A)
            +* (list 'a nil)
            +=> (A NIL)
            +* (cons 'a nil)
            +=> (A)
            +
            +

            To understand what's happening in the example above, you have to understand consing, and how lists are built on top of Cons-Cells.

            +
            ;; this:
            +(list 'a 'b 'c)
            +;; is the same as this:
            +(cons 'a (cons 'b (cons 'c nil)))
            +;; while this:
            +(list 'a 'nil)
            +;; is the same as this:
            +(cons 'a (cons nil nil))
            +
            +

            The end of a chain of cons-cells normally terminates in nil, but you can have the cdr of a cons-cell point to a value too, and eliminate the need for an extra consing by using dot-notation:

            +
            ;; this:
            +'(a . b)
            +;; is the same as this:
            +(cons 'a 'b)
            +
            +

            A list of dot-notation pairs like this is called an association list, or alist for short. They are one of many structures available in Lisp for storing key/value pairs, and have a good API.

            +
            '((a . b)
            +  (c . d)
            +  (e . f))
            +
            +

            So then, just what is this "Cons-Cell" I keep talking about, you ask?

            +

            A Cons-Cell is a pair of pointers, the car and the cdr---acronyms for "Contents of Address Register" and "Contents of Decrement Register", respectively. The car is usually a pointer to a value, while the cdr can be a pointer to the car of another cons-cell, a pointer to NIL, or in the case of a dotted-pair, another pointer to a value.

            +

            Consider again the examples above. Now you can more clearly see how lists are built on top of Cons-Cell chains, and what is happening when you work with Cons-Cells directly:

            +
            ;; this creates three cons-cells, the quoted symbols 'A, 'B, and 'C each in the CAR of their own Cons-Cell
            +(list 'a 'b 'c)
            +;; it would be the same as typing this:
            +(cons 'a (cons 'b (cons 'c nil)))
            +;; or this:
            +'(a . (b . (c . nil)))
            +;; or this:
            +'(a b c . nil)
            +;; or simply this:
            +'(a b c)
            +
            +

            A common focal-point of Lisp source code optimization centers on minimizing the number of conses performed by your application. Note how a dotted-pair only conses once, while a two item list that contains the same information conses twice; so by using an alist instead of other list-based data structures such as plists, you are already eliminating half the memory and processing requirements.

            + + +
            + +
            +
            +
            + +

            results matching ""

            +
              + +
              +
              + +

              No results matching ""

              + +
              +
              +
              + +
              +
              + +
              + + + + + + + + + + + + + + +
              + + +
              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-05-symbols.html b/clones/llthw.common-lisp.dev/1-01-05-symbols.html new file mode 100644 index 00000000..193634b7 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-05-symbols.html @@ -0,0 +1,1896 @@ + + + + + + + Symbols and Namespaces ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              +
              + + + + + + + + +
              + +
              + +
              + + + + + + + + +
              +
              + +
              +
              + +
              + +

              Exercise 1.1.5

              +

              Symbols and Namespaces

              +

              Common Lisp is often referred to as a LISP2---that is, it has separate namespaces for Functions and Variables in any given environment. In principle, this means that you can bind and assign both a function and a variable to the symbol foo, evaluate (foo foo), and Lisp can distinguish between them automatically by their position in a form. You can also explicitly refer to the function definition in an argument position with the reader macro #', such as in (apply #'foo foo). In practice, however, this is considered bad form. Consider the example:

              +
              (defvar foo 1)
              +
              +(defun foo (foo)
              +  (+ foo foo))
              +
              +(foo foo)
              +=> 2
              +
              +

              There are actually three separate bindings of the symbol foo in the above example. First, there is the global variable foo bound and assigned with defvar to the value of 1. There is the function definition of foo, and it has a parameter named foo as well. In the body of foo the function, it is its parameter being added to itself; so when the function foo is applied to the global variable foo, you get (+ 1 1) => 2.

              +

              This is because in addition to having separate namespaces for Functions and Variables, Common Lisp is also both dynamically and lexically scoped. Dynamic scoping is special and explicit in Common Lisp; lexical scoping is more intuitive and implicit---in other words, you have to specifically declare a symbol to be special to use its dynamic binding from within a lexical scope where the symbol could be lexically bound and assigned as a different variable, while many forms introduce an implicit lexical scope. For this reason there is a naming convention for top-level, dynamic variables, called "earmuffs":

              +
              ;; top-level, dynamic variables can be declared with DEFVAR or DEFPARAMETER
              +(defvar *my-dynamic-var* "I'm special!")
              +=> *MY-DYNAMIC-VAR*
              +;; notice that the variable names are qualified with a pair of asterisks? These are called earmuffs.
              +(defparameter *my-extra-special-dynamic-var* "I'm special, too!")
              +=> *MY-EXTRA-SPECIAL-DYNAMIC-VAR*
              +;; one obvious way to introduce a lexical scope is with a LET form for binding and assigning lexical variables:
              +(let ((one 1)
              +      (two 2)
              +      (three 3))
              +  (+ one two three))
              +=> 6
              +;; now let's put them both together
              +(defvar *one* 1)
              +=> *ONE*
              +(let ((one 1.0))
              +  (+ one *one*))
              +=> 2.0
              +
              +

              The "earmuffs" distinguish special variables from lexical. Even though this is "just a convention", it's one you should be certain to follow. The combination of separate namespaces for functions and variables, with both dynamic and lexical scoping of symbols, is extremely powerful---but it can easily get out of hand. Distinguishing your special dynamic variables with the earmuffs will make a big difference.

              +

              Another excellent feature for taming the raw power of Common Lisp is its package system, which allow you to specify custom read-tables for your environment. When you define a package, you have to explicitly import symbols you want available in the package namespace---even the symbols of the Common Lisp language itself; you can import all of a package's exported symbols into your new package at once with the :use keyword expression in the body of your package definition.

              +

              To fully explore the package system, go ahead and create a file called ex1-1-5.lisp, and enter the following code:

              +
              (in-package :cl-user)
              +
              +(defpackage #:my-new-package
              +  (:nicknames #:newpack)
              +  (:use :cl :cl-user)
              +  (:export #:mad-adder))
              +
              +(in-package :my-new-package)
              +
              +(defvar *my-private-var* "I'm not exported from the package")
              +
              +(defun mad-adder (n &rest rest)
              +  "An addition function for MY-NEW-PACKAGE."
              +  (apply #'+ n rest))
              +
              +

              You could then continue defining your functions, variables, classes, methods, and other code in your new package, and specifically list the symbols you want to export as the package's public interface in the package definition's :export keyword expression. Notice that in this package definition, we've also given the package a nickname, newpack, and told it to use all the exported symbols from the COMMON-LISP and COMMON-LISP-USER packages in the MY-NEW-PACKAGE local read-table.

              +

              Now back at the command line, navigate to the folder where you saved this file and, on Linux and OS X, run:

              +
              $ rlwrap sbcl --load "ex1-1-5.lisp"
              +
              +

              While on Windows, run:

              +
              $ sbcl --load "ex1-1-5.lisp"
              +
              +

              This will load and compile your source code file into the Lisp image, and as normal you will be dropped at the Lisp prompt in the COMMON-LISP-USER package. If you ever need to check what package you're in, you can evaluate *package*.

              +

              You can refer to any bound symbol in the current Lisp image by using its full name---normally, when you type in a symbol name, you don't have to type the package namespace it's in as well. Lisp assumes that a symbol you enter exists in the current package, unless you specifically tell it otherwise. You can access any symbol in a package, even if it's not exported, but generally speaking you should obey the implicit agreement you make with the developers of a library to use their package's exported interface instead of meddling with the internals.

              +

              Given that you have now defined the mad-adder function in my-new-package and loaded the file, but you're working in the cl-user package when the REPL starts, you might think you can just call mad-adder directly---you'd get an error in this case, however, because the full name of mad-adder is actually my-new-package:mad-adder not common-lisp-user:mad-adder. You can use the package nickname instead, which is a convenient way to save typing and still be explicit:

              +
              ;; this:
              +(newpack:mad-adder 1)
              +;; is the same as:
              +(my-new-package:mad-adder 1)
              +;; if a symbol isn't exported, however, you have to use two colons between the package and symbol
              +newpack::*my-private-var*
              +
              +

              There are some symbol names you can't use, however---at least not without trickery. As a general rule, you cannot use any of the 978 external symbols in the COMMON-LISP package for either a function or a variable, even if that binding does not exist in the Common Lisp standard. All the names of symbols exported by the COMMON-LISP package are reserved.

              + + +
              + +
              +
              +
              + +

              results matching ""

              +
                + +
                +
                + +

                No results matching ""

                + +
                +
                +
                + +
                +
                + +
                + + + + + + + + + + + + + + +
                + + +
                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-06-prefix-notation.html b/clones/llthw.common-lisp.dev/1-01-06-prefix-notation.html new file mode 100644 index 00000000..967ed2d2 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-06-prefix-notation.html @@ -0,0 +1,1841 @@ + + + + + + + Prefix Notation ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                +
                + + + + + + + + +
                + +
                + +
                + + + + + + + + +
                +
                + +
                +
                + +
                + +

                Exercise 1.1.6

                +

                Prefix Notation

                +

                An evaluated list expression has syntactically and semantically meaningful positions. Remember, lists are implemented as Cons-Cells. So the car of an evaluated list has to be a valid operator; the cdr of the evaluated list is itself a list of arguments to the operator called parameters. In other words, the operator always comes first, and is not infixed between arguments, as would be the case in algebraic notation. This is called "Polish Prefix Notation".

                +
                ;; Polish Prefix notation, the operator comes first:
                +(operator . (list of parameters))
                +
                +

                For example, say you want to add together a list of numbers. Normally, you would think to write this: 1 + 2 + 3 + 4 + 5 = 15, infixing the operators between the arguments; but in Lisp you would write:

                +
                * (+ 1 2 3 4 5)
                +=> 15
                +
                +

                In Lisp, you don't have to write the addition operator, +, over and over between each number you wish to add together. You are passing parameters to a function, and the function knows to collect the parameters as a set and Sum them. That's the big conceptual difference between Lisp and other languages---when the operator comes first, you are telling the computer what you want instead of what to do and how to do it. So in the example above, you are telling Lisp you want the Sum of the set of integers from 1 to 5 inclusive, not telling it to add 1 to 2, then add the result to 3, then add the result to 4, and then add that result to 5, to get the integer 15. Do you see the difference?

                +

                Valid operators can be a symbol representing a function, macro, or special operator; or a lambda expression representing an anonymous function. If it is a symbol, the Lisp evaluator will first check if the symbol is a special operator, and if it's not, it will look for a matching definition in the read-table for a function. Macros are tricky---they can be expanded into normal Lisp code at various times; reader macros are expanded at read-time, while defmacro forms are expanded at compile time. There are also various techniques for controlling when and where macros are to be expanded.

                +

                The handling of arguments is particular to the type of operator. While functions, for example, can only receive a single return value from any parameter expressions, special operators have their own rules. Macros allow you to arbitrarily change the syntax and semantics of Lisp---so, obviously, the rules are defined by the macro definition form itself. Exactly how one should apply the raw power of macros is a subject of much debate in the Lisp community.

                + + +
                + +
                +
                +
                + +

                results matching ""

                +
                  + +
                  +
                  + +

                  No results matching ""

                  + +
                  +
                  +
                  + +
                  +
                  + +
                  + + + + + + + + + + + + + + +
                  + + +
                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-07-style-guide.html b/clones/llthw.common-lisp.dev/1-01-07-style-guide.html new file mode 100644 index 00000000..86bc9d0f --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-07-style-guide.html @@ -0,0 +1,2005 @@ + + + + + + + Common Lisp Style Guide ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                  +
                  + + + + + + + + +
                  + +
                  + +
                  + + + + + + + + +
                  +
                  + +
                  +
                  + +
                  + +

                  Exercise 1.1.7

                  +

                  Common Lisp Style Guide

                  +

                  Style is fundamental to programming—particularly in Lisp, where the unlimited power and flexibility of paradigm can easily go to your head. A little carelessness can make for sloppy, illegible code; but if you make a point to consider your code as an art-form as well as a tool to get a job done, you, and anyone else who has to read your code later, will thank you for it.

                  +

                  But don't make the mistake of thinking these rules are prescriptive; and not everyone in the Lisp community agrees with them. Consider them more like practical suggestions which will get you thinking about style, and then you and your team can decide together which style rules you want to follow for your coding aesthetic.

                  +

                  At this stage of learning Lisp, you may not fully appreciate all the style rules given here, or understand everything being discussed. And that's okay. Take a deep breath, and familiarize yourself with these points to the best of your ability, and then treat this chapter like a reference; it will mean more and more after each chapter of this book you work through, and will be something you can keep referring to with each Lisp project.

                  +

                  Symbols and Naming

                  +

                  Clear and meaningful symbol-names in your Lisp programs are one of the most important aspects of code readability.

                  +

                  While there are no hard-fast rules for naming symbols in the Common Lisp standard, beyond a list of which characters are allowed, certain conventions have arisen in the Lisp community which you should know, and usually follow religiously. There are times when you can, and may have to, break convention, but those are special cases which require experience and finesse.

                  +

                  Symbol names should be descriptive, short, typed in all lowercase, with words separated by a single hyphen:

                  +
                  (defun my-addition-function (&rest rest)
                  +  (apply #'+ rest))
                  +=> MY-ADDITION-FUNCTION
                  +
                  +(deftype my-integer-type ()
                  +  '(and integer
                  +        (satisfies plusp)))
                  +=> MY-INTEGER-TYPE
                  +
                  +(defvar my-hash-table (make-hash-table :test 'equal))
                  +=> MY-HASH-TABLE
                  +
                  +(defvar my-alist '(("one" . 1)
                  +                   ("two" . 2)
                  +                   ("three" . 3)))
                  +=> MY-ALIST
                  +
                  +;; Note that symbol names created from strings should be in all-caps:
                  +(intern "MY-NEW-INTERNED-SYMBOL")
                  +=> MY-NEW-INTERNED-SYMBOL
                  +   NIL
                  +;; or you'll have to reference it in surrounding hbars as a literal, case-sensitive symbol:
                  +(intern "my-funky-interned-symbol")
                  +=> |my-funky-interned-symbol|
                  +   NIL
                  +
                  +

                  Note that a pair of hbars is syntactic, not stylistic. It allows you, among other things, to define case-sensitive symbols; but it is generally only used for foreign-function interfaces.

                  +

                  Global variables, i.e., variables declared as top-level forms with defvar or defparameter, are named using "earmuffs" because they are dynamic and special, such as the following built into Common Lisp:

                  +
                  *package*
                  +=> #<PACKAGE "COMMON-LISP-USER">
                  +*print-base*
                  +=> 10
                  +
                  +

                  In the case of earmuffs, these are stylistic. They are not parsed as syntactic tokens by the Lisp reader, they are simply read as part of the symbol name.

                  +

                  Another stylistic convention for symbol names uses a pair of plus-signs to wrap symbol-names of constants:

                  +
                  (defconstant +my-new-constant+ 1.0)
                  +
                  +

                  Package internal symbols are sometimes named with a prepended percent-sign, and not exported with the package API. These are similar in purpose to private functions, methods, and variables in other programming languages---only they can always be accessed by using the full symbol name:

                  +
                  (defpackage #:my-new-package
                  +  (:use :cl)
                  +  (:export #:mad-adder))
                  +
                  +(in-package :my-new-package)
                  +
                  +;; Do some wonky stuff with a package-internal function
                  +(defun %madder (x)
                  +  (declare (integer x))
                  +  (apply #'+ (loop for i from 1 upto x
                  +                   collect (* x i))))
                  +
                  +;; Write an exported interface to your package internal function
                  +(defun mad-adder (x)
                  +  "Call %MADDER with integer argument X."
                  +  (%madder x))
                  +
                  +(in-package :cl-user)
                  +
                  +(my-new-package:mad-adder 10)
                  +
                  +(my-new-package::%madder 10)
                  +
                  +

                  Predicate functions, i.e., boolean tests, typically end with a suffixed "p". If it is a multi-word symbol already separated by dashes, you append the suffix as "-p" (dash-p); while if it is a single word or mnemonic symbol name, the "p" can be appended without a dash.

                  +
                  (bit-vector-p #*01010001)
                  +=> T
                  +(integerp 10)
                  +=> T
                  +
                  +

                  Parentheses, Indentation, and Whitespace

                  +

                  Parentheses should all close on the same line, when ending multiple forms; while balancing parentheses on separate lines from your code, to demarcate a code block, is common practice in other languages, it is not the case in Common Lisp. If you are having trouble matching the parentheses in your head, use a source-code editor which highlights matching opening or closing parens. And since in Lisp, all non-atomic forms are lists, and wrapped in a pair of parentheses, it is also worthwhile to use tools to find unmatched parens.

                  +
                  ;; bad style
                  +(defun a-badly-formatted-function (x y z)
                  +  (progn
                  +    (setq x (+ x x))
                  +    (setq y (* y y))
                  +    (mod
                  +      (+ z z)
                  +      (+ x y)
                  +      )
                  +    )
                  +  )
                  +
                  +;; the right way
                  +(defun a-pretty-function (x y z)
                  +  "Function definitions need docstrings."
                  +  (declare (integer x y z))
                  +  (let ((x2 (+ x x))
                  +        (y2 (* y y)))
                  +    (mod (* z z) (+ x2 y2))))
                  +
                  +

                  If you have trouble getting Lisp style right, you can always run your code through the Pretty Printer to see how Lisp thinks it should be formatted.

                  +

                  If you use Emacs+SLIME (and many Lisp Hackers will tell you that you must), proper indentation is handled quite well; other editors, such as Sublime Text, need a plugin installed to indent Lisp code, but don't always do it right---so it's important to know how to manually indent your code.

                  +

                  Indentation in Lisp uses the space character, not Tabs. Bodies of expressions are indented by two spaces from their parent form, while paramaters and list members can be lined up into columns when they take up too many characters to fit on an ideal line of code. For example:

                  +
                  ;; IF is a special operator, and doesn't have a body expression
                  +(if t t nil)
                  +
                  +;; but you'll normally need to split the form for clarity; see how the three parameters line up?
                  +(if t
                  +    (format t "Then: True~%")
                  +    (format t "Else: False~%"))
                  +
                  +;; WHEN does have a body expression though, so its body isn't lined up with the test-form parameter
                  +(when t
                  +  (format t "This is true, too!"))
                  +
                  +

                  You only need a single space character or line-break between forms in a list. Likewise, you only need one extra line between top-level forms. Extraneous whitespace makes your code more difficult for others to read.

                  +

                  You should also avoid the temptation to use the Tab character inside a form or list to force a table-like structure onto your code. This isn't FORTRAN, it's Lisp---and Lisp should flow.

                  +
                  ;; a badly formatted class definition
                  +(defclass march-hare ()
                  +  ((name        :type string  :initarg :name        :initform "Haigha"  :accessor name)
                  +   (tea-time-p  :type boolean :initarg :tea-time-p  :initform t         :accessor tea-time-p)
                  +   (tie         :type string  :initarg :tie         :initform "bow-tie" :accessor tie)))
                  +
                  +;; the right way
                  +(defclass march-hare ()
                  +  ((name :type string :initarg :name :initform "Haigha" :accessor name
                  +         :documentation "The name of the March Hare.")
                  +   (tea-time-p :type boolean :initarg :tea-time-p :initform t :accessor tea-time-p
                  +               :documentation "Whether or not it's tea-time.")
                  +   (tie :type string :initarg :tie :initform "bow-tie" :accessor tie
                  +        :documentation "The style of tie the March Hare is wearing."))
                  +  (:documentation "'The March Hare will be much the most interesting, and perhaps as this is May it won't be raving mad---at least not so mad as it was in March.' -- Lewis Carroll"))
                  +
                  +

                  Comments and Documentation

                  +

                  You should always comment and document your code; that being said, Lisp, when written correctly, can be effectively self-documenting and self-explanatory (see "Decomposition, Refactoring, and Abstraction" below for more information). Your code should be clean and readable enough that comments and documentation are technically unnecessary, but then write clean, short, and to-the-point comments and documentation strings to expand on what the code itself already says.

                  +

                  Conventions for comments in Lisp are pretty loose, but if you read enough Lisp source-code, you'll find the following general pattern:

                  +
                  ;;;; four preceding semi-colons for file headers, copyright and license information
                  +
                  +;;; three preceding semi-colons for descriptive text
                  +
                  +;; two preceding semi-colons for commentary on the immediately following text
                  +
                  +; one preceding semi-colon for in-line comments, inside code blocks
                  +
                  +

                  You should always include meaningful docstrings in your object definition forms---even in your global variables. In class definition forms, you can add docstrings to each slot of the class, the class itself, and each of the generic functions and methods. Lack of documentation, or documentation that has fallen out of sync with the codebase, is considered a bug just as much as code that does not work as expected.

                  +

                  Decomposition, Refactoring, and Abstraction

                  +

                  Your Lisp code should be so clear and focused that, whenever possible, even a non-programmer can read and understand it. This is more difficult than you might expect, as it requires careful thought and planning to achieve successfully.

                  +

                  The general idea is to divide your code up into the smallest reusable pieces; if, for example, you were to write a new summation function, and it contained logic for sorting a list of numbers, instead of writing the logic for sorting a list in-line, inside the summation function, you could write a separate list-sorting function, and call it inside the summation function. This offers three immediate benefits: you get a new, generally useful function almost for free; the logic of your summation function is more tightly focused on the task it was designed for; and the code becomes easier to read and maintain. You can then improve the implementation of either function without worrying about the other.

                  +

                  Oftentimes, as you work on software, you'll find repetitive code-patterns that become cumbersome to write, and may all need to be changed separately during maintenance, refactoring, or major upgrades. Common Lisp, through the most-favoured Emacs+SLIME development environment, is highly interactive, so it supports incremental, functional development. Whenever you come across redundant patterns, it is in your interest to abstract away those code patterns into a macro, which at compile-time will be transformed into the code you need at run-time. This technique also allows you to do some pretty awesome stuff, like intelligently creating interfaces derived from a dynamic data-set; but you should get into the habit of this style of programming, because it will make your code cleaner and easier to manage over time.

                  +

                  Functions, Macros, and Methods

                  +

                  Sometimes it can be difficult to decide when, in your software, to use a function, macro, or method and CLOS class for a specific problem. Again, since Lisp offers so many options for choice of paradigm, you can program in any number of styles, and even mix-and-match paradigms in the same source-code file without trouble; but this rampant mix-and-matching can create unnecessary frustration for maintenance, debugging, and upgrading; so it's useful to pick a dominant paradigm and stick to it.

                  +

                  That being said, if you want to take full advantage of Common Lisp's multi-paradigm toolset, you can do so sanely. It is simply a matter of deciding up-front how you're going to organize your code and express your logic.

                  +

                  A multi-paradigm approach to programming that I have found useful is straightforward, logically consistent, and in keeping with the design goals of the Common Lisp language:

                  +
                    +
                  • Separate application tasks into computation, transformation, and statefulness.
                  • +
                  • Decompose all application logic into pure, clearly-defined functions.
                  • +
                  • Use macros for monadic-style I/O in pure functional programs; object-oriented programs are designed with I/O in mind.
                  • +
                  • When writing functions, program functionally. Avoid writing functions that cause side-effects or are destructive, in-place operations; but if you have to, name them appropriately so that it is obvious.
                  • +
                  • Use macros when abstracting. The point of macros is compile-time code-transformation. Your macros will be more generally useful when you decompose logic from them into pure functions, and use them for their intended purpose.
                  • +
                  • When you need to track state, and thus cause side-effects, you should use CLOS classes and methods—they were designed with that purpose in mind.
                  • +
                  +

                  Cross-Platform Development

                  +

                  Lisp is, by nature, a cross-platform development language; but each implementation of Common Lisp contains implementation-dependent extensions, and platform-specific functionality that is unavoidable. Generally speaking, you should make every effort to write cross-platform, cross-implementation software, so that it "just works" everywhere. When a problem requires implementation or platform specific code to solve, take the extra five minutes to find out how to make it work on other platforms. If you need to, refer to the source code of other popular cross-platform libraries, to see how they approach the problem.

                  +

                  As an example, you can and should write software that takes advantage of 64-bit architectures; but even today, you cannot always count on it being there for your users. Your software should scale gracefully to 32-bit architectures. And when certain features require it, document them as such and provide an alternative.

                  +

                  The same is true for web applications. You can't predict which browser your users will prefer; and users resent getting a page that tells them to upgrade or change their browser. You have no choice but to support every browser and platform—so, think about Lisp software the same way, and you will be doing yourself and your users a favor from the beginning.

                  +

                  Be certain to test your code on every platform you have access to, and in multiple implementations of Lisp for each platform. It may seem like a lot of extra work for nothing at first, but it will save you a lot of time down the road.

                  +

                  Libraries

                  +

                  As well as learning the Common Lisp language, it is important to familiarize yourself and keep up to date with the wide variety of Lisp libraries available on-line, particularly those in the Quicklisp package repository. There are two important reasons for this:

                  +
                    +
                  • Instead of reinventing the wheel, you can use a feature-complete, dedicated library to implement your functionality.
                  • +
                  • When you know what libraries are freely available, you can dedicate more of your time to writing and testing new code.
                  • +
                  +

                  Also, whenever it is both possible and reasonable, the code you write should be packaged into logical units, and distributed as open-source libraries that are loadable through Quicklisp. Depending on the type of company you work for, however, this may be more difficult than you might expect; most software development shops like to control all IP produced by their employees, even code produced in their off-hours—if you have a contract, be sure to check with your manager first before you release any software you write into the wild; and in the future, keep an eye out for such clauses and be certain to fight for your right to contribute to open-source software.

                  +

                  Knowing what code to push up from a software project into a general purpose library can be tricky, but there are a few rules you can keep in mind:

                  +
                    +
                  • If you find yourself copy and pasting code between projects.
                  • +
                  • If you abstract a common problem into a cleaner syntax.
                  • +
                  • If your code solves a known problem or lack in the Lisp community, that is too general for a specific commercial software project.
                  • +
                  + + +
                  + +
                  +
                  +
                  + +

                  results matching ""

                  +
                    + +
                    +
                    + +

                    No results matching ""

                    + +
                    +
                    +
                    + +
                    +
                    + +
                    + + + + + + + + + + + + + + +
                    + + +
                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-01-08-configuration.html b/clones/llthw.common-lisp.dev/1-01-08-configuration.html new file mode 100644 index 00000000..b97bcfe7 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-01-08-configuration.html @@ -0,0 +1,1904 @@ + + + + + + + Configuring Your Development Environment ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                    +
                    + + + + + + + + +
                    + +
                    + +
                    + + + + + + + + +
                    +
                    + +
                    +
                    + +
                    + +

                    Exercise 1.1.8

                    +

                    Configuring Your Development Environment

                    +

                    Now that you've gotten yourself a feel for Common Lisp, you'll want to spend a little time configuring your development environment so that you can dive right into the code. A lot of configuration choices are a matter of personal taste, but as long as you feel comfortable, and nothing interferes with your ability to learn and hack in Lisp, you can't really go wrong.

                    +

                    The In-Browser REPL

                    +

                    (Deprecated)

                    +

                    You can start hacking in Lisp right away with the in-browser, javascript-powered REPL under the "Try Lisp" section of this site, listed in the navigation bar at the top of each page. It takes you through a quick tour of Common Lisp so you can get your feet wet without installing anything.

                    +

                    To continue with this book, however, you will need to install Common Lisp on your computer. Not all the exercises in this book will run in the in-browser REPL, so make sure you get SBCL installed and working correctly before moving on to the next exercise.

                    +

                    Installing SBCL

                    +

                    Steel Bank Common Lisp is one of the easiest Lisp implementations to get up and running—it has out of the box support for a wide selection of platforms, and is considered to be the most robust implementation available. Since it automatically compiles everything you enter at the REPL, your running Lisp processes also benefit from a major speed-boost over other Lisps.

                    +
                    +

                    + Note: the SBCL REPL is minimal by design, since it is primarily used from within Emacs+SLIME which provides its own custom prompt, history, completion, multi-line editing capabilities, and more. In order to use it effectively straight from the command-line, you will need to install a separate tool on OS X and Linux called `rlwrap`, a readline wrapper. It provides evaluation history, multi-line editing, and can be configured for completions and filters. You can read more about `rlwrap` here: utopia.knoware.nl/~hlub/uck/rlwrap/. +

                    +
                    + +

                    Windows

                    +

                    The latest SBCL installer packages for Windows, in separate versions for 32 and 64-bit systems, are available on the official downloads page.

                    +

                    Once installed, you can run SBCL from the Start menu, or call it from a command-line window. If you have PowerShell installed, it offers better features than the default command line.

                    +

                    OS X

                    +

                    On Mac OS X, you will want to install SBCL through the Homebrew package manager.

                    +

                    You will also want to install the rlwrap package, and run SBCL from the terminal as follows:

                    +
                    $ rlwrap sbcl
                    +
                    +

                    Linux

                    +

                    Most Linux distros have the latest, or a very recent, version of SBCL in their official repositories. You can simply install it from there.

                    +

                    You will also want to install the rlwrap package, and run SBCL from the shell as follows:

                    +
                    $ rlwrap sbcl
                    +
                    +

                    Debian/Ubuntu

                    +

                    The packages for SBCL in Apt tend to be severely out-of-date, so if you're using Debian or Ubuntu, you will have a little extra work to do.

                    +

                    First, install the version of SBCL available for your distro in Apt.

                    +

                    Using the old version of SBCL, you may now compile the latest version of SBCL from source.

                    +

                    Installing Quicklisp

                    +

                    Once you have SBCL up and running, the first thing you should do is install Quicklisp. It's a package manager for Lisp, and will allow you to dynamically load community-supported libraries (which typically include ASDF systems and their associated Lisp packages) into your running Lisp image. It also automatically resolves dependencies for your own Lisp projects.

                    +

                    From the command-line:

                    +
                    $ curl -O http://beta.quicklisp.org/quicklisp.lisp
                    +$ rlwrap sbcl --load quicklisp.lisp
                    +
                    +

                    You will then find yourself at the Lisp REPL, with some instructions:

                    +
                      ==== quicklisp quickstart loaded ====
                    +
                    +    To continue, evaluate: (quicklisp-quickstart:install)
                    +
                    +

                    Like the instructions tell you, type that at the REPL prompt:

                    +
                    * (quicklisp-quickstart:install)
                    +
                    +

                    Once it finishes downloading its dependencies and setting up the working folders, it will prompt you with another message confirming it was installed. Now you will want to set it up to load automatically every time you start SBCL:

                    +
                    * (ql:add-to-init-file)
                    +
                    +

                    This function will tell you exactly what it's doing before it changes your lisp .*rc file. If you're ready, press Enter to continue when it prompts you to do so.

                    +

                    That's it! You can now use ql:system-apropos to search for libraries, and ql:quickload to download and install them.

                    +

                    You can put your Lisp projects under ~/quicklisp/local-projects/ so that Quicklisp can find them automatically; then you will be able to quickload your own projects just like the libraries distributed with Quicklisp.

                    +

                    Choosing a Text Editor

                    +

                    If you ask any Lisp developer what editor you should be using, or what IDE is available for Common Lisp, the first thing they'll tell you is, Emacs. Emacs and SLIME (the Superior Lisp Interaction Mode for Emacs), makes a powerful combination. You can control the entire environment with your keyboard, never having to waste time reaching for the mouse; run, test, and debug code in the REPL as you write it in another buffer; experiment and explore alternate approaches to solving the same problem, profiling your code to get the best performance; and have the full Common Lisp HyperSpec at your fingertips. The only problem is, some users really dislike Emacs, or simply don't know it. The steep learning curve can be a real damper to your progress when coming to both Lisp and Emacs as a newbie; so the policy of this book is, use what you know, and make it work until you know Lisp well enough to get comfortable learning Emacs. If you wait until the right time, learning Emacs will be a boost to your productivity, not a hindrance.

                    +
                    + Note: +

                    If you want to move ahead with Emacs, detailed instructions for setting up the Emacs Live environment with support for Common Lisp are available in the next chapter, your first Extra Credit exercise.

                    +
                    + +

                    If you know Emacs and have a great disdain for it, far preferring Vim, you can take advantage of most of the features of SLIME through the Vim package, Slimv.

                    +

                    For users who have no experience with Emacs or Vim, all you really need at the moment is a simple text editor. Anything more will probably just confuse you, and keep you from focusing on Lisp itself. A few worth checking out are:

                    +
                      +
                    • Sublime Text: very well supported, extensible, and actively maintained; syntax highlighting for Lisp is built-in; a REPL plugin is available so you can get a similar experience to Emacs without as steep a learning curve. Free to try, but requires a paid license for continued use. It is available to download for Windows, OS X, and Linux.
                    • +
                    • Atom: currently in beta, built entirely on Web technologies, GitHub's Atom Editor is like a stripped-down Sublime Text with a few unique features. A plugin for Lisp syntax highlighting is available for download within the editor settings. Binaries are available to download for OS X and Windows 7 and 8; the source code is available to compile for other systems, although in Linux it may be available in your package manager.
                    • +
                    • Cloud9: the Cloud9 service is like Sublime Text or Atom in the browser. You can access your code from anywhere, sync it up with your repo, collaborate on code, and more. Syntax highlighting for Lisp is built-in. Cloud9 has both free and premium plans. Best viewed in Chrome, Safari, and Firefox.
                    • +
                    • Notepad++: A clean and simple text editor with syntax highlighting for Lisp. Available for Windows.
                    • +
                    +

                    Other popular text and code editors, such as BBedit, TextWrangler, and Gedit, do not have syntax highlighting for Lisp.

                    +

                    Working From the Command-Line

                    +

                    (writing notes)

                    +
                      +
                    • Importance of being comfortable with the Command-Line
                    • +
                    • Running and Compiling Lisp from the Command-Line
                    • +
                    • Lisp shell scripts
                    • +
                    • Launching the REPL
                    • +
                    + + +
                    + +
                    +
                    +
                    + +

                    results matching ""

                    +
                      + +
                      +
                      + +

                      No results matching ""

                      + +
                      +
                      +
                      + +
                      +
                      + +
                      + + + + + + + + + + + + + + +
                      + + +
                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-00-input-output.html b/clones/llthw.common-lisp.dev/1-02-00-input-output.html new file mode 100644 index 00000000..5197244b --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-00-input-output.html @@ -0,0 +1,1860 @@ + + + + + + + Printing, Streams, and Strings ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                      +
                      + + + + + + + + +
                      + +
                      + +
                      + + + + + + + + +
                      +
                      + +
                      +
                      + +
                      + +

                      Chapter 1.2

                      +

                      Printing, Strings, and Streams

                      +
                      +

                      "There is no such thing as luck; there is only adequate or inadequate preparation to cope with a statistical universe."

                      +
                      Robert A. Heinlein, Have Space Suit---Will Travel
                      + +
                      +

                      Now that you've got an idea of what Lisp is all about and you have your development environment configured to your liking, we can get moving on some real, practical code.

                      +

                      At the end of the day, no matter what the program you're working on does, at some point you will have to give something back to the user. The more interactive the program, the more data will be going back and forth between the user and your program. And users love interactivity---they like to know just how long a set of tasks will take, they want to see updates to data in real-time, they want feedback.

                      +

                      Since development in Lisp is so inherently interactive, it makes sense to think about your programs this way too. So we will be starting our exploration of Common Lisp with the core language features that underlie input and output: printing, strings, and streams.

                      +

                      Exercises:

                      + + + +
                      + +
                      +
                      +
                      + +

                      results matching ""

                      +
                        + +
                        +
                        + +

                        No results matching ""

                        + +
                        +
                        +
                        + +
                        +
                        + +
                        + + + + + + + + + + + + + + +
                        + + +
                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-01-strings.html b/clones/llthw.common-lisp.dev/1-02-01-strings.html new file mode 100644 index 00000000..d10ab840 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-01-strings.html @@ -0,0 +1,1846 @@ + + + + + + + Strings ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                        +
                        + + + + + + + + +
                        + +
                        + +
                        + + + + + + + + +
                        +
                        + +
                        +
                        + +
                        + +

                        Exercise 1.2.1

                        +

                        Strings

                        +

                        Strings are pretty important in programming; no matter what your program does, eventually you're going to need a string to send some information to the user of your program.

                        +

                        Some programming languages have a lot of different types of strings, but Lisp only has four: the standard string type, as well as simple-string, base-string, and simple-base-string types. The usage of these other string types is fairly specialized, so normally you will be using the string type itself.

                        +

                        Creating Strings

                        +

                        The simplest way to create an object of type string in Lisp is to simply type it at the REPL or in a *.lisp file, using the double-quote syntax.

                        +

                        Try this at the REPL:

                        +
                        * "this is a string"
                        +
                        +* "this is another string"
                        +
                        +

                        What You Should See

                        +

                        When you type a string at the REPL and hit Return to evaluate it, Lisp treats the entire string as a single atom, even though underneath it is really a specialized vector of character objects. If you remember, an atom is anything that is not a Cons. String objects are also self-evaluating objects. Thus:

                        +
                        * "this is a string"
                        +=> "this is a string"
                        +* "this is another string"
                        +=> "this is another string"
                        +
                        + + +
                        + +
                        +
                        +
                        + +

                        results matching ""

                        +
                          + +
                          +
                          + +

                          No results matching ""

                          + +
                          +
                          +
                          + +
                          +
                          + +
                          + + + + + + + + + + + + + + +
                          + + +
                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-02-more-strings.html b/clones/llthw.common-lisp.dev/1-02-02-more-strings.html new file mode 100644 index 00000000..adcc8df1 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-02-more-strings.html @@ -0,0 +1,1845 @@ + + + + + + + More Strings ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                          +
                          + + + + + + + + +
                          + +
                          + +
                          + + + + + + + + +
                          +
                          + +
                          +
                          + +
                          + +

                          Exercise 1.2.2

                          +

                          More Strings

                          +

                          In Lisp, strings can contain any character without special markup, except for two particular characters which must be escaped; normally, what you type inside the double-quotes is exactly what you get. Line-breaks and all.

                          +

                          Sometimes though, you want to include double-quote characters inside your string. Lisp has a way of doing that, using the escape-character, \, the Backslash.

                          +

                          As it turns out, the backslash will escape any character. So if you want to print a literal backslash, it too has to be escaped.

                          +
                          * "this string contains \"double-quotes\"."
                          +* "and this string has an escaped backslash: \\."
                          +
                          +

                          What You Should See

                          +
                          * "this string contains \"double-quotes\"."
                          +
                          +"this string contains \"double-quotes\"."
                          +* "and this string has an escaped backslash: \\."
                          +
                          +"and this string has an escaped backslash: \\."
                          +
                          +

                          Once again, you get back exactly what you typed.

                          + + +
                          + +
                          +
                          +
                          + +

                          results matching ""

                          +
                            + +
                            +
                            + +

                            No results matching ""

                            + +
                            +
                            +
                            + +
                            +
                            + +
                            + + + + + + + + + + + + + + +
                            + + +
                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-03-unicode.html b/clones/llthw.common-lisp.dev/1-02-03-unicode.html new file mode 100644 index 00000000..985c80ca --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-03-unicode.html @@ -0,0 +1,1843 @@ + + + + + + + Unicode and Strings ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                            +
                            + + + + + + + + +
                            + +
                            + +
                            + + + + + + + + +
                            +
                            + +
                            +
                            + +
                            + +

                            Exercise 1.2.3

                            +

                            Unicode and Strings

                            +

                            Generally speaking, string objects in Common Lisp are Unicode by default, encoded as UTF-8. This is not a guarantee, however; it's typically just a default on most implementations of Lisp on platforms that support it.

                            +

                            You can do a quick check to see if your implementation of Lisp supports Unicode or not.

                            +
                            * char-code-limit
                            +
                            +

                            If that constant variable returns 1114112, then you're in luck! You have full Unicode support. If it's less than that, you may be more limited in what you can do with strings.

                            +

                            In SBCL, you can test specifically for Unicode support using Lisp's read-time conditionals (but this feature test is not portable):

                            +
                            * #+sb-unicode (format nil "~C" #\cuneiform_sign_an_plus_naga_opposing_an_plus_naga)
                            +
                            +

                            This code will only return a string of the cuneiform sign if you are using SBCL and you have Unicode support enabled; if you also want to see the cuneiform sign, and not a numbered Unicode box character, you have to install cuneiform fonts as well.

                            +

                            On Arch Linux, the ttf-akkadian package is available in AUR. For other platforms, you can find up-to-date links for Sumerian, Akkadian, Old Babylonian, and Neo-Assyrian fonts from the Wikipedia article for the Cuneiform (Unicode block).

                            + + + +
                            + +
                            +
                            +
                            + +

                            results matching ""

                            +
                              + +
                              +
                              + +

                              No results matching ""

                              + +
                              +
                              +
                              + +
                              +
                              + +
                              + + + + + + + + + + + + + + +
                              + + +
                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-04-chars.html b/clones/llthw.common-lisp.dev/1-02-04-chars.html new file mode 100644 index 00000000..4abd5b7a --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-04-chars.html @@ -0,0 +1,1858 @@ + + + + + + + Characters ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                              +
                              + + + + + + + + +
                              + +
                              + +
                              + + + + + + + + +
                              +
                              + +
                              +
                              + +
                              + +

                              Exercise 1.2.4

                              +

                              Characters

                              +

                              Strings are specialized vectors of element-type character, which is a fancy way to say that the type of strings in Lisp descends from sequences, and can only contain character objects in a flat, one-dimensional array. In Lisp, these character elements are atomic, self-evaluating objects in their own right, and have a distinct syntax that is not always the same as the glyph that may be used to represent them in a string.

                              +

                              Characters are referred to as "unitary tokens" in the Standard, and there are actually two kinds of character objects in Common Lisp---graphic characters and non-graphic characters. Only the graphic character objects are associated with a glyph---all other characters are required by the ANSI Standard to have a name. Now the space character has two representations that are equal, one named, and one that uses the space character---so even though it could be lumped with the other non-graphic characters, it is specifically defined as a graphic character object because it does have a glyph associated with it: the empty glyph.

                              +

                              At the REPL, you can use the Sharpsign-Backquote syntax to refer to a literal character object. Most of the characters that you can type with your keymap set to US-English can be entered using the sharpsign-backslash followed by the character itself. Some characters also have names so that they are easier to type:

                              +
                              #\a
                              +#\A
                              +#\Space
                              +#\Newline
                              +#\Tab
                              +
                              +

                              In the code above, you can see both kinds of characters objects being used, graphic and non-graphic. Notice that some character names are case-sensitive. Typing #\a gives you the lower-case letter a character object, while typing #\A gives you the upper-case letter A character object, just as you would expect---but this behaviour does differ from other symbols, and even from other implementation-specific unicode character representations which we'll see in the next exercise.

                              +

                              As it turns out, you can easily get a list of characters from a string. Try this out:

                              +
                              (coerce "hello, multiverse!" 'list)
                              +
                              +

                              What You Should See

                              +
                              * #\a
                              +#\a
                              +* #\A
                              +#\A
                              +* #\Space
                              +#\
                              +* #\Newline
                              +#\Newline
                              +* #\Tab
                              +#\Tab
                              +* (coerce "hello, multiverse!" 'list)
                              +(#\h #\e #\l #\l #\o #\, #\  #\m #\u #\l #\t #\i #\v #\e #\r #\s #\e #\!)
                              +
                              +

                              Did you notice that when you enter the #\Space character at the REPL, it returns the graphic representation of it and not the named? That is the expected behaviour---but it's generally considered easier to identify in source code when you use the named representation.

                              + + +
                              + +
                              +
                              +
                              + +

                              results matching ""

                              +
                                + +
                                +
                                + +

                                No results matching ""

                                + +
                                +
                                +
                                + +
                                +
                                + +
                                + + + + + + + + + + + + + + +
                                + + +
                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-05-more-chars.html b/clones/llthw.common-lisp.dev/1-02-05-more-chars.html new file mode 100644 index 00000000..78d890c2 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-05-more-chars.html @@ -0,0 +1,1854 @@ + + + + + + + More Characters ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                +
                                + + + + + + + + +
                                + +
                                + +
                                + + + + + + + + +
                                +
                                + +
                                +
                                + +
                                + +

                                Exercise 1.2.5

                                +

                                More Characters

                                +

                                While not portable, and not part of the Common Lisp standard, in SBCL and a few other Lisp implementations, you can refer to any character beyond the ASCII-range using a character object with its Unicode name, simply replacing the space word-separators with underscores (_). This is a little unusual for the Lisp world, since symbol names normally use the - (hyphen/dash) character as the word-separator; but as I said in Section 1.1.3, the Common Lisp Style Guide, that is a naming convention, which in this case isn't followed.

                                +

                                Some of these characters you've seen before, but lets go through a few so you get used to typing them out:

                                +
                                #\subscript_three
                                +#\greek_small_letter_lamda
                                +#\greek_capital_letter_sigma
                                +#\cuneiform_sign_an_plus_naga_opposing_an_plus_naga
                                +
                                +

                                These names are not case-sensitive: you could type #\Greek_Small_Letter_Lamda, #\GREEK_SMALL_LETTER_LAMDA, or even #\gReEK_sMaLl_LeTtER_lAmDA, and the Lisp reader will see it the same---for style and legibility of your code, however, you should stick with the lower-case names. You can use this syntax to enter any Unicode character into the SBCL REPL.

                                +

                                What You Should See

                                +
                                * #\subscript_three
                                +#\SUBSCRIPT_THREE
                                +* #\greek_small_letter_lamda
                                +#\GREEK_SMALL_LETTER_LAMDA
                                +* #\greek_capital_letter_sigma
                                +#\GREEK_CAPITAL_LETTER_SIGMA
                                +* #\cuneiform_sign_an_plus_naga_opposing_an_plus_naga
                                +#\CUNEIFORM_SIGN_AN_PLUS_NAGA_OPPOSING_AN_PLUS_NAGA
                                +
                                +

                                When you enter a character object at the REPL, it returns itself. When you want the character's glyph, i.e., what it will look like in a string, you need to put the character into a string. This will be covered in a later exercise.

                                +
                                + Note: +

                                You've probably noticed that the Greek letter lambda's name is "misspelled" in the example above. It's not a mistake, this is the actual character name in the Unicode standard, because the name of the letter is no longer spelled with the letter beta following the mu in modern Greek.

                                +

                                This is a good opportunity to remind you to type in exactly, character for character, what I have in the example code into the REPL. Did you get an error when typing the above example? Check what you typed, and make sure you typed exactly what you're supposed to.

                                +
                                + + +
                                + +
                                +
                                +
                                + +

                                results matching ""

                                +
                                  + +
                                  +
                                  + +

                                  No results matching ""

                                  + +
                                  +
                                  +
                                  + +
                                  +
                                  + +
                                  + + + + + + + + + + + + + + +
                                  + + +
                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-06-char-codes.html b/clones/llthw.common-lisp.dev/1-02-06-char-codes.html new file mode 100644 index 00000000..d7ef1fe3 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-06-char-codes.html @@ -0,0 +1,1845 @@ + + + + + + + Character Codes ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                  +
                                  + + + + + + + + +
                                  + +
                                  + +
                                  + + + + + + + + +
                                  +
                                  + +
                                  +
                                  + +
                                  + +

                                  Exercise 1.2.6

                                  +

                                  Character Codes

                                  +

                                  Character objects all have numeric values, called codes, corresponding to either the code-points in the Unicode table, or the current encoding of your running Lisp image. Lisp comes with a lot of useful tools for working with characters and strings as numbers and vectors/arrays, and where the standard falls short, there are several popular libraries you can always rely on.

                                  +

                                  You can get the code for a character object with the function char-code, and the character object for a code with code-char, as follows:

                                  +
                                  (code-char #x61)
                                  +(char-code #\a)
                                  +
                                  +
                                  + See the symbol `#x61` in the example above? That's the hex-number `0x61`, which is `97` in decimal. Sometimes it's more convenient to reference integers using a different notation than decimal. The Unicode tables are listed using hexadecimal (base-16), for instance---so you can just type the hex-number using the Sharpsign-X syntax. There will be more discussion on numbers and notation in Chapter 1.6. +
                                  + +

                                  What You Should See

                                  +
                                  * (code-char #x61)
                                  +#\a
                                  +* (char-code #\a)
                                  +97
                                  +
                                  + + +
                                  + +
                                  +
                                  +
                                  + +

                                  results matching ""

                                  +
                                    + +
                                    +
                                    + +

                                    No results matching ""

                                    + +
                                    +
                                    +
                                    + +
                                    +
                                    + +
                                    + + + + + + + + + + + + + + +
                                    + + +
                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-07-strings-from-chars.html b/clones/llthw.common-lisp.dev/1-02-07-strings-from-chars.html new file mode 100644 index 00000000..1463ea29 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-07-strings-from-chars.html @@ -0,0 +1,1843 @@ + + + + + + + Strings from Chars ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                    +
                                    + + + + + + + + +
                                    + +
                                    + +
                                    + + + + + + + + +
                                    +
                                    + +
                                    +
                                    + +
                                    + +

                                    Exercise 1.2.7

                                    +

                                    Strings From Characters

                                    +

                                    Most of the time, you'll want to work with strings instead of characters. You can get a one-character string object directly from a character object by calling the string function on it:

                                    +
                                    (string #\greek_small_letter_lamda)
                                    +
                                    +

                                    But the string function only takes one argument, a character or a string, and isn't very smart. It doesn't know how to do much in terms of type conversion.

                                    +

                                    It's also easy to get a string from a list of characters. Remember the coerce function introduced in exercise 1.2.4? You can change the type argument from 'list to 'string, and then the coerce function knows you want convert the list into a sequence of type string:

                                    +
                                    (coerce '(#\( #\greek_small_letter_lamda #\)) 'string)
                                    +
                                    +

                                    What You Should See

                                    +
                                    * (string #\greek_small_letter_lamda)
                                    +"λ"
                                    +* (coerce '(#\( #\greek_small_letter_lamda #\)) 'string)
                                    +"(λ)"
                                    +
                                    + + +
                                    + +
                                    +
                                    +
                                    + +

                                    results matching ""

                                    +
                                      + +
                                      +
                                      + +

                                      No results matching ""

                                      + +
                                      +
                                      +
                                      + +
                                      +
                                      + +
                                      + + + + + + + + + + + + + + +
                                      + + +
                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-08-printing.html b/clones/llthw.common-lisp.dev/1-02-08-printing.html new file mode 100644 index 00000000..d3edd759 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-08-printing.html @@ -0,0 +1,1869 @@ + + + + + + + Printing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                      +
                                      + + + + + + + + +
                                      + +
                                      + +
                                      + + + + + + + + +
                                      +
                                      + +
                                      +
                                      + +
                                      + +

                                      Exercise 1.2.8

                                      +

                                      Printing

                                      +

                                      There are a lot of ways for a programmer to handle printing with Lisp, and all of them are built on top of the write function. You will rarely need to use write directly, but it is useful to know about in order to understand all the different ways you can print objects in Lisp, and where to print them to.

                                      +

                                      Since the write function is extremely powerful and general, it takes a lot of parameters. Most of them are keyword parameters, however, so you can call the function without knowing or using all of them, and trust that the standard has implemented sensible defaults for your use-case.

                                      +

                                      The simplest use of write is to call it with only one argument, what you want printed, according to the system defaults for printing that type of object:

                                      +
                                      (write "hello")
                                      +(write 10)
                                      +(write 'hello)
                                      +
                                      +

                                      But lets say you want to know how an integer is printed in hexadecimal, octets, or binary. You can set the :base and :radix parameters to change the default behavior:

                                      +
                                      (write 10000 :base 16 :radix t)
                                      +(write 10000 :base 8 :radix t)
                                      +(write 10000 :base 2 :radix t)
                                      +
                                      +
                                      + The `:radix` keyword parameter is a generalized boolean. This means that any "non-NIL" value you pass to it will be read the same as "True", even if you don't supply `t` itself. The only time it will be treated as "False" is when you specifically pass it `NIL`. +
                                      + +

                                      What You Should See

                                      +
                                      * (write "hello")
                                      +"hello"
                                      +"hello"
                                      +* (write 10)
                                      +10
                                      +10
                                      +* (write 'hello)
                                      +HELLO
                                      +HELLO
                                      +* (write 10000 :base 16 :radix t)
                                      +#x2710
                                      +10000
                                      +* (write 10000 :base 8 :radix t)
                                      +#o23420
                                      +10000
                                      +* (write 10000 :base 2 :radix t)
                                      +#b10011100010000
                                      +10000
                                      +
                                      +

                                      Do you understand everything that's happening here? Take a moment to review what you've typed, and what you've gotten back at the REPL.

                                      +

                                      With the first three examples, you probably noticed that you're getting back the same value twice. This is because the default :stream is *standard-output*, which is the same place function return values are being sent while you're working in the REPL. You're also printing the objects with all their default settings, as Lisp would normally print them for you. You won't normally see this exact behavior outside the REPL though---in upcoming exercises, you'll learn more about streams and what you can do with them, and what happens to values when they're not sent to a stream or bound to a variable.

                                      +

                                      But notice how changing the defaults in the last three examples changed the way write printed the arguments, but didn't change the actual return value in any way (i.e., the integer 10,000)? This is how write works. First it prints the object parameter you pass it, according to any changes you've made to the instructions for the Lisp Printer using write's keyword parameters, and then when it's done it returns the original object as well.

                                      + + +
                                      + +
                                      +
                                      +
                                      + +

                                      results matching ""

                                      +
                                        + +
                                        +
                                        + +

                                        No results matching ""

                                        + +
                                        +
                                        +
                                        + +
                                        +
                                        + +
                                        + + + + + + + + + + + + + + +
                                        + + +
                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-09-more-printing.html b/clones/llthw.common-lisp.dev/1-02-09-more-printing.html new file mode 100644 index 00000000..7a155bac --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-09-more-printing.html @@ -0,0 +1,1869 @@ + + + + + + + More Printing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                        +
                                        + + + + + + + + +
                                        + +
                                        + +
                                        + + + + + + + + +
                                        +
                                        + +
                                        +
                                        + +
                                        + +

                                        Exercise 1.2.9

                                        +

                                        More Printing

                                        +

                                        As I said in the previous exercise, Common Lisp has a lot of functions for printing, including one named print, which you'll see here in this exercise. I'll also show you how the same functionality can be implemented with write, so you can get a feel for specializing a very general interface---a common development pattern in Common Lisp.

                                        +

                                        print works exactly as you would expect a print function to work. You pass it an object to print and a stream to print it to. It prints the object between a new-line character and a space---note: print prints the object readably, in other words, in a format suitable to be read by the Lisp reader, escaping special characters.

                                        +

                                        Let's see it in action, along with an equivalent version using write:

                                        +
                                        (print "hello, multiverse!")
                                        +(print "hello again, multiverse!" t)
                                        +(print "hello, multiverse, are you there?" nil)
                                        +(progn (terpri t)
                                        +       (write "hello, multiverse!" :stream t :escape t)
                                        +       (write-char #\Space t))
                                        +
                                        +

                                        There are a few new things here, which we can go over quickly for now. They will be explained in more detail later.

                                        +

                                        First, notice that the print function takes two arguments: the object you want to print, and then the stream you want to print the object to. You can use the boolean truth symbol t as shorthand for *standard-output*. You don't have to pass the second argument---the default is nil, so the first line of code is the same in principle as the third.

                                        +

                                        progn, one of the special operators, tells Lisp to evaluate each expression in its body sequentially, in the order they appear.

                                        +

                                        terpri stands for "terminate printing". It's used to send a new-line character to a stream. It seems slightly illogical to use it at the beginning of a printing sequence, but that is how the print function is implemented.

                                        +

                                        For the write function, I've introduced two new keyword parameters, :stream and :escape, which tell write where to print the object parameter, and whether or not what's printed should be escaped, respectively.

                                        +

                                        Lastly, there is write-char, which is like write, but only prints a single character object to a stream.

                                        +

                                        What You Should See

                                        +
                                        * (print "hello, multiverse!")
                                        +
                                        +"hello, multiverse!"
                                        +"hello, multiverse!"
                                        +* (print "hello again, multiverse!" t)
                                        +
                                        +"hello again, multiverse!"
                                        +"hello again, multiverse!"
                                        +* (print "hello, multiverse, are you there?" nil)
                                        +
                                        +"hello, multiverse, are you there?"
                                        +"hello, multiverse, are you there?"
                                        +* (progn (terpri t)
                                        +         (write "hello, multiverse!" :stream t :escape t)
                                        +         (write-char #\Space t))
                                        +
                                        +"hello, multiverse!"
                                        +#\
                                        +
                                        +

                                        Everything make sense?

                                        +

                                        A little word on the last example---notice how the return value of the whole progn form is different from print? In Lisp, if you don't specify a return value (and in so doing, leave the expression early, before evaluation reaches the end), the return value of the last evaluated form in the expression is returned from the top-most expression. In this case, write-char is the last expression in the progn, so its return value, #\Space, is returned by the progn.

                                        +

                                        Obviously, you'll notice, the print function is doing something different---but we'll get to that soon.

                                        + + +
                                        + +
                                        +
                                        +
                                        + +

                                        results matching ""

                                        +
                                          + +
                                          +
                                          + +

                                          No results matching ""

                                          + +
                                          +
                                          +
                                          + +
                                          +
                                          + +
                                          + + + + + + + + + + + + + + +
                                          + + +
                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-10-prin1.html b/clones/llthw.common-lisp.dev/1-02-10-prin1.html new file mode 100644 index 00000000..cdcfd3be --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-10-prin1.html @@ -0,0 +1,1849 @@ + + + + + + + Printing With prin1 ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                          +
                                          + + + + + + + + +
                                          + +
                                          + +
                                          + + + + + + + + +
                                          +
                                          + +
                                          +
                                          + +
                                          + +

                                          Exercise 1.2.10

                                          +

                                          Printing With prin1

                                          +

                                          The prin1 function is very similar to print, except it doesn't output a preceding newline or a trailing space. Its emphasis is on printing readably for the Lisp Reader, i.e., what you print with prin1 is meant to be read again as source code. Like print, prin1 sets the Lisp printer paramater :escape to t, so special characters are printed escaped in strings, the same way you have to type them at the REPL and in your Lisp source files.

                                          +
                                          (prin1 "Although largely uninteresting, this \"string\" has escaped characters in it.")
                                          +
                                          +(prin1 "Remember, since the backslash (\\) is the escape character, it needs to be escaped too.")
                                          +
                                          +(prin1 "\Y\o\u\ \c\a\n\ \a\l\s\o\ \e\s\c\a\p\e\ \e\v\e\r\y\ \c\h\a\r\a\c\t\e\r\ \i\n\ \a\ \s\t\r\i\n\g\.")
                                          +
                                          +

                                          What You Should See

                                          +
                                          * (prin1 "Although largely uninteresting, this \"string\" has escaped characters in it.")
                                          +"Although largely uninteresting, this \"string\" has escaped characters in it."
                                          +"Although largely uninteresting, this \"string\" has escaped characters in it."
                                          +* (prin1 "Remember, since the backslash (\\) is the escape character, it needs to be escaped too.")
                                          +"Remember, since the backslash (\\) is the escape character, it needs to be escaped too."
                                          +"Remember, since the backslash (\\) is the escape character, it needs to be escaped too."
                                          +* (prin1 "\Y\o\u\ \c\a\n\ \a\l\s\o\ \e\s\c\a\p\e\ \e\v\e\r\y\ \c\h\a\r\a\c\t\e\r\ \i\n\ \a\ \s\t\r\i\n\g\.")
                                          +"You can also escape every character in a string."
                                          +"You can also escape every character in a string."
                                          +
                                          +

                                          Notice how only the characters that need to be escaped in a string are printed and returned escaped? As far as the Lisp Reader is concerned, a string can contain any character---but since the double-quote character terminates a string, it needs to be escaped if you want it printed, and since the escape character used would normally escape the following character, you also have to escape the backslash to print it. But that's it. Every other character supported by your implementation's current encoding can be included in a string.

                                          + + +
                                          + +
                                          +
                                          +
                                          + +

                                          results matching ""

                                          +
                                            + +
                                            +
                                            + +

                                            No results matching ""

                                            + +
                                            +
                                            +
                                            + +
                                            +
                                            + +
                                            + + + + + + + + + + + + + + +
                                            + + +
                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-11-princ.html b/clones/llthw.common-lisp.dev/1-02-11-princ.html new file mode 100644 index 00000000..a150ae67 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-11-princ.html @@ -0,0 +1,1850 @@ + + + + + + + Printing With princ ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                            +
                                            + + + + + + + + +
                                            + +
                                            + +
                                            + + + + + + + + +
                                            +
                                            + +
                                            +
                                            + +
                                            + +

                                            Exercise 1.2.11

                                            +

                                            Printing With princ

                                            +

                                            When you want to send a string to a stream that's meant for your users and not the Lisp Reader, you'll want to use the princ function. It sets the Lisp Printer parameters :escape and :readably to nil, so that your users can see the string you intended, and not the string you had to type in Lisp to not break anything.

                                            +
                                            (princ "Hello, multiverse!")
                                            +
                                            +(princ "My name is \"Colin\".")
                                            +
                                            +
                                            + Tip: +

                                            As an exception to the usual rule of "Type exactly what I type", you can change my name to yours whenever it comes up in a source-code example. Just make sure it runs!

                                            +
                                            + +

                                            What You Should See

                                            +
                                            * (princ "Hello, multiverse!")
                                            +Hello, multiverse!
                                            +"Hello, multiverse!"
                                            +* (princ "My name is \"Colin\".")
                                            +My name is "Colin".
                                            +"My name is \"Colin\"."
                                            +
                                            +

                                            Now the difference between the printed string and the return result for a function should be more clear. You can see above what setting the Lisp Printer parameters :escape and :readably to nil do: it prints the characters in a string un-escaped, not printing the outer quotation marks---so your users get exactly the string you intended.

                                            +

                                            The princ function, like the other Lisp Printer functions we've covered so far, still returns the original string object after it has been printed to a stream. This is not the case with format, which we'll go over briefly in the next two exercises.

                                            + + +
                                            + +
                                            +
                                            +
                                            + +

                                            results matching ""

                                            +
                                              + +
                                              +
                                              + +

                                              No results matching ""

                                              + +
                                              +
                                              +
                                              + +
                                              +
                                              + +
                                              + + + + + + + + + + + + + + +
                                              + + +
                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-12-format.html b/clones/llthw.common-lisp.dev/1-02-12-format.html new file mode 100644 index 00000000..76c820ad --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-12-format.html @@ -0,0 +1,1868 @@ + + + + + + + A Brief Introduction to Format ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                              +
                                              + + + + + + + + +
                                              + +
                                              + +
                                              + + + + + + + + +
                                              +
                                              + +
                                              +
                                              + +
                                              + +

                                              Exercise 1.2.12

                                              +

                                              A Brief Introduction to Format

                                              +

                                              Pretty much every programming language has some way to insert arbitrary data into a string. Lisp is no exception. One difference, perhaps, is that in Lisp, the format function is a part of the language standard, and must be fully supported for the implementation to call itself Common Lisp. In other languages, formatting strings is usually outside the scope of the core language, and only available through the standard library.

                                              +

                                              The format function in Lisp is so powerful, however, that I can only introduce you to a little bit of it right now. The full treatise on this surprising core ANSI Common Lisp functionality will appear in Chapter 1.18, once you have a better grasp on key features of the language.

                                              +

                                              The Basics of Format

                                              +

                                              The format function uses a special type of string with its own internal syntax, called control sequences. These control sequences are made up of the tilde (~) character and the control character itself, and may also include certain infix parameters which customize the behavior of the control sequence.

                                              +

                                              For example, a format control sequence you'll use often is ~A, the aesthetic control sequence. It consumes an argument, and inserts that argument into the string, printed the same way that the princ function would print it. ~S, the standard control sequence, consumes an argument and prints it the way prin1 would print it. And ~W, the write control sequence, consumes an argument and prints it the way that write would print it without any of its keyword parameters changed.

                                              +

                                              What do I mean by "consumes an argument" though? Well, let me show you:

                                              +
                                              (format nil "Hello, my name is ~A." "Colin")
                                              +
                                              +

                                              This expression calls the format function, tells it to return the formatted string by setting the output stream to nil, and creates a format string that consumes one argument which will be printed aesthetically. Following that is the one argument, a string with my name in it.

                                              +

                                              Now consider this example:

                                              +
                                              (format nil "My name is ~A ~A." "Colin" "Lupton")
                                              +
                                              +

                                              Now this example expects to consume two arguments. And those two arguments follow, which are now my first and last names as separate string objects.

                                              +

                                              Now try these out:

                                              +
                                              (format t "Hello, ~A!" "multiverse")
                                              +
                                              +(format t "Hello, ~S!" "multiverse")
                                              +
                                              +(format t "Hello, ~W!" "multiverse")
                                              +
                                              +

                                              What You Should See

                                              +

                                              You should notice right away a few differences between format and the standard Lisp printer functions. You should see something like this:

                                              +
                                              * (format nil "My name is ~A." "Colin")
                                              +"My name is Colin."
                                              +* (format nil "My name is ~A ~A." "Colin" "Lupton")
                                              +"My name is Colin Lupton."
                                              +* (format t "Hello, ~A!" "multiverse")
                                              +Hello, multiverse!
                                              +NIL
                                              +* (format t "Hello, ~S!" "multiverse")
                                              +Hello, "multiverse"!
                                              +NIL
                                              +* (format t "Hello, ~W!" "multiverse")
                                              +Hello, "multiverse"!
                                              +NIL
                                              +
                                              +

                                              First up, notice that when you tell format to return the formatted string, you only get back one value now? The return value alone. But when you send the formatted string to t, which in the context of the format function's stream parameter is a shorthand for *standard-output*, you see that the formatted string is printed, and you get back a return value of nil instead of another string object.

                                              +

                                              Now notice that with the standard and write control sequences, the argument gets printed literally? That is, it includes the double-quote syntax that would tell the Lisp Reader that this is a string object, if you were to have Lisp try and read such a string---but since there's other junk in the string that Lisp wouldn't understand, it's not a good idea to try.

                                              + + +
                                              + +
                                              +
                                              +
                                              + +

                                              results matching ""

                                              +
                                                + +
                                                +
                                                + +

                                                No results matching ""

                                                + +
                                                +
                                                +
                                                + +
                                                +
                                                + +
                                                + + + + + + + + + + + + + + +
                                                + + +
                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-13-more-format.html b/clones/llthw.common-lisp.dev/1-02-13-more-format.html new file mode 100644 index 00000000..e68a1c72 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-13-more-format.html @@ -0,0 +1,1872 @@ + + + + + + + A Little Bit More on Format ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                +
                                                + + + + + + + + +
                                                + +
                                                + +
                                                + + + + + + + + +
                                                +
                                                + +
                                                +
                                                + +
                                                + +

                                                Exercise 1.2.13

                                                +

                                                A Little Bit More on Format

                                                +

                                                Now that you've seen how the format function works, we'll go through a few more control sequences that you might find useful. Again, the full tour of format string syntax won't be coming until chapter 1.18, but this should give you enough to work with for now.

                                                +

                                                Try these examples out, and see if you can guess what these format control sequences do. They will be explained afterwards, but don't cheat---try them out, and see if you can guess what they do before you read on past the example.

                                                +
                                                (format nil "~~")
                                                +
                                                +(format nil "H~CO" #\subscript_two)
                                                +
                                                +(format nil "~R" 10000)
                                                +
                                                +(format nil "~X" 10000)
                                                +
                                                +(format nil "~D" 10000)
                                                +
                                                +(format nil "~O" 10000)
                                                +
                                                +(format nil "~B" 10000)
                                                +
                                                +(format nil "~%Hello, ~A!" "Colin")
                                                +
                                                +(format nil "~&I said, hello!")
                                                +
                                                +

                                                What You Should See

                                                +
                                                (format nil "~~")
                                                +"~"
                                                +CL-USER> (format nil "H~CO" #\subscript_two)
                                                +"H₂O"
                                                +CL-USER> (format nil "~R" 10000)
                                                +"ten thousand"
                                                +CL-USER> (format nil "~X" 10000)
                                                +"2710"
                                                +CL-USER> (format nil "~D" 10000)
                                                +"10000"
                                                +CL-USER> (format nil "~O" 10000)
                                                +"23420"
                                                +CL-USER> (format nil "~B" 10000)
                                                +"10011100010000"
                                                +
                                                +

                                                Did you guess everything correctly? If not, don't panic. Look over what you typed and the return results, and see now if you can infer what was printed to the string.

                                                +

                                                Much like with the backslash character in a regular string, you can include a tilde character in a format string with the tilde-tilde control sequence, ~~. It doesn't consume any arguments.

                                                +

                                                You can consume a character object argument using ~C.

                                                +

                                                You can insert an integer into a format string with ~R, but since it can be a bit overkill with its flexibility, there are also simplified control sequences for printing the integer to hexadecimal, decimal, octet, and binary, like we did with write earlier: ~X, ~D, ~O, and ~B, respectively. They all consume an argument, which must be an integer.

                                                +

                                                You can force the insertion of a #\Newline character with ~%. It doesn't consume any arguments.

                                                +

                                                And you can insert a #\Newline only if the output stream is not already at the beginning of a line with ~&. It doesn't consume any arguments either.

                                                + + +
                                                + +
                                                +
                                                +
                                                + +

                                                results matching ""

                                                +
                                                  + +
                                                  +
                                                  + +

                                                  No results matching ""

                                                  + +
                                                  +
                                                  +
                                                  + +
                                                  +
                                                  + +
                                                  + + + + + + + + + + + + + + +
                                                  + + +
                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-14-pathnames.html b/clones/llthw.common-lisp.dev/1-02-14-pathnames.html new file mode 100644 index 00000000..9cb1a120 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-14-pathnames.html @@ -0,0 +1,1884 @@ + + + + + + + Pathnames ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                  +
                                                  + + + + + + + + +
                                                  + +
                                                  + +
                                                  + + + + + + + + +
                                                  +
                                                  + +
                                                  +
                                                  + +
                                                  + +

                                                  Exercise 1.2.14

                                                  +

                                                  Pathnames

                                                  +

                                                  Lisp has a special way of handling files from your computer: pathname objects. They allow Lisp to handle file-names, for the most part, in a platform-agnostic manner. If they seem like overkill, just keep in mind how many different platforms and file-systems Lisp supports.

                                                  +

                                                  Pathname objects are represented using the reader macro syntax #P"..."; they look like strings preceded by a Sharpsign-P, but they have a lot of internal structure you have to know about. Let's take a look at what you can get out of a seemingly simple pathname:

                                                  +
                                                  (truename ".")
                                                  +
                                                  +(pathname-directory (truename "."))
                                                  +
                                                  +(pathname-host (truename "."))
                                                  +
                                                  +(pathname-name (truename "."))
                                                  +
                                                  +(pathname-type (truename "."))
                                                  +
                                                  +

                                                  You'll get nil back for pathname-name and pathname-type. But now let's create a new file with your text editor named "llthw-ex-1-2-14.lisp" and save it in the folder on your computer you got back from (truename "."). If you changed the default folder to open SBCL in, like you were instructed to, this should be your home folder, or a folder dedicated to your Lisp code.

                                                  +

                                                  In "llthw-ex-1-2-14.lisp" enter the following code and save it again:

                                                  +
                                                  ;; an empty Common Lisp file
                                                  +
                                                  +

                                                  Back at the REPL, try this now:

                                                  +
                                                  (truename "llthw-ex-1-2-14.lisp")
                                                  +
                                                  +(pathname-name (truename "llthw-ex-1-2-14.lisp"))
                                                  +
                                                  +(pathname-type (truename "llthw-ex-1-2-14.lisp"))
                                                  +
                                                  +(file-namestring (truename "llthw-ex-1-2-14.lisp"))
                                                  +
                                                  +

                                                  What You Should See

                                                  +

                                                  Obviously, the exact pathnames you see will be personalized for your system. Mine below are just for sake of example, so don't panic if you don't see exactly the same pathname objects that I have.

                                                  +
                                                  * (truename ".")
                                                  +#P"/home/colin/"
                                                  +* (pathname-directory (truename "."))
                                                  +(:ABSOLUTE "home" "colin")
                                                  +* (pathname-host (truename "."))
                                                  +#<SB-IMPL::UNIX-HOST {1000020BE3}>
                                                  +* (pathname-name (truename "."))
                                                  +NIL
                                                  +* (pathname-type (truename "."))
                                                  +NIL
                                                  +
                                                  +

                                                  After creating the file "llthw-ex-1-2-14.lisp" in the directory you got from (truename "."):

                                                  +
                                                  * (truename "llthw-ex-1-2-14.lisp")
                                                  +#P"/home/colin/llthw-ex-1-2-14.lisp"
                                                  +* (pathname-name (truename "llthw-ex-1-2-14.lisp"))
                                                  +"llthw-ex-1-2-14"
                                                  +* (pathname-type (truename "llthw-ex-1-2-14.lisp"))
                                                  +"lisp"
                                                  +* (file-namestring (truename "llthw-ex-1-2-14.lisp"))
                                                  +"llthw-ex-1-2-14.lisp"
                                                  +
                                                  +

                                                  Do you understand what's going on here? Take a moment to review to see if you can guess what everything is doing, and that all the code is returning what you think should be returned.

                                                  +

                                                  Let's start with the function truename. You can see that it takes a regular string that represents, but isn't, a pathname object. In fact, truename accepts any pathname designator, which can be a relative or full pathname namestring, a file stream, or an actual pathname object.

                                                  +

                                                  The rest of the new functions you've seen this exercise will only accept a pathname object, proper. That is why you need to first call truename on the pathname designator strings above, to get a pathname object to pass to the pathname functions.

                                                  +

                                                  Notice the last function in the examples above, file-namestring? It gives you back just the file's namestring for a pathname object to a file. If you give it a pathname object to a directory, it just returns an empty string, "". There are some other, similar functions related to it: namestring, directory-namestring, host-namestring, and enough-namestring. Can you guess what they do?

                                                  +

                                                  Extra Credit

                                                  +

                                                  Try out the extra namestring functions, namestring, directory-namestring, host-namestring, and enough-namestring. Can you get them to run? Can you predict the results you get from them?

                                                  + + +
                                                  + +
                                                  +
                                                  +
                                                  + +

                                                  results matching ""

                                                  +
                                                    + +
                                                    +
                                                    + +

                                                    No results matching ""

                                                    + +
                                                    +
                                                    +
                                                    + +
                                                    +
                                                    + +
                                                    + + + + + + + + + + + + + + +
                                                    + + +
                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-15-streams.html b/clones/llthw.common-lisp.dev/1-02-15-streams.html new file mode 100644 index 00000000..8f1cbefe --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-15-streams.html @@ -0,0 +1,1867 @@ + + + + + + + Streams ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                    +
                                                    + + + + + + + + +
                                                    + +
                                                    + +
                                                    + + + + + + + + +
                                                    +
                                                    + +
                                                    +
                                                    + +
                                                    + +

                                                    Exercise 1.2.15

                                                    +

                                                    Streams

                                                    +

                                                    You've seen a little bit about streams already---just enough to print to *standard-output*. But streams can do a lot more than that. Streams are, simply put, the crux of I/O in Lisp.

                                                    +

                                                    Streams are objects, too, just like the character, string, integer, and pathname objects you've seen so far. A stream can be designated just for input, just for output, or both. Typically, streams accept only characters or bytes---so when you're printing a string to a stream, you are in fact streaming the sequence of characters that make up a string.

                                                    +

                                                    The idea of a stream is pretty simple to understand---if you've ever used YouTube or Netflix, you know that those services stream video to their users, so that you can start watching a video before the whole file has downloaded to your computer. Streams in Lisp are no different---you send data to a stream, and a user listening on that stream gets the data as it becomes available.

                                                    +

                                                    Between bytes and characters, you can send any data you want over a stream. Lisp makes it a cinch to read and write data for I/O.

                                                    +

                                                    Making Streams

                                                    +

                                                    There are a few ways to make string streams manually for input and output; but bi-directional streams can only be made from existing input and output streams. Try out the following code to get a feel for what streams do:

                                                    +
                                                    (make-string-input-stream "hello?")
                                                    +
                                                    +(read (make-string-input-stream "hello!"))
                                                    +
                                                    +(with-input-from-string (s "It's the multiverse!")
                                                    +  (read s))
                                                    +
                                                    +(with-output-to-string (out)
                                                    +  (with-input-from-string (in "\"Can I ask who's calling?\"")
                                                    +    (let ((io (make-two-way-stream in out)))
                                                    +      (format io "~A It's the Jovian moon, Io!" (read io)))))
                                                    +
                                                    +

                                                    What You Should See

                                                    +
                                                    * (make-string-input-stream "hello?")
                                                    +#<SB-IMPL::STRING-INPUT-STREAM {1004CDF9B3}>
                                                    +* (read (make-string-input-stream "hello!"))
                                                    +HELLO!
                                                    +* (with-input-from-string (s "It's the multiverse!")
                                                    +    (read s))
                                                    +IT
                                                    +* (with-output-to-string (out)
                                                    +    (with-input-from-string (in "\"Can I ask who's calling?\"")
                                                    +      (let ((io (make-two-way-stream in out)))
                                                    +        (format io "~A It's the Jovian moon, Io!" (read io)))))
                                                    +"Can I ask who's calling? It's the Jovian moon, Io!"
                                                    +
                                                    +

                                                    Here you can see that it's pretty easy to create an input stream object from a string, but on its own all you get is the object itself returned. What do you do with that?

                                                    +

                                                    The next example wraps the make-string-input-stream in a read form. You haven't seen this before, but basically it's the entry point to the Lisp Reader, which I have mentioned in the context of printing. Remember what I said about Lisp printing things readably? Since the input you gave it doesn't have any extra escaped quotation marks, read thinks it's seeing a symbol. So that's what you get back, the uninterned symbol 'HELLO!.

                                                    +

                                                    You can see another side of this same point in the third example. The with-input-from-string macro does a little bit more work for you than just creating an input stream---it also binds that stream to the local variable s for the body of the macro. In this case, we just read from the stream bound to s. And since read means have Lisp read it, it treats it as Lisp data, and parses the IT as a symbol, which ends at the single quote. If you read from that stream three more times, you'd get the symbols 'S, THE, and MULTIVERSE!.

                                                    +

                                                    Lastly, we create a bi-directional stream, writing to it and reading from it in a really silly way just because we can. First, we create the output stream and bind it to a local variable out. Second, we create an input stream from the string "\"Can I ask who's calling?\"" and bind it to a local variable in. Third, we make a bi-directional stream from those bound to in and out, and bind it to the local variable io. Fourth, we use the format function to print to the bi-directional stream, feeding the data from the input stream back into the output stream. All this is then returned by the outermost macro, with-output-to-string. Notice how this time you got the whole string? That's because you entered the string object readably for the input stream.

                                                    +

                                                    In the next exercise, we'll look at creating, and reading and writing to binary streams from files on your computer.

                                                    + + +
                                                    + +
                                                    +
                                                    +
                                                    + +

                                                    results matching ""

                                                    +
                                                      + +
                                                      +
                                                      + +

                                                      No results matching ""

                                                      + +
                                                      +
                                                      +
                                                      + +
                                                      +
                                                      + +
                                                      + + + + + + + + + + + + + + +
                                                      + + +
                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-16-file-streams.html b/clones/llthw.common-lisp.dev/1-02-16-file-streams.html new file mode 100644 index 00000000..3432b9df --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-16-file-streams.html @@ -0,0 +1,1869 @@ + + + + + + + File Streams ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                      +
                                                      + + + + + + + + +
                                                      + +
                                                      + +
                                                      + + + + + + + + +
                                                      +
                                                      + +
                                                      +
                                                      + +
                                                      + +

                                                      Exercise 1.2.16

                                                      +

                                                      File Streams

                                                      +

                                                      To read from and write to files on your computer with Lisp, you create a file-stream object. While similar in principle to string streams, there's stuff you can do with file streams that you can't do with string streams.

                                                      +

                                                      Like with string streams, you can create file streams manually with open. But for now let's look at the simplest use-case, creating a file using the with-open-file macro and putting some text in it; then we'll read that text back using the same macro and print it in the REPL.

                                                      +
                                                      (with-open-file (s "~/monkey.txt" :direction :output :if-does-not-exist :create :if-exists :supersede)
                                                      +  (format s "I had a little monkey,~%Brought him to the country,~%Fed him on ginger-bread...~%"))
                                                      +
                                                      +(with-open-file (s "~/monkey.txt" :direction :input)
                                                      +  (format t "~&;;; ~A" (read-line s)))
                                                      +
                                                      +(with-open-file (s "~/monkey.txt" :direction :input)
                                                      +  (do ((line (read-line s) (read-line s nil 'eof)))
                                                      +      ((eq line 'eof) "-- Marilyn Manson")
                                                      +    (format t "~&;;; ~A~%" line)))
                                                      +
                                                      +
                                                      + Note: +

                                                      No animals were harmed in the making of this exercise.

                                                      +
                                                      + +

                                                      What You Should See

                                                      +
                                                      * (with-open-file (s "~/monkey.txt" :direction :output :if-does-not-exist :create :if-exists :supersede)
                                                      +    (format s "I had a little monkey,~%Brought him to the country,~%Fed him on ginger-bread...~%"))
                                                      +NIL
                                                      +* (with-open-file (s "~/monkey.txt" :direction :input)
                                                      +    (format t "~&;;; ~A" (read-line s)))
                                                      +;;; I had a little monkey,
                                                      +NIL
                                                      +* (with-open-file (s "~/monkey.txt" :direction :input)
                                                      +    (do ((line (read-line s) (read-line s nil 'eof)))
                                                      +        ((eq line 'eof) "-- Marilyn Manson")
                                                      +      (format t "~&;;; ~A~%" line)))
                                                      +;;; I had a little monkey,
                                                      +;;; Brought him to the country,
                                                      +;;; Fed him on ginger-bread...
                                                      +"-- Marilyn Manson"
                                                      +
                                                      +

                                                      First up, you might want to take this opportunity to browse your file system and verify that the file monkey.txt was actually created in your Home directory. You should be able to open it with any text editor you want and see what you wrote to it. Cool, eh? Any time you're at the REPL, and want to make a note of something, you can use this code to leave yourself a reminder.

                                                      +

                                                      As I said above, you can create either an input or output file stream using the function open; but if you do it manually, you have to remember to close it as soon as you've finished writing to it or reading from it. The with-open-file macro opens and closes the file for you, and gives you a stream to work with in its body. It's much more convenient and better reflects the Lisp Way.

                                                      +

                                                      Don't worry too much about the do loop constructor I've introduced; all you need to know for now is that it iterates over the lines in the file you opened until it reaches the end-of-file. Once it does, you can set something to be returned---which in this case is just a string.

                                                      +

                                                      In the next exercise, we'll be dipping our toes into binary streams.

                                                      + + +
                                                      + +
                                                      +
                                                      +
                                                      + +

                                                      results matching ""

                                                      +
                                                        + +
                                                        +
                                                        + +

                                                        No results matching ""

                                                        + +
                                                        +
                                                        +
                                                        + +
                                                        +
                                                        + +
                                                        + + + + + + + + + + + + + + +
                                                        + + +
                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-17-binary-streams.html b/clones/llthw.common-lisp.dev/1-02-17-binary-streams.html new file mode 100644 index 00000000..86182880 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-17-binary-streams.html @@ -0,0 +1,1857 @@ + + + + + + + Binary Streams ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                        +
                                                        + + + + + + + + +
                                                        + +
                                                        + +
                                                        + + + + + + + + +
                                                        +
                                                        + +
                                                        +
                                                        + +
                                                        + +

                                                        Exercise 1.2.17

                                                        +

                                                        Binary Streams

                                                        +

                                                        You might find the subject of Binary Streams a little esoteric at such an early stage in your Lisp experience, but we'll only be touching on them lightly, just to show you that they're there.

                                                        +

                                                        Working with Binary Streams in general is very similar to working with file streams. You open an input, output, or bi-directional file stream, and you simply specify that you're working with bytes. In the last exercise, we didn't specify a type for input and output, and thus used the default character stream for files.

                                                        +
                                                        (with-open-file (b "~/binary-monkey.txt" :direction :output :element-type 'unsigned-byte :if-exists :supersede)
                                                        +  (write-byte 109 b)
                                                        +  (write-byte 111 b)
                                                        +  (write-byte 110 b)
                                                        +  (write-byte 107 b)
                                                        +  (write-byte 101 b)
                                                        +  (write-byte 121 b))
                                                        +
                                                        +

                                                        What You Should See

                                                        +
                                                        * (with-open-file (b "~/binary-monkey.txt" :direction :output :element-type 'unsigned-byte :if-exists :supersede)
                                                        +    (write-byte 109 b)
                                                        +    (write-byte 111 b)
                                                        +    (write-byte 110 b)
                                                        +    (write-byte 107 b)
                                                        +    (write-byte 101 b)
                                                        +    (write-byte 121 b))
                                                        +121
                                                        +
                                                        +

                                                        Now go to the file ~/binary-monkey.txt on your computer, and open it in a text editor. What do you see? Is it what you expected or a complete surprise?

                                                        +

                                                        If all went well, you should have a file that just contains the word "monkey". Remember, everything in a computer is really stored and run in binary---everything else is just a representation for our benefit, to make working with computers easier and friendlier. But it helps to remember this point. You won't normally want to read and write to text files in binary, but for many other file formats and network protocols, this is the best way to work with them.

                                                        +

                                                        When you set the element-type of the file stream to unsigned-byte, that allowed you to use write-byte on the stream. Lisp also lets you represent bytes as integers. So when you wrote those numbers to the text file, you were really writing the character bytes to that text file that spelled out the word "monkey". You could also have used the hexadecimal, octal, or binary representation of the integers, as I showed you in exercise 1.2.8.

                                                        +

                                                        Extra Credit

                                                        +

                                                        Rewrite the above example three times to use a do loop I showed you before, and a list of the numbers 109, 111, 110, 107, 101, and 121; represent these integers in hexadecimal, octal, and binary notation, respectively.

                                                        +

                                                        If you do it right, you should only have to call the write-byte function once in your do loop.

                                                        +

                                                        Also write the code to read the file back into Lisp as a string, and transform it into ALL-CAPS. Hint: you can do this either with format or the function string-upcase.

                                                        + + +
                                                        + +
                                                        +
                                                        +
                                                        + +

                                                        results matching ""

                                                        +
                                                          + +
                                                          +
                                                          + +

                                                          No results matching ""

                                                          + +
                                                          +
                                                          +
                                                          + +
                                                          +
                                                          + +
                                                          + + + + + + + + + + + + + + +
                                                          + + +
                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-18-prompting-users.html b/clones/llthw.common-lisp.dev/1-02-18-prompting-users.html new file mode 100644 index 00000000..0f4a6fa9 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-18-prompting-users.html @@ -0,0 +1,1856 @@ + + + + + + + Prompting Users ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                          +
                                                          + + + + + + + + +
                                                          + +
                                                          + +
                                                          + + + + + + + + +
                                                          +
                                                          + +
                                                          +
                                                          + +
                                                          + +

                                                          Exercise 1.2.18

                                                          +

                                                          Prompting Users

                                                          +

                                                          Lisp has two built-in functions for prompting users, y-or-n-p and yes-or-no-p---they are predicate functions, in the sense that all they do is return T or NIL. Unlike most other predicate functions you'll see, though, the argument you pass to them in code isn't what they're testing---it's a format string that goes to the user over *query-io*, and the test is applied to the user's input.

                                                          +

                                                          If you've used the command line at all before starting this book, you may have noticed a lot of command line applications will tell you what they're going to do, and ask you to confirm before it continues. Something like, "Going to write your changes to a file. Are you sure you want to continue? (Y or N)." And then it waits for you to type the letter Y or N on the keyboard.

                                                          +

                                                          Both of these functions are similar in purpose, but y-or-n-p only expects the user to type one character on the keyboard. yes-or-no-p expects the user to type the whole word "yes" or "no". In both cases, hit Return/Enter after to submit your response.

                                                          +

                                                          Naturally, feel free to substitute your own name in the the example below:

                                                          +
                                                          (y-or-n-p "Is your name Colin?")
                                                          +
                                                          +(yes-or-no-p "Are you sure?")
                                                          +
                                                          +(y-or-n-p "Are you a ~S?" 'monkey)
                                                          +
                                                          +

                                                          What You Should See

                                                          +
                                                          * (y-or-n-p "Is your name Colin?")
                                                          +Is your name Colin? (y or n) y
                                                          +
                                                          +T
                                                          +* (yes-or-no-p "Are you sure?")
                                                          +Are you sure? (yes or no) yes
                                                          +
                                                          +T
                                                          +* (y-or-n-p "Are you a ~S?" 'monkey)
                                                          +Are you a MONKEY? (y or n) n
                                                          +
                                                          +NIL
                                                          +
                                                          +

                                                          Try each of these functions out a few times. Ask any question you want in the string you pass to y-or-n-p and yes-or-no-p.

                                                          +

                                                          We will be looking at more involved prompts in Chapter 1.3, where your user can type more than just "y" or "n", or "yes" or "no". But first, in the next exercise we'll take a look at Lisp's pretty-printer.

                                                          + + +
                                                          + +
                                                          +
                                                          +
                                                          + +

                                                          results matching ""

                                                          +
                                                            + +
                                                            +
                                                            + +

                                                            No results matching ""

                                                            + +
                                                            +
                                                            +
                                                            + +
                                                            +
                                                            + +
                                                            + + + + + + + + + + + + + + +
                                                            + + +
                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-02-19-pretty-printing.html b/clones/llthw.common-lisp.dev/1-02-19-pretty-printing.html new file mode 100644 index 00000000..16533aa1 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-02-19-pretty-printing.html @@ -0,0 +1,1846 @@ + + + + + + + Pretty-Printing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                            +
                                                            + + + + + + + + +
                                                            + +
                                                            + +
                                                            + + + + + + + + +
                                                            +
                                                            + +
                                                            +
                                                            + +
                                                            + +

                                                            Exercise 1.2.19

                                                            +

                                                            Pretty Printing

                                                            +

                                                            You may or may not have noticed already that Lisp has a way to print Lisp code, formatted in such a way that it's more straightforward to read. By default, whenever possible the pretty-printer outputs the code all on one line; if there's no room left in the default margins, then it breaks the code up into multiple lines.

                                                            +

                                                            To see the pretty-printer in action, I'll be showing you some pretty ugly code. Normally you would never write Lisp this way---but it shows you how Lisp can take badly formatted code and give you something better.

                                                            +

                                                            In this case, type out this example all on one line in the REPL before you hit Return/Enter.

                                                            +
                                                            (pprint '(defun monkey (a b c) "a monkey function" (let ((d 4) (e 5) (f 6)) (values (list a b c) (list d e f)))))
                                                            +
                                                            +

                                                            What You Should See

                                                            +
                                                            * (pprint '(defun monkey (a b c) "a monkey function" (let ((d 4) (e 5) (f 6)) (values (list a b c) (list d e f)))))
                                                            +(DEFUN MONKEY (A B C)
                                                            +  "a monkey function"
                                                            +  (LET ((D 4) (E 5) (F 6))
                                                            +    (VALUES (LIST A B C) (LIST D E F))))
                                                            +NIL
                                                            +
                                                            +

                                                            Remember how I introduced "quoting" in the Common Lisp Bootcamp chapter? It turns Lisp code into data, so the function definition above is never evaluated by Lisp. It's read, but not eval'd. Otherwise, don't worry too much about the function definition for now. It's just illustrative, to show how the pretty printer splits up a long line into multiple lines.

                                                            +

                                                            Now, if you didn't quote the above function definition, it would be evaluated, and then you'd actually be pretty-printing the return value of the function instead of the code. Not very useful in this case---but say you wanted to pretty-print the result of a loop that collects a whole lot of data? It would be useful then.

                                                            +

                                                            Lisp's Pretty Printing facilities are pretty complex, and that's to say nothing of pretty-printing with format. Throughout this book, you'll see more ways to take advantage of the Pretty Printer along the way. But that's all for Chapter 1.2!

                                                            + + +
                                                            + +
                                                            +
                                                            +
                                                            + +

                                                            results matching ""

                                                            +
                                                              + +
                                                              +
                                                              + +

                                                              No results matching ""

                                                              + +
                                                              +
                                                              +
                                                              + +
                                                              +
                                                              + +
                                                              + + + + + + + + + + + + + + +
                                                              + + +
                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-03-0-getting-input-from-users.html b/clones/llthw.common-lisp.dev/1-03-0-getting-input-from-users.html new file mode 100644 index 00000000..bf006692 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-03-0-getting-input-from-users.html @@ -0,0 +1,2028 @@ + + + + + + + Extra Credit: Getting Input from Users ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                              +
                                                              + + + + + + + + +
                                                              + +
                                                              + +
                                                              + + + + + + + + +
                                                              +
                                                              + +
                                                              +
                                                              + +
                                                              + +

                                                              Chapter 1.3 --- Extra Credit

                                                              +

                                                              Getting Input From Users

                                                              +
                                                              +

                                                              "Never worry about theory as long as the machinery does what it's supposed to do."

                                                              +
                                                              Robert A. Heinlein, Waldo & Magic, Inc.
                                                              + +
                                                              +

                                                              Often, as a programmer you'll need to handle unpredictable user input. You have no way of knowing what a user might try to enter when you give them a prompt or a form, whether because of unfamiliarity with the system, ignorance of some arbitrary convention, or in the worst case, malicious intent. Not all programs need a way to handle data entry or text commands---but when your program does, it's important to consider in advance how you will validate all user input before it is parsed, read, evaluated, or stored by Lisp---because as a programmer you have made certain assumptions about how your program will be used, and both your users and future-you will thank you for validating input and handling issues in a sensible and interactive way that can be easily understood.

                                                              +

                                                              Lisp has some particularly powerful tools for handling all these possibilities. You can even give your users a complete Lisp REPL that allow them to live-hack your application for customizability---but it could also allow them to easily break everything. Given a few best practices, however, you can implement a validated, sandboxed shell; prevent SQL injection attacks; and more.

                                                              +

                                                              We won't be going over every aspect of this task here, but this Extra Credit chapter should be enough to get you thinking about validating every possible interaction a user might have with your program, to keep it secure and stable.

                                                              +

                                                              This Chapter will contain exercises on:

                                                              +
                                                                +
                                                              • READ
                                                              • +
                                                              • EVAL
                                                              • +
                                                              • Sequences
                                                              • +
                                                              • Concatenation
                                                              • +
                                                              • Splitting
                                                              • +
                                                              • Replacing
                                                              • +
                                                              • Parsing Numbers
                                                              • +
                                                              • Custom Prompts
                                                              • +
                                                              +

                                                              Exercise 1.3.1

                                                              +

                                                              READ: an introduction to the Lisp Reader

                                                              +

                                                              The read procedure can read from a stream

                                                              +
                                                              * (read)
                                                              +
                                                              +

                                                              ...

                                                              +

                                                              Nothing actually happens until you type something else.

                                                              +
                                                              * (read)
                                                              +test ;; this is the thing I type when read blocks
                                                              +TEST
                                                              +
                                                              +* (read)
                                                              +12345
                                                              +12345
                                                              +
                                                              +* (read)
                                                              +"A string"
                                                              +"A string"
                                                              +
                                                              +

                                                              Since read invokes the Lisp reader, any comments you type in its input are ignored. It reads an s-expression, not a line. So you can do things like

                                                              +
                                                              * (read)
                                                              +"This is a
                                                              +multiline string"
                                                              +"This is a
                                                              +multiline string"
                                                              +
                                                              +* (read)
                                                              +(list 1 2
                                                              +      3 4
                                                              +      5 6)
                                                              +(LIST 1 2 3 4 5 6)
                                                              +
                                                              +

                                                              As you can see by that call to list, an expression read this way is not evaluated. Which is why you can still see the symbol list at the front of the List read returns.

                                                              +
                                                              * (read)
                                                              +(+ 2 3)
                                                              +(+ 2 3)
                                                              +
                                                              +* (read)
                                                              +(defun foo ()
                                                              +  (+ a b))
                                                              +(DEFUN FOO () (+ A B))
                                                              +
                                                              +* (read)
                                                              +(loop (format t "Fun!~%"))
                                                              +(LOOP (FORMAT T "Fun!~%"))
                                                              +
                                                              +

                                                              Exercise 1.3.2

                                                              +

                                                              EVAL: an introduction to the Lisp Evaluator

                                                              +

                                                              In order to evaluate something you read, you need to use eval. Some forms are self-evaluating (that is, they return themselves when evaluated).

                                                              +
                                                              * (eval (read)) ;; NEVER DO THIS IN A REAL PROGRAM
                                                              +12345
                                                              +12345
                                                              +
                                                              +* (eval (read))
                                                              +"A string"
                                                              +"A string"
                                                              +
                                                              +

                                                              Some don't.

                                                              +
                                                              * (eval (read))
                                                              +test
                                                              +  The variable TEST is unbound.
                                                              +     [Condition of type UNBOUND-VARIABLE]
                                                              +
                                                              +* (eval (read))
                                                              +(+ 2 3)
                                                              +5
                                                              +
                                                              +* (eval (read))
                                                              +(defun foo ()
                                                              +  (+ a b))
                                                              +
                                                              +; in: DEFUN FOO
                                                              +;     (+ A B)
                                                              +;
                                                              +; caught WARNING:
                                                              +;   undefined variable: A
                                                              +;
                                                              +; caught WARNING:
                                                              +;   undefined variable: B
                                                              +;
                                                              +; compilation unit finished
                                                              +;   Undefined variables:
                                                              +;     A B
                                                              +;   caught 2 WARNING conditions
                                                              +FOO
                                                              +
                                                              +

                                                              We're not going to try to call that foo we just defined because, as you can see by the compilation warnings, we don't have values for a and b anywhere (and we're not covering dynamic scope until later).

                                                              +

                                                              Hopefully you noticed the NEVER DO THIS... comment up top. It's because of things like

                                                              +
                                                              * (eval (read))
                                                              +(loop (format t "Fun!~%"))
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +Fun!
                                                              +... ;; FOREVER (until you kill the process with an interrupt)
                                                              +
                                                              +

                                                              Exercise 1.3.3

                                                              +

                                                              Sequences

                                                              +

                                                              If you have an existing buffer you want to destructively read into, you can use read-sequence.

                                                              +
                                                              * (let ((dest (make-list 5)))
                                                              +    (read-sequence dest *standard-input*)
                                                              +    dest)
                                                              +abcde
                                                              +(#\a #\b #\c #\d #\e)
                                                              +
                                                              +

                                                              This procedure won't read more input than can fit into the buffer you specify.

                                                              +
                                                              * (let ((dest (make-list 3)))
                                                              +    (read-sequence dest *standard-input*)
                                                              +    dest)
                                                              +abcdefghi
                                                              +(#\a #\b #\c)
                                                              +
                                                              +* (let ((dest (list)))
                                                              +    (read-sequence dest *standard-input*)
                                                              +    dest)
                                                              +NIL
                                                              +
                                                              +

                                                              Note that it doesn't even wait for input when given a zero-length buffer. It will also keep reading until the buffer is filled...

                                                              +
                                                              * (defparameter *buf* (make-list 7))
                                                              +*BUF*
                                                              +
                                                              +* (read-sequence *buf* *standard-input*)
                                                              +one
                                                              +two
                                                              +7
                                                              +
                                                              +* *buf*
                                                              +(#\o #\n #\e #\Newline #\t #\w #\o)
                                                              +
                                                              +

                                                              or until some sort of break occurs.

                                                              +
                                                              * (read-sequence *buf* *standard-input*)
                                                              +abc
                                                              +User Interrupt
                                                              +   [Condition of type SIMPLE-ERROR]
                                                              +
                                                              +* *buf*
                                                              +(#\a #\b #\c #\Newline #\t #\w #\o)
                                                              +
                                                              +

                                                              As you can see from the above examples, the return value of read-sequence is the number of stream elements it consumed, and it really is a destructive update on the specified buffer.

                                                              +

                                                              The buffer can be of any sequence type, rather than just a list.

                                                              +
                                                              * (let ((dest (make-string 5)))
                                                              +    (read-sequence dest *standard-input*)
                                                              +    dest)
                                                              +abcdef
                                                              +"abcde"
                                                              +
                                                              +* (let ((dest (make-array '(5))))
                                                              +    (read-sequence dest *standard-input*)
                                                              +    dest)
                                                              +abcdef
                                                              +#(#\a #\b #\c #\d #\e)
                                                              +
                                                              +

                                                              Exercise 1.3.4

                                                              +

                                                              More Sequences

                                                              +

                                                              Exercise 1.3.5

                                                              +

                                                              Sequence Operations

                                                              +

                                                              Exercise 1.3.6

                                                              +

                                                              Concatenation

                                                              +

                                                              Exercise 1.3.7

                                                              +

                                                              Splitting

                                                              +

                                                              Exercise 1.3.8

                                                              +

                                                              Replacing

                                                              +

                                                              Exercise 1.3.9

                                                              +

                                                              Numbers

                                                              +

                                                              Exercise 1.3.10

                                                              +

                                                              Input and Output Streams

                                                              +

                                                              Exercise 1.3.11

                                                              +

                                                              Simple Prompts

                                                              +

                                                              Exercise 1.3.12

                                                              +

                                                              Custom Prompts

                                                              +

                                                              Exercise 1.3.13

                                                              +

                                                              Handling Input from Custom Prompts

                                                              + + +
                                                              + +
                                                              +
                                                              +
                                                              + +

                                                              results matching ""

                                                              +
                                                                + +
                                                                +
                                                                + +

                                                                No results matching ""

                                                                + +
                                                                +
                                                                +
                                                                + +
                                                                +
                                                                + +
                                                                + + + + + + + + + + + + + + +
                                                                + + +
                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-04-0-lists.html b/clones/llthw.common-lisp.dev/1-04-0-lists.html new file mode 100644 index 00000000..a0f778f6 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-04-0-lists.html @@ -0,0 +1,2363 @@ + + + + + + + Lists and List-Operations ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                +
                                                                + + + + + + + + +
                                                                + +
                                                                + +
                                                                + + + + + + + + +
                                                                +
                                                                + +
                                                                +
                                                                + +
                                                                + +

                                                                Chapter 1.4

                                                                +

                                                                Lists and List Operations

                                                                +
                                                                +

                                                                "While the laws of statistics tell you how unlikely a particular coincidence is, they state just as firmly that coincidences do happen."

                                                                +
                                                                Robert A. Heinlein, The Door Into Summer
                                                                + +
                                                                +

                                                                In the spirit of Lambda Calculus and a pure functional heritage, the Lisp-family of programming languages gets its name from its purpose---LISt Processing. Even though Common Lisp is not a purely-functional programming language, its fundamental syntax has not deviated from this heritage; as you should remember from Chapter 1.1, Cons-Cells are one of two essential forms of Expressions in Lisp, and they are represented using List syntax; and since the other---Atoms---are, by definition, self-evaluating, everything interesting that you can do in Lisp is effectively a List operation. And these are divided into consing and non-consing operations.

                                                                +

                                                                This is important to remember---it's the reason there are so many parentheses in Lisp source-code. Every form surrounded by parentheses is a list. The only difference between code and data, syntactically speaking, is that code is read and evaluated whereas data is only read; you can switch to "data mode" by quoting an expression, but quoting isn't a free pass. Lisp still expects to be able to Read the forms you've quoted as valid forms, so the syntax is just as important to data as it is to code.

                                                                +

                                                                This is also the key to Lisp's homoiconicity---the same syntax is used to represent both Code and Data, and as a result you can treat Code as Data, and Data as Code. As far as Lisp is concerned, there is no difference between the two.

                                                                +

                                                                But Lists are also a proper type in Common Lisp, that descends from sequences. We have already seen some sequence operations on other data types, like Strings, and will explore them further. However, in this chapter, we will focus on Lists as a proper data type and Consing operations on these Lists.

                                                                +
                                                                  +
                                                                • Consing and Cons-Cells
                                                                • +
                                                                • The LIST Function
                                                                • +
                                                                • CAR and CDR
                                                                • +
                                                                • FIRST, REST, and LAST
                                                                • +
                                                                • PUSH and POP
                                                                • +
                                                                • List Position
                                                                • +
                                                                • APPEND
                                                                • +
                                                                • Quoting
                                                                • +
                                                                • Circular Lists
                                                                • +
                                                                • Circular Trees
                                                                • +
                                                                +

                                                                Exercise 1.4.1

                                                                +

                                                                Cons-Cells

                                                                +

                                                                Cons-Cells are the smallest compound data structure in Lisp. A Cons-Cell is effectively a pair of pointers. You can tell if what you're looking at is a Cons-Cell by using the predicate consp.

                                                                +
                                                                * (consp 5)
                                                                +NIL
                                                                +
                                                                +* (consp "a")
                                                                +NIL
                                                                +
                                                                +* (consp 'a)
                                                                +NIL
                                                                +
                                                                +* (consp (cons 'a 'b))
                                                                +T
                                                                +
                                                                +

                                                                Exercise 1.4.2

                                                                +

                                                                Consing

                                                                +

                                                                One way to create a Cons-Cell is using the cons function.

                                                                +
                                                                * (cons 'a 'b)
                                                                +(A . B)
                                                                +
                                                                +

                                                                They can hold any type of data, not just symbols.

                                                                +
                                                                * (cons 1 2)
                                                                +(1 . 2)
                                                                +
                                                                +* (cons "one" "two")
                                                                +("one" . "two")
                                                                +
                                                                +

                                                                Exercise 1.4.3

                                                                +

                                                                Dot-Notation

                                                                +

                                                                You can see that when we cons two atoms together, we get back a Dotted Pair. This is a readable representation of Cons-Cells. That is, you can use it directly, rather than calling cons.

                                                                +
                                                                * (cons 'a 'b)
                                                                +(A . B)
                                                                +
                                                                +* '(a . b)
                                                                +(A . B)
                                                                +
                                                                +

                                                                These two representations are equivalent.

                                                                +
                                                                * (equal (cons 'a 'b) '(a . b))
                                                                +T
                                                                +
                                                                +

                                                                Exercise 1.4.4

                                                                +

                                                                More Consing

                                                                +

                                                                Cons-Cells need not contain homogenous data.

                                                                +
                                                                * (cons 'a 2)
                                                                +(A . 2)
                                                                +
                                                                +* (cons 1 "two")
                                                                +(1 . "two")
                                                                +
                                                                +* (cons "a" 'b)
                                                                +("a" . B)
                                                                +
                                                                +

                                                                Exercise 1.4.5

                                                                +

                                                                CAR and CDR

                                                                +

                                                                Using Cons-Cells as building blocks would be kind of pointless if we couldn't get their components back out. To get the value of the first slot in a Cons-Cell, we use the car function.

                                                                +
                                                                * (cons 'a 'b)
                                                                +(A . B)
                                                                +
                                                                +* (car (cons 'a 'b))
                                                                +A
                                                                +
                                                                +

                                                                Similarly, we can get the value from the second slot in a Cons-Cell using cdr.

                                                                +
                                                                * (cons 1 2)
                                                                +(1 . 2)
                                                                +
                                                                +* (cdr (cons 1 2))
                                                                +2
                                                                +
                                                                +

                                                                Exercise 1.4.6

                                                                +

                                                                More CAR and CDR

                                                                +

                                                                cons, car and cdr are purely functional. Which means they never mutate their arguments.

                                                                +
                                                                * (defvar *a* (cons 1 2))
                                                                +*A*
                                                                +
                                                                +* *a*
                                                                +(1 . 2)
                                                                +
                                                                +* (cdr *a*)
                                                                +2
                                                                +
                                                                +* *a*
                                                                +(1 . 2)
                                                                +
                                                                +* (cons 3 (cdr *a*))
                                                                +(3 . 2)
                                                                +
                                                                +* *a*
                                                                +(1 . 2)
                                                                +
                                                                +

                                                                It is an error to use car and cdr on something other than a Cons-Cell.

                                                                +
                                                                * (car 1)
                                                                +; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: 1>
                                                                +
                                                                +* (cdr 'a)
                                                                +; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: A>.
                                                                +
                                                                +

                                                                This includes other compound values such as strings and vectors

                                                                +
                                                                * (car "a")
                                                                +; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: "a">.
                                                                +
                                                                +* (cdr #(1 2))
                                                                +; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: #<(SIMPLE-VECTOR 2) {1007D4C76F}>>.
                                                                +
                                                                +

                                                                but not the empty list, also represented as NIL

                                                                +
                                                                * (car nil)
                                                                +NIL
                                                                +
                                                                +* (cdr nil)
                                                                +NIL
                                                                +
                                                                +* (car ())
                                                                +NIL
                                                                +
                                                                +* (cdr ())
                                                                +NIL
                                                                +
                                                                +

                                                                Exercise 1.4.7

                                                                +

                                                                Lists

                                                                +

                                                                A list is either the empty list, or a chain of Cons-Cells ending with the empty list.

                                                                +
                                                                * (listp nil)
                                                                +T
                                                                +
                                                                +* (listp (cons 5 nil))
                                                                +T
                                                                +
                                                                +

                                                                If you cons something onto the empty list, you get the list of that thing.

                                                                +
                                                                * (cons 5 nil)
                                                                +(5)
                                                                +
                                                                +

                                                                We can exploit the Cons-Cells' ability to contain heterogenous data in order to represent linked lists or trees.

                                                                +
                                                                * (cons 3 (cons 2 (cons 1 nil)))
                                                                +(3 2 1)
                                                                +
                                                                +

                                                                Exercise 1.4.8

                                                                +

                                                                More Lists

                                                                +

                                                                Another way to create lists is using the list function.

                                                                +
                                                                * (list 3 2 1)
                                                                +(3 2 1)
                                                                +
                                                                +

                                                                The expression (list a b ...) is effectively shorthand for the expression (cons a (cons b ...)), with the final value being consed onto NIL.

                                                                +
                                                                * (list 1 2 3)
                                                                +(1 2 3)
                                                                +
                                                                +* (cons 1 (cons 2 (cons 3 nil)))
                                                                +(1 2 3)
                                                                +
                                                                +* (equal (list 1 2 3) (cons 1 (cons 2 (cons 3 nil))))
                                                                +T
                                                                +
                                                                +

                                                                As with cons, it's possible to build up trees, rather than merely lists, using list.

                                                                +
                                                                * (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8)))
                                                                +(1 (2 3) (4 ((5) 6 7 8)))
                                                                +
                                                                +

                                                                Exercise 1.4.9

                                                                +

                                                                Even More CAR and CDR

                                                                +

                                                                Because car and cdr are purely functional, and return their target value, it's possible to chain them in order to look into nested structures.

                                                                +
                                                                * (cons (cons 1 2) 3)
                                                                +((1 . 2) . 3)
                                                                +
                                                                +* (car (car (cons (cons 1 2) 3)))
                                                                +1
                                                                +
                                                                +

                                                                This also applies to deeply nested lists.

                                                                +
                                                                * (defparameter *tree* (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8))))
                                                                +*tree*
                                                                +
                                                                +* *tree*
                                                                +(1 (2 3) (4 ((5) 6 7 8)))
                                                                +
                                                                +* (car (cdr (car (cdr *tree*))))
                                                                +3
                                                                +
                                                                +

                                                                This is common enough that Lisp supports shorthand for such tree selections.

                                                                +
                                                                * (car *tree*)
                                                                +1
                                                                +
                                                                +* (cadr *tree*)
                                                                +
                                                                +(2 3)
                                                                +
                                                                +* (cadadr *tree*)
                                                                +3
                                                                +
                                                                +* (cddr *tree*)
                                                                +((4 ((5) 6 7 8)))
                                                                +
                                                                +* (cdddr *tree*)
                                                                +NIL
                                                                +
                                                                +

                                                                They're actual functions though. Not a reader syntax based on the number of as and d s between the c and r. So, for instance:

                                                                +
                                                                * (caddadddaaar *tree*)
                                                                +   The function COMMON-LISP-USER::CADDADDDAAAR is undefined.
                                                                +      [Condition of type UNDEFINED-FUNCTION]
                                                                +
                                                                +

                                                                Exercise 1.4.10

                                                                +

                                                                Push and Pop

                                                                +

                                                                We mentioned before that cons, car, cdr and friends are purely functional. But, sometimes, you want to destructively modify a list you've defined. For instance, in order to implement a mutable stack. In order to destructively cons elements onto a list, use push.

                                                                +
                                                                * (defvar *stack* nil)
                                                                +*stack*
                                                                +
                                                                +* (push 1 *stack*)
                                                                +(1)
                                                                +
                                                                +* *stack*
                                                                +(1)
                                                                +
                                                                +* (push 2 *stack*)
                                                                +(2 1)
                                                                +
                                                                +* (push 3 *stack*)
                                                                +(3 2 1)
                                                                +
                                                                +* *stack*
                                                                +(3 2 1)
                                                                +
                                                                +

                                                                Exercise 1.4.11

                                                                +

                                                                Pop

                                                                +

                                                                The other half of the a stack involves destructively removing the first element from it. This can be done with pop.

                                                                +
                                                                * *stack*
                                                                +(3 2 1)
                                                                +
                                                                +* (pop *stack*)
                                                                +3
                                                                +
                                                                +* *stack*
                                                                +(2 1)
                                                                +
                                                                +* (pop *stack*)
                                                                +2
                                                                +
                                                                +* (pop *stack*)
                                                                +1
                                                                +
                                                                +* *stack*
                                                                +NIL
                                                                +
                                                                +

                                                                Calling pop on an empty list has no effect.

                                                                +
                                                                * *stack*
                                                                +NIL
                                                                +
                                                                +* (pop *stack*)
                                                                +NIL
                                                                +
                                                                +* *stack*
                                                                +NIL
                                                                +
                                                                +

                                                                Exercise 1.4.12

                                                                +

                                                                More Push and Pop

                                                                +

                                                                Like cons, push isn't limited to the existing type of its target.

                                                                +
                                                                * *stack*
                                                                +NIL
                                                                +
                                                                +* (push 1 *stack*)
                                                                +(1)
                                                                +
                                                                +* (push "b" *stack*)
                                                                +("b" 1)
                                                                +
                                                                +* (push 'c *stack*)
                                                                +(c "b" 1)
                                                                +
                                                                +* (push (list 4 5) *stack*)
                                                                +((4 5) C "a" 1)
                                                                +
                                                                +* *stack*
                                                                +((4 5) C "a" 1)
                                                                +
                                                                +

                                                                Exercise 1.4.13

                                                                +

                                                                First, Rest, and Last

                                                                +

                                                                In addition to car and cdr, it's also possible to manipulate Cons-Cells using the first and rest functions. They're just different names for the same functions. first is the same as car

                                                                +
                                                                * (cons 'a 'b)
                                                                +(A . B)
                                                                +
                                                                +* (car (cons 'a 'b))
                                                                +A
                                                                +
                                                                +* (first (cons 'a 'b))
                                                                +A
                                                                +
                                                                +

                                                                and rest is the same as cdr

                                                                +
                                                                * (cons 1 2)
                                                                +(1 . 2)
                                                                +
                                                                +* (cdr (cons 1 2))
                                                                +2
                                                                +
                                                                +* (rest (cons 1 2))
                                                                +2
                                                                +
                                                                +

                                                                A third function, last, lets you get at the last Cons-Cell in a particular series.

                                                                +
                                                                * (last (cons 1 (cons 2 (cons 3 nil))))
                                                                +(3)
                                                                +
                                                                +* (last (cons 1 2))
                                                                +(1 . 2)
                                                                +
                                                                +* (last (list 3 4 5))
                                                                +(5)
                                                                +
                                                                +

                                                                Exercise 1.4.14

                                                                +

                                                                List Position

                                                                +

                                                                When dealing with linked lists, if you want to get at a particular element somewhere in the middle, you could either chain some cars and cdrs.

                                                                +
                                                                * (car (cdr (cdr (cdr (list 0 1 2 3 4 5)))))
                                                                +3
                                                                +
                                                                +* (cadddr (list 0 1 2 3 4 5))
                                                                +3
                                                                +
                                                                +

                                                                or you could use the nth function.

                                                                +
                                                                * (nth 3 (list 0 1 2 3 4 5))
                                                                +3
                                                                +
                                                                +* (nth 4 (list 0 1 2 3 4 5))
                                                                +4
                                                                +
                                                                +* (nth 5 (list 5 4 3 2 1 0))
                                                                +0
                                                                +
                                                                +

                                                                This isn't any more efficient (in the run-time sense) than cdr traversal, but is shorter to write if you need to access some deeper list element in a flat list.

                                                                +

                                                                Exercise 1.4.15

                                                                +

                                                                Appending

                                                                +

                                                                Putting lists together is the job of the append function.

                                                                +
                                                                * (append (list 1 2 3) (list 4 5 6))
                                                                +(1 2 3 4 5 6)
                                                                +
                                                                +* (append (list 6 5 4 3) (list 2 1))
                                                                +(6 5 4 3 2 1)
                                                                +
                                                                +

                                                                append is an example of a function that takes a &rest argument. Meaning you can pass it any number of lists...

                                                                +
                                                                * (append (list 'a 'b 'c 'd) (list 'e 'f) (list 'g))
                                                                +(A B C D E F G)
                                                                +
                                                                +* (append (list 1) (list 2) (list 3) (list 4))
                                                                +(1 2 3 4)
                                                                +
                                                                +

                                                                ...though passing it one list is pointless.

                                                                +
                                                                * (append (list 1 2 3))
                                                                +(1 2 3)
                                                                +
                                                                +* (list 1 2 3)
                                                                +(1 2 3)
                                                                +
                                                                +

                                                                Exercise 1.4.16

                                                                +

                                                                More Appending

                                                                +

                                                                Like car, cdr, first, rest, last and nth, append is functional. It will return a new list rather than mutating any of its arguments.

                                                                +
                                                                * (defvar *lst* (list 1 2 3 4 5))
                                                                +*lst*
                                                                +
                                                                +* *lst*
                                                                +(1 2 3 4 5)
                                                                +
                                                                +* (append *lst* (list 6 7 8))
                                                                +(1 2 3 4 5 6 7 8)
                                                                +
                                                                +* *lst*
                                                                +(1 2 3 4 5)
                                                                +
                                                                +* (append (list -3 -2 -1 0) *lst*)
                                                                +(-3 -2 -1 0 1 2 3 4 5)
                                                                +
                                                                +* *lst*
                                                                +(1 2 3 4 5)
                                                                +
                                                                +* (append (list 0) *lst* (list 6))
                                                                +(0 1 2 3 4 5 6)
                                                                +
                                                                +* *lst*
                                                                +(1 2 3 4 5)
                                                                +
                                                                +

                                                                This means both that you may safely pass it any data you want appended without worrying about losing the original lists, and that if you want such behavior, you need to explicitly assign the result of append yourself.

                                                                +

                                                                Exercise 1.4.17

                                                                +

                                                                Circular Lists

                                                                +

                                                                The destructive equivalent of append is nconc. Using such side-effects, it's possible to create circular lists.

                                                                +
                                                                * (defparameter *cycle* (list 'a 'b))
                                                                +*CYCLE*
                                                                +
                                                                +* (first *cycle*)
                                                                +A
                                                                +
                                                                +* (second *cycle*)
                                                                +B
                                                                +
                                                                +* (third *cycle*)
                                                                +NIL
                                                                +
                                                                +* (fourth *cycle*)
                                                                +NIL
                                                                +
                                                                +

                                                                Before we create an actual cycle, we need to tell the interpreter to print them (otherwise the request to print a circular list would never return; unlike Haskell, Common Lisp is not a lazy language by default).

                                                                +
                                                                * (setf *print-circle* t)
                                                                +T
                                                                +
                                                                +* (nconc *cycle* *cycle*)
                                                                +#1=(A B . #1#)
                                                                +
                                                                +* (third *cycle*)
                                                                +A
                                                                +
                                                                +* (fourth *cycle*)
                                                                +B
                                                                +
                                                                +* (loop repeat 15 for elem in *cycle* collect elem)
                                                                +(A B A B A B A B A B A B A B A)
                                                                +
                                                                +

                                                                Exercise 1.4.18

                                                                +

                                                                Circular Trees

                                                                +

                                                                The nconc procedure is fine when all you want is a simple cycle, but it's also possible to use direct mutation to create more elaborate structures.

                                                                +
                                                                * (defparameter *knot* (list 1 2 3 4 (cons nil nil)))
                                                                +*KNOT*
                                                                +
                                                                +* (setf (car (nth 4 *knot*)) (cdr *knot*))
                                                                +#1=(1 2 3 4 (#1#))
                                                                +
                                                                +* (setf (cdr (nth 4 *knot*)) (cddr *knot*))
                                                                +#1=(3 4 ((1 2 . #1#) . #1#))
                                                                +
                                                                +

                                                                Now we've got a structure that branches back on itself twice.

                                                                +
                                                                * (defun cycle-walk (count cycle &key (turn #'car))
                                                                +    (loop with place = cycle
                                                                +          repeat count for elem = (car place)
                                                                +          unless (consp elem) do (format t "~a " elem)
                                                                +          do (setf place (if (consp elem)
                                                                +                             (funcall turn elem)
                                                                +                             (cdr place)))))
                                                                +CYCLE-WALK
                                                                +
                                                                +* (cycle-walk 25 *knot* :turn #'car)
                                                                +1 2 3 4 2 3 4 2 3 4 2 3 4 2 3 4 2 3 4
                                                                +NIL
                                                                +
                                                                +* (cycle-walk 25 *knot* :turn #'cdr)
                                                                +1 2 3 4 3 4 3 4 3 4 3 4 3 4 3 4 3 4
                                                                +NIL
                                                                +
                                                                +* (let ((dir))
                                                                +    (defun switch (pair)
                                                                +      (setf dir (not dir))
                                                                +      (if dir
                                                                +          (car pair)
                                                                +          (cdr pair))))
                                                                +SWITCH
                                                                +
                                                                +* (cycle-walk 25 *knot* :turn #'switch)
                                                                +1 2 3 4 3 4 2 3 4 3 4 2 3 4 3 4 2 3 4
                                                                +NIL
                                                                +
                                                                +

                                                                Of course, it's possible to go further. Large, divergent "trees" that eventually cycle backwards from any number of branches at arbitrary depths. You'd build them the same way though; using some combination of nconc, setf along with car/cdr and friends.

                                                                +

                                                                Exercise 1.4.19

                                                                +

                                                                Quoting

                                                                +

                                                                Another way to construct tree structure is using the quote or '.

                                                                +
                                                                * (quote (1 2 3))
                                                                +(1 2 3)
                                                                +
                                                                +* '(1 2 3)
                                                                +(1 2 3)
                                                                +
                                                                +* (list 1 2 3)
                                                                +(1 2 3)
                                                                +
                                                                +

                                                                The structures you create this way are equivalent.

                                                                +
                                                                * (equal (quote (1 2 3)) '(1 2 3))
                                                                +T
                                                                +
                                                                +* (equal '(1 2 3) (list 1 2 3))
                                                                +T
                                                                +
                                                                +

                                                                The difference is that, while list essentially means "Return the list of these arguments", quote/' means "Return this argument without evaluating it".

                                                                +
                                                                * (defparameter *test* 2)
                                                                +*test*
                                                                +
                                                                +* (list 1 *test* 3)
                                                                +(1 2 3)
                                                                +
                                                                +* '(1 *test* 3)
                                                                +(1 *test* 3)
                                                                +
                                                                +* (list (+ 3 4) (+ 5 6) (+ 7 8))
                                                                +(7 11 15)
                                                                +
                                                                +* '((+ 3 4) (+ 5 6) (+ 7 8))
                                                                +((+ 3 4) (+ 5 6) (+ 7 8))
                                                                +
                                                                +

                                                                Exercise 1.4.20

                                                                +

                                                                More Quoting

                                                                +

                                                                Because quote supresses evaluation, you can use it to more easily build deeply nested structures.

                                                                +
                                                                * (list 1 (list 2 3) (list 4 (list (list 5) 6 7 8)))
                                                                +(1 (2 3) (4 ((5) 6 7 8)))
                                                                +
                                                                +* '(1 (2 3) (4 ((5) 6 7 8)))
                                                                +(1 (2 3) (4 ((5) 6 7 8)))
                                                                +
                                                                +

                                                                Take care not to use quoted data for mutation though. While the structures produced may be the same, mutating a quoted structure is undefined by the Common Lisp language spec, and is thus entirely implementation dependant.

                                                                +
                                                                * (defvar *listed* (list 3 2 1))
                                                                +*listed*
                                                                +
                                                                +* (defvar *quoted* '(3 2 1))
                                                                +*quoted*
                                                                +
                                                                +* (push 4 *listed*)
                                                                +(4 3 2 1)
                                                                +
                                                                +* *listed*
                                                                +(4 3 2 1)
                                                                +
                                                                +* (push 4 *quoted*)
                                                                +???
                                                                +
                                                                +* *quoted*
                                                                +???
                                                                +
                                                                +

                                                                The question marks aren't there so you can figure out what the results are supposed to be. They signify that what you get back in these situations depends on which implementation of Common Lisp you're using. They may do incompatible things, but because the spec leaves this situation undefined, none of them are actually wrong. So, you know ... careful.

                                                                + + +
                                                                + +
                                                                +
                                                                +
                                                                + +

                                                                results matching ""

                                                                +
                                                                  + +
                                                                  +
                                                                  + +

                                                                  No results matching ""

                                                                  + +
                                                                  +
                                                                  +
                                                                  + +
                                                                  +
                                                                  + +
                                                                  + + + + + + + + + + + + + + +
                                                                  + + +
                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-05-0-lookups-trees.html b/clones/llthw.common-lisp.dev/1-05-0-lookups-trees.html new file mode 100644 index 00000000..afa38096 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-05-0-lookups-trees.html @@ -0,0 +1,2814 @@ + + + + + + + Extra Credit: Look-up Lists and Trees ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                  +
                                                                  + + + + + + + + +
                                                                  + +
                                                                  + +
                                                                  + + + + + + + + +
                                                                  +
                                                                  + +
                                                                  +
                                                                  + +
                                                                  + +

                                                                  Chapter 1.5 --- Extra Credit

                                                                  +

                                                                  Look-up Lists and Trees

                                                                  +
                                                                  +

                                                                  "Take sides! Always take sides! You will sometimes be wrong—but the man who refuses to take sides must always be wrong."

                                                                  +
                                                                  Robert A. Heinlein, Double Star
                                                                  + +
                                                                  +

                                                                  In addition to the typical lists you saw throughout the exercises of the previous chapter, Lisp also has a couple special types of look-up lists that have more structure than just position. They are called Association Lists and Property Lists, or alists and plists for short. They are typically used for data and not code, because they both consist of key--value pairs; but this is Lisp, after all, so there are packages where these special data lists are repurposed as code, and later on you'll see how to do similar things yourself if you ever need or want to.

                                                                  +

                                                                  If you have never come across the concept of key--value pair data structures before, they are straightforward to use and understand---all they do is assign a value you specify to a keyword, so that you can add them to a list and get the value back later by name instead of having to remember where in the list you put the value. They are the basis for all structured data, including types such as Hash Tables, Structs, Classes, Database Tables, and more, all of which we'll be covering in this book.

                                                                  +

                                                                  This chapter will contain exercises on:

                                                                  +
                                                                    +
                                                                  • Examples of ALISTS and PLISTS
                                                                  • +
                                                                  • Creating PLISTS
                                                                  • +
                                                                  • Adding items to PLISTS
                                                                  • +
                                                                  • Changing values in PLISTS
                                                                  • +
                                                                  • Removing items from PLISTS
                                                                  • +
                                                                  • Creating ALISTS
                                                                  • +
                                                                  • Adding items to ALISTS
                                                                  • +
                                                                  • Removing items from ALISTS
                                                                  • +
                                                                  • Practical size-constraints for ALISTS and PLISTS, alternate data types to look out for.
                                                                  • +
                                                                  • Trees
                                                                  • +
                                                                  • More Trees
                                                                  • +
                                                                  • Tries
                                                                  • +
                                                                  • More Tries
                                                                  • +
                                                                  • Why Can't I Hold All These Tries?
                                                                  • +
                                                                  • Object Reference
                                                                  • +
                                                                  • Acyclic Graphs
                                                                  • +
                                                                  +

                                                                  Exercise 1.5.1

                                                                  +

                                                                  Lookups: ALISTs and PLISTs

                                                                  +

                                                                  alists and plists are two basic ways of representing linear-lookup key--value structures. An alist is a list of cons cells

                                                                  +
                                                                  * '((a . 1) (b . 2) (c . 3))
                                                                  +((A . 1) (B . 2) (C . 3))
                                                                  +
                                                                  +

                                                                  while a plist is a flat list of expressions, whose every odd element is a key and every even element is a value.

                                                                  +
                                                                  * (list 'a 1 'b 2 'c 3)
                                                                  +(A 1 B 2 C 3)
                                                                  +
                                                                  +

                                                                  Both constructs are of type list.

                                                                  +
                                                                  * (listp '((a . 1) (b . 2) (c . 3)))
                                                                  +T
                                                                  +
                                                                  +* (listp (list 'a 1 'b 2 'c 3))
                                                                  +T
                                                                  +
                                                                  +

                                                                  Which is a double-edged blessing; any general list-processing function can transparently take alists or plists as arguments, but it's not easy to tell whether a particular construct is a plain list or a plist/alist (and there are cases where you want to treat them differently).

                                                                  +

                                                                  Exercise 1.5.2

                                                                  +

                                                                  PLISTs

                                                                  +

                                                                  A plist is just a flat list with an even number of elements. Each odd element is taken to be the key of the immediately following element.

                                                                  +
                                                                  * (list 'a 1 'b 2)
                                                                  +(A 1 B 2)
                                                                  +
                                                                  +* (list :foo "a" :bar "b")
                                                                  +(:FOO "a" :BAR "b")
                                                                  +
                                                                  +

                                                                  Calling the function getf on a plist and a key will try to find that key in the plist. If it is found, the return value will be that keys' value.

                                                                  +
                                                                  * (getf (list :foo "a" :bar "b") :bar)
                                                                  +"b"
                                                                  +
                                                                  +* (getf (list :foo "a" :bar "b") :foo)
                                                                  +"a"
                                                                  +
                                                                  +

                                                                  The getf function also takes an optional argument, default, which it will return if the given key is not found in the given plist. The default default is NIL.

                                                                  +
                                                                  * (getf (list :foo "a" :bar "b") :mumble)
                                                                  +NIL
                                                                  +
                                                                  +* (getf (list :foo "a" :bar "b") :mumble 'great-googly-moogly)
                                                                  +GREAT-GOOGLY-MOOGLY
                                                                  +
                                                                  +

                                                                  Trying this on an odd-length list might give you an error, even if you specify a default value.

                                                                  +
                                                                  * (getf (list :foo "a" :bar "b" :baz) :foo)
                                                                  +"a"
                                                                  +
                                                                  +* (getf (list :foo "a" :bar "b" :baz) :mumble)
                                                                  +
                                                                  +  malformed property list: (:FOO "a" :BAR "b" :BAZ).
                                                                  +     [Condition of type SIMPLE-TYPE-ERROR]
                                                                  +
                                                                  +* (getf (list :foo "a" :bar "b" :baz) :mumble 'tralala)
                                                                  +
                                                                  +  malformed property list: (:FOO "a" :BAR "b" :BAZ).
                                                                  +     [Condition of type SIMPLE-TYPE-ERROR]
                                                                  +
                                                                  +

                                                                  Exercise 1.5.3

                                                                  +

                                                                  More PLISTs

                                                                  +

                                                                  Like all Cons-Cells, a plist can be heterogenously typed. That is, you can put many different types of things in it.

                                                                  +
                                                                  * (list :a 1 :b 'two :c "three")
                                                                  +(:A 1 :B TWO :C "three")
                                                                  +
                                                                  +* (getf (list :a 1 :b 'two :c "three") :b)
                                                                  +TWO
                                                                  +
                                                                  +* (getf (list :a 1 :b 'two :c "three") :c)
                                                                  +"three"
                                                                  +
                                                                  +

                                                                  This goes for the keys, as well as the values.

                                                                  +
                                                                  * (list 1 :a 'two :b "three" :c)
                                                                  +(1 :A TWO :B "three" :C)
                                                                  +
                                                                  +* (getf (list 1 :a 'two :b "three" :c) 1)
                                                                  +:A
                                                                  +
                                                                  +* (getf (list 1 :a 'two :b "three" :c) 'two)
                                                                  +:B
                                                                  +
                                                                  +

                                                                  However, be careful. getf tests its keys by pointer equality, and there's no way to specify otherwise. Which means that you can't really use compound structures as keys in a plist.

                                                                  +
                                                                  * (getf (list 1 :a 'two :b "three" :c) "three")
                                                                  +NIL
                                                                  +
                                                                  +

                                                                  Because it's a flat list, you can add keys to an existing plist using cons or append.

                                                                  +
                                                                  * (list :a 1 :b 2 :c 3)
                                                                  +(:A 1 :B 2 :C 3)
                                                                  +
                                                                  +* (let ((plist (list :a 1 :b 2 :c 3)))
                                                                  +    (cons :d (cons 4 plist)))
                                                                  +(:D 4 :A 1 :B 2 :C 3)
                                                                  +
                                                                  +* (let ((plist (list :a 1 :b 2 :c 3)))
                                                                  +    (cons :d (cons 4 plist))
                                                                  +    plist)
                                                                  +(:A 1 :B 2 :C 3)
                                                                  +
                                                                  +* (let ((plist (list :a 1 :b 2 :c 3)))
                                                                  +    (append (list :d 4 :e 5) plist))
                                                                  +(:D 4 :E 5 :A 1 :B 2 :C 3)
                                                                  +
                                                                  +* (let ((plist (list :a 1 :b 2 :c 3)))
                                                                  +    (append (list :d 4 :e 5) plist)
                                                                  +    plist)
                                                                  +(:A 1 :B 2 :C 3)
                                                                  +
                                                                  +

                                                                  Exercise 1.5.4

                                                                  +

                                                                  Even More PLISTs

                                                                  +

                                                                  Its possible to mutate plists, as most other values, by using setf.

                                                                  +
                                                                  * (defparameter *plist* (list :a 1 :b 'two :c "three"))
                                                                  +*PLIST*
                                                                  +
                                                                  +* (getf *plist* :b)
                                                                  +TWO
                                                                  +
                                                                  +* (setf (getf *plist* :b) 'three)
                                                                  +THREE
                                                                  +
                                                                  +* (getf *plist* :b)
                                                                  +THREE
                                                                  +
                                                                  +* *plist*
                                                                  +(:A 1 :B THREE :C "three")
                                                                  +
                                                                  +

                                                                  The key you set this way doesn't need to exist already.

                                                                  +
                                                                  * (setf (getf *plist* :d) 71)
                                                                  +71
                                                                  +
                                                                  +* (getf *plist* :d)
                                                                  +71
                                                                  +
                                                                  +

                                                                  but the order of new keys may surprise you.

                                                                  +
                                                                  * *plist*
                                                                  +(:D 71 :A 1 :B THREE :C "three")
                                                                  +
                                                                  +

                                                                  In order to remove keys from a plist, you'd have to remove the desired key and its related value. The destructive procedure remf does exactly that.

                                                                  +
                                                                  * (remf *plist* :b)
                                                                  +T
                                                                  +
                                                                  +* *plist*
                                                                  +(:D 71 :A 1 :C "three")
                                                                  +
                                                                  +

                                                                  Exercise 1.5.5

                                                                  +

                                                                  ALISTs

                                                                  +

                                                                  An alist is a list of Cons-Cells. The first element of each Cons-Cell is taken to be the key, while the rest is taken to be the value.

                                                                  +
                                                                  * '((a . 1) (b . 2) (c . 3))
                                                                  +((A . 1) (B . 2) (C . 3))
                                                                  +
                                                                  +* (list (cons :foo "a") (cons :bar "b"))
                                                                  +((:FOO . "a") (:BAR . "b"))
                                                                  +
                                                                  +

                                                                  Calling the function assoc on a key and an alist will try to find that key in the alist. If it is found, the return value will be the whole Cons-Cell in question.

                                                                  +
                                                                  * (assoc 'b '((a . 1) (b . 2) (c . 3)))
                                                                  +(B . 2)
                                                                  +
                                                                  +* (assoc 'a '((a . 1) (b . 2) (c . 3)))
                                                                  +(A . 1)
                                                                  +
                                                                  +

                                                                  Trying this on a malformed alists may yield errors, though they won't be quite as specific as the ones thrown for malformed plists.

                                                                  +
                                                                  * (assoc 'a '((a . 1) (b . 2) c))
                                                                  +(A . 1)
                                                                  +
                                                                  +* (assoc 'c '((a . 1) (b . 2) c))
                                                                  +
                                                                  +  The value C is not of type LIST.
                                                                  +     [Condition of type TYPE-ERROR]
                                                                  +
                                                                  +

                                                                  Specifically, that error refers to that trailing c in our alist. This is because assoc compares the given key with the car of each element in the given list. If a particular element is not a list (or cons), you can't take its car, which means the selector will error.

                                                                  +

                                                                  Exercise 1.5.6

                                                                  +

                                                                  More ALISTs

                                                                  +

                                                                  As with plists, alists may be heterogenously typed.

                                                                  +
                                                                  * '((a . 1) (b . "two") (c . three) (d . #(#\f #\o #\u #\r)))
                                                                  +((A . 1) (B . "two") (C . THREE) (D . #(#\f #\o #\u #\r)))
                                                                  +
                                                                  +* (assoc 'b '((a . 1) (b . "two") (c . three) (d . #(#\f #\o #\u #\r))))
                                                                  +(B . "two")
                                                                  +
                                                                  +* (assoc 'd '((a . 1) (b . "two") (c . three) (d . #(#\f #\o #\u #\r))))
                                                                  +(D . #(#\f #\o #\u #\r))
                                                                  +
                                                                  +

                                                                  and this again applies to both keys and values.

                                                                  +
                                                                  * '((1 . a) ("two" . b) (three . c) (#(#\f #\o #\u #\r) . d))
                                                                  +((1 . A) ("two" . B) (THREE . C) (#(#\f #\o #\u #\r) . D))
                                                                  +
                                                                  +* (assoc 'three '((1 . a) ("two" . b) (three . c) (#(#\f #\o #\u #\r) . d)))
                                                                  +(THREE . C)
                                                                  +
                                                                  +* (assoc 1 '((1 . a) ("two" . b) (three . c) (#(#\f #\o #\u #\r) . d)))
                                                                  +(1 . A)
                                                                  +
                                                                  +

                                                                  Unlike with plists, compound keys might be useful. Because assoc accepts a test (or test-not) argument, which lets you specify the test to run when determining key equality.

                                                                  +
                                                                  * (assoc "two" '((1 . a) ("two" . b) (three . c) (#(#\f #\o #\u #\r) . d)) :test #'equal)
                                                                  +("two" . B)
                                                                  +
                                                                  +* (assoc #(#\f #\o #\u #\r) '((1 . a) ("two" . b) (three . c) (#(#\f #\o #\u #\r) . d)) :test #'equalp)
                                                                  +(#(#\f #\o #\u #\r) . D)
                                                                  +
                                                                  +

                                                                  Because alists are lists of cons cells, you can use cons to functionally insert items

                                                                  +
                                                                  * '((a . 1) (b . "two") (c . three))
                                                                  +((A . 1) (B . "two") (C . THREE))
                                                                  +
                                                                  +* (let ((alist '((a . 1) (b . "two") (c . three))))
                                                                  +    (cons (cons 'd 'four) alist))
                                                                  +((D . FOUR) (A . 1) (B . "two") (C . THREE))
                                                                  +
                                                                  +* (let ((alist '((a . 1) (b . "two") (c . three))))
                                                                  +    (cons (cons 'd 'four) alist)
                                                                  +    alist)
                                                                  +((A . 1) (B . "two") (C . THREE))
                                                                  +
                                                                  +

                                                                  Similarly, you can use the standard remove/remove-if functions on alists transparently.

                                                                  +
                                                                  * (remove 'b '((a . 1) (b . "two") (c . three)) :key #'car)
                                                                  +((A . 1) (C . THREE))
                                                                  +
                                                                  +* (remove-if (lambda (p) (eq 'c (car p))) '((a . 1) (b . "two") (c . three)))
                                                                  +((A . 1) (B . "two"))
                                                                  +
                                                                  +* (remove-if
                                                                  +    (lambda (pair)
                                                                  +      (numberp (car pair)))
                                                                  +    '((a . 1) (1 . a) (b . "two") (2 . b) (c . three)))
                                                                  +((A . 1) (B . "two") (C . THREE))
                                                                  +
                                                                  +

                                                                  Exercise 1.5.7

                                                                  +

                                                                  Even More ALISTs

                                                                  +

                                                                  You can mutate alists, just as you can mutate almost everything else.

                                                                  +
                                                                  * (defparameter *alist* '((a . 1) (b . 2) (c . 3)))
                                                                  +*ALIST*
                                                                  +
                                                                  +* (setf (cdr (assoc 'b *alist*)) 42)
                                                                  +42
                                                                  +
                                                                  +* *alist*
                                                                  +((A . 1) (B . 42) (C . 3))
                                                                  +
                                                                  +

                                                                  Though, unlike with plists, the key you're mutating must already exist.

                                                                  +
                                                                  * (setf (cdr (assoc 'foo *alist*)) 43)
                                                                  +
                                                                  +  The value NIL is not of type CONS.
                                                                  +     [Condition of type TYPE-ERROR]
                                                                  +
                                                                  +

                                                                  It is possible to add keys to an alist, but you need to be more explicit about it.

                                                                  +
                                                                  * (push '(foo . 43) *alist*)
                                                                  +((FOO . 43) (A . 1) (B . 42) (C . 3))
                                                                  +
                                                                  +* *alist*
                                                                  +((FOO . 43) (A . 1) (B . 42) (C . 3))
                                                                  +
                                                                  +

                                                                  You can also remove keys using setf and the functional approaches we discussed in the previous section.

                                                                  +
                                                                  * (setf *alist* (remove 'b *alist* :key #'car))
                                                                  +((FOO . 43) (A . 1) (C . 3))
                                                                  +
                                                                  +* *alist*
                                                                  +((FOO . 43) (A . 1) (C . 3))
                                                                  +
                                                                  +

                                                                  Exercise 1.5.8

                                                                  +

                                                                  Efficiency, and Alternatives to ALISTs and PLISTs

                                                                  +

                                                                  We mentioned earlier that the alist and plist were both representation of linear-lookup key--value structures. This is because they both work naively. That is, doing a lookup entails traversing the entire structure and comparing each key in turn until one matches the key we're looking for...

                                                                  +
                                                                  * (trace eq)
                                                                  +(EQ)
                                                                  +
                                                                  +* (assoc 'b '((a . 1) (b . 2) (c . 3) (d . 4)) :test #'eq)
                                                                  +  0: (EQ B A)
                                                                  +  0: EQ returned NIL
                                                                  +  0: (EQ B B)
                                                                  +  0: EQ returned T
                                                                  +(B . 2)
                                                                  +
                                                                  +* (assoc 'd '((a . 1) (b . 2) (c . 3) (d . 4)) :test #'eq)
                                                                  +  0: (EQ D A)
                                                                  +  0: EQ returned NIL
                                                                  +  0: (EQ D B)
                                                                  +  0: EQ returned NIL
                                                                  +  0: (EQ D C)
                                                                  +  0: EQ returned NIL
                                                                  +  0: (EQ D D)
                                                                  +  0: EQ returned T
                                                                  +(D . 4)
                                                                  +
                                                                  +

                                                                  ... or until we reach the end of the list.

                                                                  +
                                                                  * (assoc 'foo '((a . 1) (b . 2) (c . 3) (d . 4)) :test #'eq)
                                                                  +  0: (EQ FOO A)
                                                                  +  0: EQ returned NIL
                                                                  +  0: (EQ FOO B)
                                                                  +  0: EQ returned NIL
                                                                  +  0: (EQ FOO C)
                                                                  +  0: EQ returned NIL
                                                                  +  0: (EQ FOO D)
                                                                  +  0: EQ returned NIL
                                                                  +NIL
                                                                  +
                                                                  +* (untrace eq)
                                                                  +T
                                                                  +
                                                                  +

                                                                  This is often Good Enough, but there are times when you care about lookup performance, and might be willing to sacrifice simplicity of implementation. No, we're not implementing hash-tables. They're already provided as part of the language (though that won't stop us later). Lets take a look at some tree structures.

                                                                  +

                                                                  Exercise 1.5.9

                                                                  +

                                                                  Trees

                                                                  +

                                                                  If we pick keys so that we can sort them instead of merely comparing them for equality, we could use a tree structure rather than a plain list. Though we do need to do a bit more work. A tree is typically recursively defined as either

                                                                  +
                                                                    +
                                                                  1. A value followed by two trees (a left branch and a right branch)
                                                                  2. +
                                                                  3. The terminal value (which marks the end of our tree)
                                                                  4. +
                                                                  +

                                                                  Which we can represent as things like

                                                                  +
                                                                  * '((1 . a) nil nil)
                                                                  +((1 . A) NIL NIL)
                                                                  +
                                                                  +* '((2 . b) ((1 . a) nil nil) ((3 . c) nil ((4 . d) nil nil)))
                                                                  +((2 . B) ((1 . A) NIL NIL) ((3 . C) NIL ((4 . D) NIL NIL)))
                                                                  +
                                                                  +

                                                                  This is not the only possible tree representation, nor necessarily the best. We'll reserve others for later on. You can see that our "value" is a key--value pair in the style of an alist and our terminal value is NIL. Also, note that our keys are sorted. That is, everything in the left branch of a particular tree has a lesser key than the "value" of that tree, while everything in the right branch has a greater key. This is the property that will let us do faster lookups. Ideally, it will let us cut half of the remaining search space out with each comparison.

                                                                  +

                                                                  Here's lookup:

                                                                  +
                                                                  * (defun lookup (key sorted-tree)
                                                                  +    (let ((k (caar sorted-tree)))
                                                                  +      (cond ((null sorted-tree) nil)
                                                                  +        ((> k key)
                                                                  +         (lookup key (second sorted-tree)))
                                                                  +        ((< k key)
                                                                  +         (lookup key (third sorted-tree)))
                                                                  +        (t
                                                                  +         (first sorted-tree)))))
                                                                  +LOOKUP
                                                                  +
                                                                  +* (trace lookup)
                                                                  +(LOOKUP)
                                                                  +
                                                                  +* (lookup 4 '((2 . b) ((1 . a) nil nil) ((3 . c) nil ((4 . d) nil nil))))
                                                                  +  0: (LOOKUP 4 ((2 . B) ((1 . A) NIL NIL) ((3 . C) NIL ((4 . D) NIL NIL))))
                                                                  +    1: (LOOKUP 4 ((3 . C) NIL ((4 . D) NIL NIL)))
                                                                  +      2: (LOOKUP 4 ((4 . D) NIL NIL))
                                                                  +      2: LOOKUP returned (4 . D)
                                                                  +    1: LOOKUP returned (4 . D)
                                                                  +  0: LOOKUP returned (4 . D)
                                                                  +(4 . D)
                                                                  +
                                                                  +

                                                                  Notice that we don't compare against all of the preceding elements in order to get to ours. We only compare against 3. A tree of four key--value pairs isn't the best demonstration of this, of course.

                                                                  +

                                                                  Exercise 1.5.10

                                                                  +

                                                                  More Trees

                                                                  +

                                                                  Since we're doing more work on trees, we may as well go SICP-style and define the functional interface.

                                                                  +
                                                                  * (defun tree (val left right)
                                                                  +    (list val left right))
                                                                  +TREE
                                                                  +
                                                                  +* (defun tree-value (tree) (first tree))
                                                                  +TREE-VALUE
                                                                  +
                                                                  +* (defun tree-left (tree) (second tree))
                                                                  +TREE-LEFT
                                                                  +
                                                                  +* (defun tree-right (tree) (third tree))
                                                                  +TREE-RIGHT
                                                                  +
                                                                  +* (defun lookup (key tree)
                                                                  +    (if (null tree)
                                                                  +        nil
                                                                  +        (let ((k (car (tree-value tree))))
                                                                  +          (cond ((> k key) (lookup key (tree-left tree)))
                                                                  +                ((< k key) (lookup key (tree-right tree)))
                                                                  +                (t (tree-value tree))))))
                                                                  +; STYLE-WARNING: redefining COMMON-LISP-USER::LOOKUP in DEFUN
                                                                  +LOOKUP
                                                                  +
                                                                  +

                                                                  Now that we have that, a naive insert looks like

                                                                  +
                                                                  * (defun insert (key value tree)
                                                                  +    (if (null tree)
                                                                  +        (tree (cons key value) nil nil)
                                                                  +        (let ((k (car (tree-value tree))))
                                                                  +          (cond ((> k key)
                                                                  +                 (tree (tree-value tree)
                                                                  +                       (insert key value (tree-left tree))
                                                                  +                       (tree-right tree)))
                                                                  +                ((< k key)
                                                                  +                 (tree (tree-value tree)
                                                                  +                       (tree-left tree)
                                                                  +                       (insert key value (tree-right tree))))
                                                                  +                (t tree)))))
                                                                  +INSERT
                                                                  +
                                                                  +

                                                                  We can use that insert on this specially-ordered alist to give us a reasonably balanced tree.

                                                                  +
                                                                  * (defparameter *lst* '((5 . e) (3 . c) (4 . d) (2 . b) (1 . a) (7 . g) (6 . f) (8 . h) (9 . i) (10 . j)))
                                                                  +*LST*
                                                                  +
                                                                  +* (reduce
                                                                  +    (lambda (memo pair)
                                                                  +      (insert (car pair) (cdr pair) memo))
                                                                  +    *lst* :initial-value nil)
                                                                  +((5 . E) ((3 . C) ((2 . B) ((1 . A) NIL NIL) NIL) ((4 . D) NIL NIL))
                                                                  + ((7 . G) ((6 . F) NIL NIL) ((8 . H) NIL ((9 . I) NIL ((10 . J) NIL NIL)))))
                                                                  +
                                                                  +* (defparameter *tree*
                                                                  +    (reduce
                                                                  +     (lambda (memo pair)
                                                                  +       (insert (car pair) (cdr pair) memo))
                                                                  +     *lst* :initial-value nil))
                                                                  +
                                                                  +

                                                                  And, just so that we're comparing like-for-like, here's a recursive definition of assoc

                                                                  +
                                                                  * (defun rec-assoc (key alist)
                                                                  +    (cond ((null alist) nil)
                                                                  +          ((eq key (caar alist)) (car alist))
                                                                  +          (t (rec-assoc key (cdr alist)))))
                                                                  +REC-ASSOC
                                                                  +
                                                                  +

                                                                  Now, lets compare lookup steps involved.

                                                                  +
                                                                  * (trace lookup rec-assoc)
                                                                  +(LOOKUP REC-ASSOC)
                                                                  +
                                                                  +* (rec-assoc 9 *lst*)
                                                                  +  0: (REC-ASSOC 9
                                                                  +                ((5 . E) (3 . C) (4 . D) (2 . B) (1 . A) (7 . G) (6 . F)
                                                                  +                 (8 . H) (9 . I) (10 . J)))
                                                                  +    1: (REC-ASSOC 9
                                                                  +                  ((3 . C) (4 . D) (2 . B) (1 . A) (7 . G) (6 . F) (8 . H)
                                                                  +                   (9 . I) (10 . J)))
                                                                  +      2: (REC-ASSOC 9
                                                                  +                    ((4 . D) (2 . B) (1 . A) (7 . G) (6 . F) (8 . H) (9 . I)
                                                                  +                     (10 . J)))
                                                                  +        3: (REC-ASSOC 9
                                                                  +                      ((2 . B) (1 . A) (7 . G) (6 . F) (8 . H) (9 . I) (10 . J)))
                                                                  +          4: (REC-ASSOC 9 ((1 . A) (7 . G) (6 . F) (8 . H) (9 . I) (10 . J)))
                                                                  +            5: (REC-ASSOC 9 ((7 . G) (6 . F) (8 . H) (9 . I) (10 . J)))
                                                                  +              6: (REC-ASSOC 9 ((6 . F) (8 . H) (9 . I) (10 . J)))
                                                                  +                7: (REC-ASSOC 9 ((8 . H) (9 . I) (10 . J)))
                                                                  +                  8: (REC-ASSOC 9 ((9 . I) (10 . J)))
                                                                  +                  8: REC-ASSOC returned (9 . I)
                                                                  +                7: REC-ASSOC returned (9 . I)
                                                                  +              6: REC-ASSOC returned (9 . I)
                                                                  +            5: REC-ASSOC returned (9 . I)
                                                                  +          4: REC-ASSOC returned (9 . I)
                                                                  +        3: REC-ASSOC returned (9 . I)
                                                                  +      2: REC-ASSOC returned (9 . I)
                                                                  +    1: REC-ASSOC returned (9 . I)
                                                                  +  0: REC-ASSOC returned (9 . I)
                                                                  +(9 . I)
                                                                  +
                                                                  +* (lookup 9 *tree*)
                                                                  +  0: (LOOKUP 9
                                                                  +             ((5 . E)
                                                                  +              ((3 . C) ((2 . B) ((1 . A) NIL NIL) NIL) ((4 . D) NIL NIL))
                                                                  +              ((7 . G) ((6 . F) NIL NIL)
                                                                  +               ((8 . H) NIL ((9 . I) NIL ((10 . J) NIL NIL))))))
                                                                  +    1: (LOOKUP 9
                                                                  +               ((7 . G) ((6 . F) NIL NIL)
                                                                  +                ((8 . H) NIL ((9 . I) NIL ((10 . J) NIL NIL)))))
                                                                  +      2: (LOOKUP 9 ((8 . H) NIL ((9 . I) NIL ((10 . J) NIL NIL))))
                                                                  +        3: (LOOKUP 9 ((9 . I) NIL ((10 . J) NIL NIL)))
                                                                  +        3: LOOKUP returned (9 . I)
                                                                  +      2: LOOKUP returned (9 . I)
                                                                  +    1: LOOKUP returned (9 . I)
                                                                  +  0: LOOKUP returned (9 . I)
                                                                  +(9 . I)
                                                                  +
                                                                  +* (untrace lookup rec-assoc)
                                                                  +T
                                                                  +
                                                                  +

                                                                  The tree structure saves us a bit of work in a situation like this. And, if we can arrange for our lookup tree to be balanced or almost balanced, we'll save more work the bigger our data-set becomes.

                                                                  +

                                                                  Exercise 1.5.11

                                                                  +

                                                                  Tries

                                                                  +

                                                                  If we can pick keys so that they're not merely sortable, but also decomposable, we can save a bit more time and space by using Tries (As an aside, "Tree" and "Trie" are pronounced the same way. This is doubly annoying because, as you'll see in a moment, a Trie is a kind of Tree. So you can't even disambiguate by saying things like "Trie, the data structure". You'll sometimes hear Tries referred to as "Prefix trees", which may or may not help the situation).

                                                                  +

                                                                  A Trie is a value and a (possibly empty) dictionary of key parts to Tries. Which can be represented as:

                                                                  +
                                                                  * '(nil nil)
                                                                  +(NIL NIL)
                                                                  +
                                                                  +* '(nil ((#\o nil ((#\n "activated; not off" ((#\e "the english name for the numeral 1" NIL)))))))
                                                                  +(NIL
                                                                  + ((#\o NIL
                                                                  +   ((#\n "activated; not off"
                                                                  +     ((#\e "the english name for the numeral 1")))))))
                                                                  +
                                                                  +* '(nil ((1 nil ((2 nil ((3 "ah ah ah." nil)))))))
                                                                  +(NIL ((1 NIL ((2 NIL ((3 "ah ah ah." NIL)))))))
                                                                  +
                                                                  +* '(nil
                                                                  +    ((this nil
                                                                  +      ((sentence nil
                                                                  +        ((is nil
                                                                  +          ((a nil ((key "This sentence is a key" nil)))
                                                                  +           (not nil ((a nil ((key "This sentence is NOT a key" nil)))))
                                                                  +           (meaningless t nil)))))))))
                                                                  +(NIL
                                                                  + ((THIS NIL
                                                                  +   ((SENTENCE NIL
                                                                  +     ((IS NIL
                                                                  +       ((A NIL ((KEY "This sentence is a key" NIL)))
                                                                  +        (NOT NIL ((A NIL ((KEY "This sentence is NOT a key" NIL)))))
                                                                  +        (MEANINGLESS T NIL)))))))))
                                                                  +
                                                                  +

                                                                  Looking up a key in a Trie means taking the decomposed key, and looking up each key part level-wise.

                                                                  +
                                                                  * (defun trie-lookup (key-parts trie)
                                                                  +    (if (null key-parts)
                                                                  +        (first trie)
                                                                  +        (let ((next (cdr (assoc (car key-parts) (second trie)))))
                                                                  +          (when next
                                                                  +            (trie-lookup (cdr key-parts) next)))))
                                                                  +TRIE-LOOKUP
                                                                  +
                                                                  +* (defparameter *trie*
                                                                  +    '(nil ((#\o nil ((#\n "activated; not off" ((#\e "the english name for the numeral 1" NIL))))))))
                                                                  +*TRIE*
                                                                  +
                                                                  +* (trie-lookup '(#\o #\n) *trie*)
                                                                  +"activated; not off"
                                                                  +
                                                                  +* (trie-lookup '(#\o #\n #\e) *trie*)
                                                                  +"the english name for the numeral 1"
                                                                  +
                                                                  +* (trie-lookup '(#\o #\n #\e #\i #\r #\o #\s) *trie*)
                                                                  +NIL
                                                                  +
                                                                  +* (trie-lookup '(#\t #\w #\o) *trie*)
                                                                  +NIL
                                                                  +
                                                                  +

                                                                  The idea here is that any common prefixes among keys are collapsed, and that some extra data about a particular sequence is held as the value. The best casefor a lookup is a key that shares no prefix with anything in the Trie. The worst case is a key that shares a long prefix, since we need to traverse the entire prefix before discovering the absence.

                                                                  +

                                                                  Exercise 1.5.12

                                                                  +

                                                                  More Tries

                                                                  +

                                                                  So lets go explicit-interface-style on this problem.

                                                                  +
                                                                  * (defun trie (val map)
                                                                  +    (list val map))
                                                                  +TRIE
                                                                  +
                                                                  +* (defun empty-trie ()
                                                                  +    (trie nil nil))
                                                                  +EMPTY-TRIE
                                                                  +
                                                                  +* (empty-trie)
                                                                  +(NIL NIL)
                                                                  +
                                                                  +* (defun trie-value (trie)
                                                                  +    (first trie))
                                                                  +TRIE-VALUE
                                                                  +
                                                                  +* (defun trie-table (trie)
                                                                  +    (second trie))
                                                                  +TRIE-TABLE
                                                                  +
                                                                  +* (defun trie-assoc (key-part trie)
                                                                  +    (cdr (assoc key-part (trie-table trie))))
                                                                  +TRIE-ASSOC
                                                                  +
                                                                  +* (defun trie-lookup (key-parts trie)
                                                                  +    (if (null key-parts)
                                                                  +        (trie-value trie)
                                                                  +        (let ((next (trie-assoc (first key-parts) trie)))
                                                                  +          (when next
                                                                  +            (trie-lookup (rest key-parts) next)))))
                                                                  +
                                                                  +

                                                                  Those are the basic getters. And nothing really fancy has been said yet. You can see why I'd leave them out for the initial pass based on their trivial nature. Insertion is less trivial to implement, but still conceptually simple.

                                                                  +
                                                                  * (defun trie-alist-insert (k trie alist)
                                                                  +    (cons (cons k trie)
                                                                  +          (remove k alist :key #'car)))
                                                                  +TRIE-ALIST-INSERT
                                                                  +
                                                                  +* (defun trie-insert (key value trie)
                                                                  +    (if key
                                                                  +        (let* ((k (first key))
                                                                  +               (next (trie-assoc k trie)))
                                                                  +          (trie (trie-value trie)
                                                                  +                (trie-alist-insert
                                                                  +                 k
                                                                  +                 (trie-insert
                                                                  +                  (rest key) value
                                                                  +                  (or next (trie nil nil)))
                                                                  +                 (trie-table trie))))
                                                                  +        (trie value (trie-table trie))))
                                                                  +TRIE-INSERT
                                                                  +
                                                                  +* (trie-insert (coerce "once" 'list) "one time, and one time only" *trie*)
                                                                  +(NIL
                                                                  + ((#\o NIL
                                                                  +   ((#\n "activated; not off"
                                                                  +     ((#\c NIL ((#\e "one time, and one time only" NIL)))
                                                                  +      (#\e "the english name for the numeral 1" NIL)))))))
                                                                  +
                                                                  +

                                                                  In order to insert a new value, associated with a particular key, we traverse that keys' parts and either recur to the next level of the trie by looking up the current part, or freshly insert that part into the current trie table. If we run out of key to traverse, we insert the new value, replacing an existing one if necessary.

                                                                  +
                                                                  * *trie*
                                                                  +(NIL
                                                                  + ((#\o NIL
                                                                  +   ((#\n "activated; not off"
                                                                  +     ((#\e "the english name for the numeral 1" NIL)))))))
                                                                  +
                                                                  +* (trie-insert (coerce "on" 'list) "switched on" *trie*)
                                                                  +(NIL
                                                                  + ((#\o NIL
                                                                  +   ((#\n "switched on"
                                                                  +     ((#\e "the english name for the numeral 1" NIL)))))))
                                                                  +
                                                                  +

                                                                  Though of course, as always, we're not doing this replacement destructively.

                                                                  +
                                                                  * *trie*
                                                                  +(NIL
                                                                  + ((#\o NIL
                                                                  +   ((#\n "activated; not off"
                                                                  +     ((#\e "the english name for the numeral 1" NIL)))))))
                                                                  +
                                                                  +

                                                                  Now, lets do the same comparison we did earlier in the Trees section.

                                                                  +
                                                                  * (defun rec-string-assoc (key alist)
                                                                  +    (cond ((null alist) nil)
                                                                  +          ((string= key (caar alist)) (car alist))
                                                                  +          (t (rec-string-assoc key (cdr alist)))))
                                                                  +
                                                                  +* (defparameter *alist*
                                                                  +    '(("p" . "the 16th letter of the English alphabet")
                                                                  +      ("pea" . "the small spherical seed or the seed-pod of the pod fruit Pisum sativum")
                                                                  +      ("peanut" . "a plant species in the legume family")
                                                                  +      ("peanuts" . "plural of peanut; syndicated comic strip started in 1950")
                                                                  +      ("peanut butter" . "a creamy delight commonly used in sandwiches")
                                                                  +      ("on" . "activated; not off")
                                                                  +      ("one" . "the English name for the numeral 1")
                                                                  +      ("ones" . "plural of 'one'")
                                                                  +      ("once" . "one time, and one time only")))
                                                                  +
                                                                  +* (defparameter *trie*
                                                                  +    (reduce
                                                                  +     (lambda (memo pair)
                                                                  +       (trie-insert
                                                                  +        (coerce (car pair) 'list)
                                                                  +        (cdr pair)
                                                                  +        memo))
                                                                  +     *alist* :initial-value (empty-trie)))
                                                                  +*TRIE*
                                                                  +
                                                                  +* (trace rec-string-assoc trie-lookup)
                                                                  +(REC-STRING-ASSOC TRIE-LOOKUP)
                                                                  +
                                                                  +* (trie-lookup (coerce "once" 'list) *trie*)
                                                                  +  0: (TRIE-LOOKUP (#\o #\n #\c #\e)
                                                                  +                  (NIL
                                                                  +                   ((#\o NIL
                                                                  +                     ((#\n "activated; not off"
                                                                  +                       ((#\c NIL ((#\e "one time, and one time only" NIL)))
                                                                  +                        (#\e "the English name for the numeral 1"
                                                                  +                         ((#\s "plural of 'one'" NIL)))))))
                                                                  +                    (#\p "the 16th letter of the English alphabet"
                                                                  +                     ((#\e NIL
                                                                  +                       ((#\a
                                                                  +                         "the small spherical seed or the seed-pod of the pod fruit Pisum sativum"
                                                                  +                         ((#\n NIL
                                                                  +                           ((#\u NIL
                                                                  +                             ((#\t "a plant species in the legume family"
                                                                  +                               ((#\  NIL
                                                                  +                                 ((#\b NIL
                                                                  +                                   ((#\u NIL
                                                                  +                                     ((#\t NIL
                                                                  +                                       ((#\t NIL
                                                                  +                                         ((#\e NIL
                                                                  +                                           ((#\r
                                                                  +                                             "a creamy delight commonly used in sandwiches"
                                                                  +                                             NIL)))))))))))))
                                                                  +                                (#\s
                                                                  +                                 "plural of peanut; syndicated comic strip started in 1950"
                                                                  +                                 NIL))))))))))))))))
                                                                  +    1: (TRIE-LOOKUP (#\n #\c #\e)
                                                                  +                    (NIL
                                                                  +                     ((#\n "activated; not off"
                                                                  +                       ((#\c NIL ((#\e "one time, and one time only" NIL)))
                                                                  +                        (#\e "the English name for the numeral 1"
                                                                  +                         ((#\s "plural of 'one'" NIL))))))))
                                                                  +      2: (TRIE-LOOKUP (#\c #\e)
                                                                  +                      ("activated; not off"
                                                                  +                       ((#\c NIL ((#\e "one time, and one time only" NIL)))
                                                                  +                        (#\e "the English name for the numeral 1"
                                                                  +                         ((#\s "plural of 'one'" NIL))))))
                                                                  +        3: (TRIE-LOOKUP (#\e) (NIL ((#\e "one time, and one time only" NIL))))
                                                                  +          4: (TRIE-LOOKUP NIL ("one time, and one time only" NIL))
                                                                  +          4: TRIE-LOOKUP returned "one time, and one time only"
                                                                  +        3: TRIE-LOOKUP returned "one time, and one time only"
                                                                  +      2: TRIE-LOOKUP returned "one time, and one time only"
                                                                  +    1: TRIE-LOOKUP returned "one time, and one time only"
                                                                  +  0: TRIE-LOOKUP returned "one time, and one time only"
                                                                  +"one time, and one time only"
                                                                  +
                                                                  +* (rec-string-assoc "once" *alist*)
                                                                  +  0: (REC-STRING-ASSOC "once"
                                                                  +                       (("p" . "the 16th letter of the English alphabet")
                                                                  +                        ("pea"
                                                                  +                         . "the small spherical seed or the seed-pod of the pod fruit Pisum sativum")
                                                                  +                        ("peanut" . "a plant species in the legume family")
                                                                  +                        ("peanuts"
                                                                  +                         . "plural of peanut; syndicated comic strip started in 1950")
                                                                  +                        ("peanut butter"
                                                                  +                         . "a creamy delight commonly used in sandwiches")
                                                                  +                        ("on" . "activated; not off")
                                                                  +                        ("one" . "the English name for the numeral 1")
                                                                  +                        ("ones" . "plural of 'one'")
                                                                  +                        ("once" . "one time, and one time only")))
                                                                  +    1: (REC-STRING-ASSOC "once"
                                                                  +                         (("pea"
                                                                  +                           . "the small spherical seed or the seed-pod of the pod fruit Pisum sativum")
                                                                  +                          ("peanut" . "a plant species in the legume family")
                                                                  +                          ("peanuts"
                                                                  +                           . "plural of peanut; syndicated comic strip started in 1950")
                                                                  +                          ("peanut butter"
                                                                  +                           . "a creamy delight commonly used in sandwiches")
                                                                  +                          ("on" . "activated; not off")
                                                                  +                          ("one" . "the English name for the numeral 1")
                                                                  +                          ("ones" . "plural of 'one'")
                                                                  +                          ("once" . "one time, and one time only")))
                                                                  +      2: (REC-STRING-ASSOC "once"
                                                                  +                           (("peanut" . "a plant species in the legume family")
                                                                  +                            ("peanuts"
                                                                  +                             . "plural of peanut; syndicated comic strip started in 1950")
                                                                  +                            ("peanut butter"
                                                                  +                             . "a creamy delight commonly used in sandwiches")
                                                                  +                            ("on" . "activated; not off")
                                                                  +                            ("one" . "the English name for the numeral 1")
                                                                  +                            ("ones" . "plural of 'one'")
                                                                  +                            ("once" . "one time, and one time only")))
                                                                  +        3: (REC-STRING-ASSOC "once"
                                                                  +                             (("peanuts"
                                                                  +                               . "plural of peanut; syndicated comic strip started in 1950")
                                                                  +                              ("peanut butter"
                                                                  +                               . "a creamy delight commonly used in sandwiches")
                                                                  +                              ("on" . "activated; not off")
                                                                  +                              ("one" . "the English name for the numeral 1")
                                                                  +                              ("ones" . "plural of 'one'")
                                                                  +                              ("once" . "one time, and one time only")))
                                                                  +          4: (REC-STRING-ASSOC "once"
                                                                  +                               (("peanut butter"
                                                                  +                                 . "a creamy delight commonly used in sandwiches")
                                                                  +                                ("on" . "activated; not off")
                                                                  +                                ("one" . "the English name for the numeral 1")
                                                                  +                                ("ones" . "plural of 'one'")
                                                                  +                                ("once" . "one time, and one time only")))
                                                                  +            5: (REC-STRING-ASSOC "once"
                                                                  +                                 (("on" . "activated; not off")
                                                                  +                                  ("one"
                                                                  +                                   . "the English name for the numeral 1")
                                                                  +                                  ("ones" . "plural of 'one'")
                                                                  +                                  ("once" . "one time, and one time only")))
                                                                  +              6: (REC-STRING-ASSOC "once"
                                                                  +                                   (("one"
                                                                  +                                     . "the English name for the numeral 1")
                                                                  +                                    ("ones" . "plural of 'one'")
                                                                  +                                    ("once" . "one time, and one time only")))
                                                                  +                7: (REC-STRING-ASSOC "once"
                                                                  +                                     (("ones" . "plural of 'one'")
                                                                  +                                      ("once" . "one time, and one time only")))
                                                                  +                  8: (REC-STRING-ASSOC "once"
                                                                  +                                       (("once"
                                                                  +                                         . "one time, and one time only")))
                                                                  +                  8: REC-STRING-ASSOC returned
                                                                  +                       ("once" . "one time, and one time only")
                                                                  +                7: REC-STRING-ASSOC returned
                                                                  +                     ("once" . "one time, and one time only")
                                                                  +              6: REC-STRING-ASSOC returned
                                                                  +                   ("once" . "one time, and one time only")
                                                                  +            5: REC-STRING-ASSOC returned
                                                                  +                 ("once" . "one time, and one time only")
                                                                  +          4: REC-STRING-ASSOC returned ("once" . "one time, and one time only")
                                                                  +        3: REC-STRING-ASSOC returned ("once" . "one time, and one time only")
                                                                  +      2: REC-STRING-ASSOC returned ("once" . "one time, and one time only")
                                                                  +    1: REC-STRING-ASSOC returned ("once" . "one time, and one time only")
                                                                  +  0: REC-STRING-ASSOC returned ("once" . "one time, and one time only")
                                                                  +("once" . "one time, and one time only")
                                                                  +
                                                                  +* (untrace rec-string-assoc trie-lookup)
                                                                  +T
                                                                  +

                                                                  As you can see, we've got a similar situation here. When using a Trie to store our keys, we can essentially ignore groups of values for the purposes of doing a lookup. Which lets us do lookups in much better than linear time.

                                                                  +

                                                                  Exercise 1.5.13

                                                                  +

                                                                  Even More Tries

                                                                  +

                                                                  Completely apart from basic lookup performance, which is good but not all-important, Tries let us compute completions fairly cheaply. In the definition of trie-lookup we've already seen, walking the trie is conflated with getting a particular value out...

                                                                  +
                                                                  (defun trie-lookup (key-parts trie)
                                                                  +  (if (null key-parts)
                                                                  +      (trie-value trie)
                                                                  +      (let ((next (trie-assoc (first key-parts) trie)))
                                                                  +    (when next
                                                                  +      (trie-lookup (rest key-parts) next)))))
                                                                  +
                                                                  +

                                                                  ...but it doesn't have to be.

                                                                  +
                                                                  * (defun trie-walk (key-parts trie)
                                                                  +    (if (null key-parts)
                                                                  +        trie
                                                                  +        (let ((next (trie-assoc (first key-parts) trie)))
                                                                  +          (when next
                                                                  +            (trie-walk (rest key-parts) next)))))
                                                                  +TRIE-WALK
                                                                  +
                                                                  +* (trie-walk (coerce "on" 'list) *trie*)
                                                                  +("activated; not off"
                                                                  + ((#\c NIL ((#\e "one time, and one time only" NIL)))
                                                                  +  (#\e "the English name for the numeral 1" ((#\s "plural of 'one'" NIL)))))
                                                                  +
                                                                  +* (defun trie-lookup (key-parts trie)
                                                                  +    (trie-value (trie-walk key-parts trie)))
                                                                  +TRIE-LOOKUP
                                                                  +
                                                                  +

                                                                  With a definition of trie-walk so decoupled, we can now do the pre-order traversal and come out with a list of contained keys that start with the components we pass in.

                                                                  +
                                                                  * (defun trie-completions (key-parts trie)
                                                                  +    (labels ((recur (path trie)
                                                                  +               (let ((rest (loop for (k . sub-trie) in (trie-table trie)
                                                                  +                              append (recur (append path (list k)) sub-trie)) ))
                                                                  +                 (if (trie-value trie)
                                                                  +                     (cons path rest)
                                                                  +                     rest))))
                                                                  +      (recur key-parts (trie-walk key-parts trie))))
                                                                  +TRIE-COMPLETIONS
                                                                  +
                                                                  +* (trie-completions (coerce "on" 'list) *trie*)
                                                                  +((#\o #\n) (#\o #\n #\c #\e) (#\o #\n #\e) (#\o #\n #\e #\s))
                                                                  +
                                                                  +

                                                                  There are a couple of other ways we can vary Trie implementations. Firstly, we can change the representation of our trie-map. In all of the above examples, they're alists, but that's not a requirement. It might be reasonable to make them hash-tables, or objects, or Trees, or even sub-Tries depending on our situation. Secondly, except for a few brief examples back in exercise 1.5.11, we've been dealing with Tries whose keys are strings and decompose into characters. Other options are possible; for example the top level might be a phrase that decomposes into words, or numbers that decompose into bits.

                                                                  +

                                                                  We won't be investigating any of the variations at the moment though; that might happen in later chapters.

                                                                  +

                                                                  Exercise 1.5.14

                                                                  +

                                                                  Hash Tables

                                                                  +

                                                                  Hash Tables are the standard constant-time lookup structure you're familiar with from other languages.

                                                                  +
                                                                  * (make-hash-table)
                                                                  +#<HASH-TABLE :TEST EQL :COUNT 0 {1003F59933}>
                                                                  +
                                                                  +

                                                                  Unlike the other table structures we've taken a look at, there isn't really a non-destructive way to interact with a Hash Table. If you want to insert keys, you mutate the argument. You could copy the table out manually and add your new key to the copy, but that makes insertion take linear time. And you still have to do it manually; you don't get it for free the way you might with a Trie or alist.

                                                                  +
                                                                  * (let ((hash (make-hash-table)))
                                                                  +    (setf (gethash 'a hash) 1
                                                                  +          (gethash 'b hash) 2
                                                                  +          (gethash 'c hash) 3)
                                                                  +    hash)
                                                                  +#<HASH-TABLE :TEST EQL :COUNT 3 {1004099983}>
                                                                  +
                                                                  +* (let ((hash (make-hash-table)))
                                                                  +    (setf (gethash 'a hash) 1
                                                                  +          (gethash 'b hash) 2
                                                                  +          (gethash 'c hash) 3)
                                                                  +    (gethash 'b hash))
                                                                  +2
                                                                  +T
                                                                  +
                                                                  +

                                                                  There's no functional way to remove keys from hash tables either, other than the mentioned table-copying approach. Removing a key mutates the argument.

                                                                  +
                                                                  * (let ((hash (make-hash-table)))
                                                                  +    (setf (gethash 'a hash) 1
                                                                  +          (gethash 'b hash) 2
                                                                  +          (gethash 'c hash) 3)
                                                                  +    (remhash 'b hash)
                                                                  +    hash)
                                                                  +#<HASH-TABLE :TEST EQL :COUNT 2 {100758CFB3}>
                                                                  +
                                                                  +

                                                                  There's a few different ways of iterating over a Hash Table, depending on specifically what you're up to. If you're looking to make some destructive changes, or maybe just print pairs, there's maphash.

                                                                  +
                                                                  * (let ((hash (make-hash-table)))
                                                                  +    (setf (gethash 'a hash) 1
                                                                  +          (gethash 'b hash) 2
                                                                  +          (gethash 'c hash) 3)
                                                                  +    (maphash (lambda (k v) (format t "~a -> ~a~%" k v)) hash))
                                                                  +A -> 1
                                                                  +B -> 2
                                                                  +C -> 3
                                                                  +NIL
                                                                  +
                                                                  +

                                                                  Note that maphash doesn't collect results, so you couldn't convert a Hash Table to an alist by calling it with cons.

                                                                  +
                                                                  * (let ((hash (make-hash-table)))
                                                                  +    (setf (gethash 'a hash) 1
                                                                  +          (gethash 'b hash) 2
                                                                  +          (gethash 'c hash) 3)
                                                                  +    (maphash #'cons hash))
                                                                  +NIL
                                                                  +
                                                                  +

                                                                  If you wanted that, you'd either need to use some functions from alexandria, or a specific piece of loop)...

                                                                  +
                                                                  * (let ((hash (make-hash-table)))
                                                                  +    (setf (gethash 'a hash) 1
                                                                  +          (gethash 'b hash) 2
                                                                  +          (gethash 'c hash) 3)
                                                                  +    (loop for k being the hash-keys of hash
                                                                  +       for v being the hash-values of hash
                                                                  +       collect (cons k v)))
                                                                  +((A . 1) (B . 2) (C . 3))
                                                                  +
                                                                  +

                                                                  ... or you'd set up your own accumulator explicitly.

                                                                  +
                                                                  * (let ((hash (make-hash-table))
                                                                  +        (acc nil))
                                                                  +    (setf (gethash 'a hash) 1
                                                                  +          (gethash 'b hash) 2
                                                                  +          (gethash 'c hash) 3)
                                                                  +    (maphash (lambda (k v) (push (cons k v) acc)) hash)
                                                                  +    acc)
                                                                  +((C . 3) (B . 2) (A . 1))
                                                                  +
                                                                  +

                                                                  Exercise 1.5.15

                                                                  +

                                                                  Object Reference

                                                                  +

                                                                  Speaking of Objects, there are two constructs in Common Lisp that give you some behaviors you might expect from them; classes and structs. This exercise won't be a complete treatment, but will show you the basics.

                                                                  +
                                                                  * (defclass foo ()
                                                                  +    ((a :initform 1)
                                                                  +     (b :initform 2)
                                                                  +     (c :initform 3)))
                                                                  +#<STANDARD-CLASS FOO>
                                                                  +
                                                                  +* (make-instance 'foo)
                                                                  +#<FOO {10058567E3}>
                                                                  +
                                                                  +* (slot-value (make-instance 'foo) 'a)
                                                                  +1
                                                                  +
                                                                  +* (slot-value (make-instance 'foo) 'c)
                                                                  +3
                                                                  +
                                                                  +

                                                                  Instead of using slot-value, it's possible to define reader and accessor functions for individual slots.

                                                                  +
                                                                  * (defclass bar ()
                                                                  +       ((a :initform 1 :reader a)
                                                                  +        (b :initform 2 :accessor b)
                                                                  +        (c :initform 3)))
                                                                  +#<STANDARD-CLASS BAR>
                                                                  +
                                                                  +* (a (make-instance 'bar))
                                                                  +1
                                                                  +
                                                                  +* (b (make-instance 'bar))
                                                                  +2
                                                                  +
                                                                  +

                                                                  A reader is basically just a getter function. You can't set its value directly.

                                                                  +
                                                                  * (defparameter *instance* (make-instance 'bar))
                                                                  +*INSTANCE*
                                                                  +
                                                                  +* *instance*
                                                                  +#<BAR {1005F806E3}>
                                                                  +
                                                                  +* (a *instance*)
                                                                  +1
                                                                  +
                                                                  +* (setf (a *instance*) 32)
                                                                  + Evaluation aborted on #<UNDEFINED-FUNCTION (SETF A) {1005DCB833}>.
                                                                  +
                                                                  +

                                                                  An accessor on the other hand, is both a getter and a setter. So you can both read and assign through the interface it sets up.

                                                                  +
                                                                  * (b *instance*)
                                                                  +2
                                                                  +
                                                                  +* (setf (b *instance*) 32)
                                                                  +32
                                                                  +
                                                                  +* (b *instance*)
                                                                  +32
                                                                  +
                                                                  +

                                                                  This isn't the same as setting public or private methods though. Even if you don't expose an accessor, it's possible to set a slots' value using the slot-value function.

                                                                  +
                                                                  * (setf (slot-value *instance* 'a) 16)
                                                                  +16
                                                                  +
                                                                  +* (a *instance*)
                                                                  +16
                                                                  +
                                                                  +

                                                                  Unlike the key--value constructs we've seen so far, there isn't an easy and portable (across Common Lisp implementations) way to iterate over keys and values. If you want that, you're stuck doing something a touch hacky. In real life, it would be a bit less hacky (see here for what you'd really do), but we haven't covered packages yet.

                                                                  +
                                                                  * (defun class-slots (class)
                                                                  +    #+openmcl-native-threads (ccl:class-slots class)
                                                                  +    #+cmu (pcl:class-slots class)
                                                                  +    #+sbcl (sb-pcl:class-slots class)
                                                                  +    #+lispworks (hcl:class-slots class)
                                                                  +    #+allegro (mop:class-slots class)
                                                                  +    #+clisp (clos:class-slots class))
                                                                  +CLASS-SLOTS
                                                                  +
                                                                  +* (defun slot-definition-name (slot)
                                                                  +    #+openmcl-native-threads (ccl:slot-definition-name slot)
                                                                  +    #+cmu (pcl:slot-definition-name slot)
                                                                  +    #+sbcl (sb-pcl:slot-definition-name slot)
                                                                  +    #+lispworks (hcl:slot-definition-name slot)
                                                                  +    #+allegro (mop:slot-definition-name slot)
                                                                  +    #+clisp (clos:slot-definition-name slot))
                                                                  +
                                                                  +* (defun map-slots (fn instance)
                                                                  +    (loop for slot in (class-slots (class-of instance))
                                                                  +       for slot-name = (slot-definition-name slot)
                                                                  +       collect (when (slot-boundp instance slot-name)
                                                                  +                 (funcall fn slot-name (slot-value instance slot-name)))))
                                                                  +MAP-SLOTS
                                                                  +
                                                                  +* (map-slots (lambda (k v) (list k v)) *instance*)
                                                                  +((A 16) (B 32) (C 3))
                                                                  +
                                                                  +

                                                                  Exercise 1.5.16

                                                                  +

                                                                  Acyclic Graphs

                                                                  +

                                                                  (TODO)

                                                                  + + +
                                                                  + +
                                                                  +
                                                                  +
                                                                  + +

                                                                  results matching ""

                                                                  +
                                                                    + +
                                                                    +
                                                                    + +

                                                                    No results matching ""

                                                                    + +
                                                                    +
                                                                    +
                                                                    + +
                                                                    +
                                                                    + +
                                                                    + + + + + + + + + + + + + + +
                                                                    + + +
                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-0-math.html b/clones/llthw.common-lisp.dev/1-06-0-math.html new file mode 100644 index 00000000..8def64a9 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-0-math.html @@ -0,0 +1,1856 @@ + + + + + + + Numbers and Math ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                    +
                                                                    + + + + + + + + +
                                                                    + +
                                                                    + +
                                                                    + + + + + + + + +
                                                                    +
                                                                    + +
                                                                    +
                                                                    + +
                                                                    + +

                                                                    Chapter 1.6

                                                                    +

                                                                    Numbers and Math

                                                                    +
                                                                    +

                                                                    "The 3-legged stool of understanding is held up by history, languages, and mathematics. Equipped with these three you can learn anything you want to learn."

                                                                    +
                                                                    Robert A. Heinlein, The Happy Days Ahead, Expanded Universe
                                                                    + +
                                                                    +

                                                                    Common Lisp comes complete with a rigorous collection of mathematical tools, and excellent handling of Big Integers and Long-Floats---enabling Lisp software to leverage powerful number crunching facilities, perform statistical analysis, scientific computing, efficient cryptography, and more. All the functions, macros, and types presented in this chapter are a part of the language itself, and do not have to be specially imported from a separate standard library to be used.

                                                                    +

                                                                    In this chapter, we will review the numeric types available in Common Lisp, their built in notations, and cover the core mathematical functionality in the Common Lisp standard.

                                                                    +

                                                                    Exercises

                                                                    + + + +
                                                                    + +
                                                                    +
                                                                    +
                                                                    + +

                                                                    results matching ""

                                                                    +
                                                                      + +
                                                                      +
                                                                      + +

                                                                      No results matching ""

                                                                      + +
                                                                      +
                                                                      +
                                                                      + +
                                                                      +
                                                                      + +
                                                                      + + + + + + + + + + + + + + +
                                                                      + + +
                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-01-integers.html b/clones/llthw.common-lisp.dev/1-06-01-integers.html new file mode 100644 index 00000000..0f2996c6 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-01-integers.html @@ -0,0 +1,1865 @@ + + + + + + + Integers ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                      +
                                                                      + + + + + + + + +
                                                                      + +
                                                                      + +
                                                                      + + + + + + + + +
                                                                      +
                                                                      + +
                                                                      +
                                                                      + +
                                                                      + +

                                                                      Exercise 1.6.1

                                                                      +

                                                                      Integers

                                                                      +

                                                                      In the REPL

                                                                      +
                                                                      5
                                                                      +
                                                                      +-5
                                                                      +
                                                                      +1
                                                                      +
                                                                      +1234567890123456789012345678901234567890
                                                                      +
                                                                      +(expt 1234567890123456789012345678901234567890 2)
                                                                      +
                                                                      +(expt 1234567890123456789012345678901234567890 147)
                                                                      +
                                                                      +(expt -1234567890123456789012345678901234567890 147)
                                                                      +
                                                                      +

                                                                      What You Should See

                                                                      +

                                                                      An integer can be positive or negative.

                                                                      +
                                                                      * 5
                                                                      +5
                                                                      +
                                                                      +* -5
                                                                      +-5
                                                                      +
                                                                      +

                                                                      It can also be any size.

                                                                      +
                                                                      * 1
                                                                      +1
                                                                      +
                                                                      +* 1234567890123456789012345678901234567890
                                                                      +1234567890123456789012345678901234567890
                                                                      +
                                                                      +* (expt 1234567890123456789012345678901234567890 2)
                                                                      +1524157875323883675049535156256668194500533455762536198787501905199875019052100
                                                                      +
                                                                      +

                                                                      Give the last two examples a try as well, but sadly I can't show them because +GitBook can't parse numbers that big to typeset them. But Lisp sure can.

                                                                      + + +
                                                                      + +
                                                                      +
                                                                      +
                                                                      + +

                                                                      results matching ""

                                                                      +
                                                                        + +
                                                                        +
                                                                        + +

                                                                        No results matching ""

                                                                        + +
                                                                        +
                                                                        +
                                                                        + +
                                                                        +
                                                                        + +
                                                                        + + + + + + + + + + + + + + +
                                                                        + + +
                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-02-more-integers.html b/clones/llthw.common-lisp.dev/1-06-02-more-integers.html new file mode 100644 index 00000000..f9df4c5a --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-02-more-integers.html @@ -0,0 +1,1863 @@ + + + + + + + More Integers ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                        +
                                                                        + + + + + + + + +
                                                                        + +
                                                                        + +
                                                                        + + + + + + + + +
                                                                        +
                                                                        + +
                                                                        +
                                                                        + +
                                                                        + +

                                                                        Exercise 1.6.2

                                                                        +

                                                                        More Integers

                                                                        +

                                                                        Of course, this doesn't mean they're always the same type internally. Various integers have different types based on their size to conserve space, though they are all usable interchangeably.

                                                                        +

                                                                        In the REPL

                                                                        +
                                                                        (type-of 1)
                                                                        +
                                                                        +(type-of 1234567890123456789012345678901234567890)
                                                                        +
                                                                        +(type-of (expt -1234567890123456789012345678901234567890 147))
                                                                        +
                                                                        +(typep 1 'integer)
                                                                        +
                                                                        +(typep 1234567890123456789012345678901234567890 'integer)
                                                                        +
                                                                        +(typep (expt -1234567890123456789012345678901234567890 147) 'integer)
                                                                        +
                                                                        +

                                                                        What You Should See

                                                                        +
                                                                        * (type-of 1)
                                                                        +BIT
                                                                        +
                                                                        +* (type-of 1234567890123456789012345678901234567890)
                                                                        +(INTEGER 4611686018427387904)
                                                                        +
                                                                        +* (type-of (expt -1234567890123456789012345678901234567890 147))
                                                                        +BIGNUM
                                                                        +
                                                                        +* (typep 1 'integer)
                                                                        +T
                                                                        +
                                                                        +* (typep 1234567890123456789012345678901234567890 'integer)
                                                                        +T
                                                                        +
                                                                        +* (typep (expt -1234567890123456789012345678901234567890 147) 'integer)
                                                                        +T
                                                                        +
                                                                        + + +
                                                                        + +
                                                                        +
                                                                        +
                                                                        + +

                                                                        results matching ""

                                                                        +
                                                                          + +
                                                                          +
                                                                          + +

                                                                          No results matching ""

                                                                          + +
                                                                          +
                                                                          +
                                                                          + +
                                                                          +
                                                                          + +
                                                                          + + + + + + + + + + + + + + +
                                                                          + + +
                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-03-hexadecimal-notation.html b/clones/llthw.common-lisp.dev/1-06-03-hexadecimal-notation.html new file mode 100644 index 00000000..c779f2d3 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-03-hexadecimal-notation.html @@ -0,0 +1,1888 @@ + + + + + + + Hexadecimal Integer Notation ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                          +
                                                                          + + + + + + + + +
                                                                          + +
                                                                          + +
                                                                          + + + + + + + + +
                                                                          +
                                                                          + +
                                                                          +
                                                                          + +
                                                                          + +

                                                                          Exercise 1.6.3

                                                                          +

                                                                          Hexadecimal Integer Notation

                                                                          +

                                                                          In the REPL

                                                                          +
                                                                          #xFF
                                                                          +
                                                                          +#x00
                                                                          +
                                                                          +#x0123456789ABCDEF
                                                                          +
                                                                          +(parse-integer "FF" :radix 16)
                                                                          +
                                                                          +(parse-integer "0123456789ABCDEF" :radix 16)
                                                                          +
                                                                          +(format nil "~x" 255)
                                                                          +
                                                                          +(format nil "~x" 81985529216486895)
                                                                          +
                                                                          +(type-of #xFF)
                                                                          +
                                                                          +(+ #xDEADBEEF #xFF)
                                                                          +
                                                                          +(format nil "~x" #x0123456789ABCDEF)
                                                                          +
                                                                          +

                                                                          What You Should See

                                                                          +

                                                                          There exists a built-in reader macro to allow for hexadecimal literals.

                                                                          +
                                                                          * #xFF
                                                                          +255
                                                                          +
                                                                          +* #x00
                                                                          +0
                                                                          +
                                                                          +* #x0123456789ABCDEF
                                                                          +81985529216486895
                                                                          +
                                                                          +

                                                                          You also have access to appropriate options in parse-integer and format to read or write hexadecimal numbers.

                                                                          +
                                                                          * (parse-integer "FF" :radix 16)
                                                                          +255
                                                                          +2
                                                                          +
                                                                          +* (parse-integer "0123456789ABCDEF" :radix 16)
                                                                          +81985529216486895
                                                                          +16
                                                                          +
                                                                          +* (format nil "~x" 255)
                                                                          +"FF"
                                                                          +
                                                                          +* (format nil "~x" 81985529216486895)
                                                                          +"123456789ABCDEF"
                                                                          +
                                                                          +

                                                                          Of course, the reader macro expands into a number...

                                                                          +
                                                                          * (type-of #xFF)
                                                                          +(INTEGER 0 4611686018427387903)
                                                                          +
                                                                          +

                                                                          ...which means you can use it anywhere you can use numbers.

                                                                          +
                                                                          * (+ #xDEADBEEF #xFF)
                                                                          +3735928814
                                                                          +
                                                                          +* (format nil "~x" #x0123456789ABCDEF)
                                                                          +"123456789ABCDEF"
                                                                          +
                                                                          + + +
                                                                          + +
                                                                          +
                                                                          +
                                                                          + +

                                                                          results matching ""

                                                                          +
                                                                            + +
                                                                            +
                                                                            + +

                                                                            No results matching ""

                                                                            + +
                                                                            +
                                                                            +
                                                                            + +
                                                                            +
                                                                            + +
                                                                            + + + + + + + + + + + + + + +
                                                                            + + +
                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-04-octal-notation.html b/clones/llthw.common-lisp.dev/1-06-04-octal-notation.html new file mode 100644 index 00000000..0ce1809d --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-04-octal-notation.html @@ -0,0 +1,1888 @@ + + + + + + + Octal Integer Notation ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                            +
                                                                            + + + + + + + + +
                                                                            + +
                                                                            + +
                                                                            + + + + + + + + +
                                                                            +
                                                                            + +
                                                                            +
                                                                            + +
                                                                            + +

                                                                            Exercise 1.6.4

                                                                            +

                                                                            Octal Integer Notation

                                                                            +

                                                                            In the REPL

                                                                            +
                                                                            #o77
                                                                            +
                                                                            +#o00
                                                                            +
                                                                            +#o01234567
                                                                            +
                                                                            +(parse-integer "77" :radix 8)
                                                                            +
                                                                            +(parse-integer "01234567" :radix 8)
                                                                            +
                                                                            +(format nil "~o" 63)
                                                                            +
                                                                            +(format nil "~o" 342391)
                                                                            +
                                                                            +(type-of #o77)
                                                                            +
                                                                            +(+ #o123 #o456)
                                                                            +
                                                                            +(format nil "~o" #o01234567)
                                                                            +
                                                                            +

                                                                            What You Should See

                                                                            +

                                                                            There is also a built-in syntax for octal literals.

                                                                            +
                                                                            * #o77
                                                                            +63
                                                                            +
                                                                            +* #o0
                                                                            +0
                                                                            +
                                                                            +* #o01234567
                                                                            +342391
                                                                            +
                                                                            +

                                                                            There also exist appropriate supporting options in parse-integer and format to read or write octal numbers.

                                                                            +
                                                                            * (parse-integer "77" :radix 8)
                                                                            +63
                                                                            +2
                                                                            +
                                                                            +* (parse-integer "01234567" :radix 8)
                                                                            +342391
                                                                            +8
                                                                            +
                                                                            +* (format nil "~o" 63)
                                                                            +"77"
                                                                            +
                                                                            +* (format nil "~o" 342391)
                                                                            +"1234567"
                                                                            +
                                                                            +

                                                                            And again, the #o reader form expands into a number...

                                                                            +
                                                                            * (type-of #o77)
                                                                            +(INTEGER 0 4611686018427387903)
                                                                            +
                                                                            +

                                                                            ... which means you can use anywhere you could use numbers.

                                                                            +
                                                                            * (+ #o123 #o456)
                                                                            +385
                                                                            +
                                                                            +* (format nil "~o" #o01234567)
                                                                            +"1234567"
                                                                            +
                                                                            + + +
                                                                            + +
                                                                            +
                                                                            +
                                                                            + +

                                                                            results matching ""

                                                                            +
                                                                              + +
                                                                              +
                                                                              + +

                                                                              No results matching ""

                                                                              + +
                                                                              +
                                                                              +
                                                                              + +
                                                                              +
                                                                              + +
                                                                              + + + + + + + + + + + + + + +
                                                                              + + +
                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-05-binary-notation.html b/clones/llthw.common-lisp.dev/1-06-05-binary-notation.html new file mode 100644 index 00000000..04299d05 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-05-binary-notation.html @@ -0,0 +1,1893 @@ + + + + + + + Binary Integer Notation ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                              +
                                                                              + + + + + + + + +
                                                                              + +
                                                                              + +
                                                                              + + + + + + + + +
                                                                              +
                                                                              + +
                                                                              +
                                                                              + +
                                                                              + +

                                                                              Exercise 1.6.5

                                                                              +

                                                                              Binary Integer Notation

                                                                              +

                                                                              In the REPL

                                                                              +
                                                                              #b1
                                                                              +
                                                                              +#b1011
                                                                              +
                                                                              +#b101010101
                                                                              +
                                                                              +(parse-integer "1011" :radix 2)
                                                                              +
                                                                              +(parse-integer "101010101" :radix 2)
                                                                              +
                                                                              +(format nil "~b" 11)
                                                                              +
                                                                              +(format nil "~b" 341)
                                                                              +
                                                                              +(type-of #b1)
                                                                              +
                                                                              +(type-of #b101)
                                                                              +
                                                                              +(+ #b10101 #b101)
                                                                              +
                                                                              +(format nil "~b" #b101010101)
                                                                              +
                                                                              +

                                                                              What You Should See

                                                                              +

                                                                              Similarly, there is a binary literal notation.

                                                                              +
                                                                              * #b1
                                                                              +1
                                                                              +
                                                                              +* #b1011
                                                                              +11
                                                                              +
                                                                              +* #b101010101
                                                                              +341
                                                                              +
                                                                              +

                                                                              format and parse-integer work nicely to encode and decode binary numbers.

                                                                              +
                                                                              * (parse-integer "1011" :radix 2)
                                                                              +11
                                                                              +4
                                                                              +
                                                                              +* (parse-integer "101010101" :radix 2)
                                                                              +341
                                                                              +9
                                                                              +
                                                                              +* (format nil "~b" 11)
                                                                              +"1011"
                                                                              +
                                                                              +* (format nil "~b" 341)
                                                                              +"101010101"
                                                                              +
                                                                              +

                                                                              And once again, the reader macro expands into a number.

                                                                              +
                                                                              * (type-of #b1)
                                                                              +BIT
                                                                              +
                                                                              +* (type-of #b101)
                                                                              +(INTEGER 0 4611686018427387903)
                                                                              +
                                                                              +

                                                                              So all the usual number-related tricks are available.

                                                                              +
                                                                              * (+ #b10101 #b101)
                                                                              +26
                                                                              +
                                                                              +* (format nil "~b" #b101010101)
                                                                              +"101010101"
                                                                              +
                                                                              + + +
                                                                              + +
                                                                              +
                                                                              +
                                                                              + +

                                                                              results matching ""

                                                                              +
                                                                                + +
                                                                                +
                                                                                + +

                                                                                No results matching ""

                                                                                + +
                                                                                +
                                                                                +
                                                                                + +
                                                                                +
                                                                                + +
                                                                                + + + + + + + + + + + + + + +
                                                                                + + +
                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-06-ratios.html b/clones/llthw.common-lisp.dev/1-06-06-ratios.html new file mode 100644 index 00000000..b7fa8c15 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-06-ratios.html @@ -0,0 +1,1886 @@ + + + + + + + Ratios and Rational Numbers ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                +
                                                                                + + + + + + + + +
                                                                                + +
                                                                                + +
                                                                                + + + + + + + + +
                                                                                +
                                                                                + +
                                                                                +
                                                                                + +
                                                                                + +

                                                                                Exercise 1.6.6

                                                                                +

                                                                                Ratios

                                                                                +

                                                                                In the REPL

                                                                                +
                                                                                3/17
                                                                                +
                                                                                +1/2
                                                                                +
                                                                                +(typep 1/2 'integer)
                                                                                +
                                                                                +(typep 1/2 'number)
                                                                                +
                                                                                +(type-of 1/2)
                                                                                +
                                                                                +.5
                                                                                +
                                                                                +(type-of .5)
                                                                                +
                                                                                +1/2
                                                                                +
                                                                                +4/8
                                                                                +
                                                                                +32/64
                                                                                +
                                                                                +

                                                                                What You Should See

                                                                                +

                                                                                Ratios are a primitive numeric type in Common Lisp.

                                                                                +
                                                                                * 3/17
                                                                                +3/17
                                                                                +
                                                                                +* 1/2
                                                                                +1/2
                                                                                +
                                                                                +

                                                                                Ratios are not integers, but they are still numbers.

                                                                                +
                                                                                * (typep 1/2 'integer)
                                                                                +NIL
                                                                                +
                                                                                +* (typep 1/2 'number)
                                                                                +T
                                                                                +
                                                                                +

                                                                                These are not the same things as their float equivalents.

                                                                                +
                                                                                * (type-of 1/2)
                                                                                +RATIO
                                                                                +
                                                                                +* .5
                                                                                +0.5
                                                                                +
                                                                                +* (type-of .5)
                                                                                +SINGLE-FLOAT
                                                                                +
                                                                                +

                                                                                They are always reduced to lowest terms.

                                                                                +
                                                                                * 1/2
                                                                                +1/2
                                                                                +
                                                                                +* 4/8
                                                                                +1/2
                                                                                +
                                                                                +* 32/64
                                                                                +1/2
                                                                                +
                                                                                + + +
                                                                                + +
                                                                                +
                                                                                +
                                                                                + +

                                                                                results matching ""

                                                                                +
                                                                                  + +
                                                                                  +
                                                                                  + +

                                                                                  No results matching ""

                                                                                  + +
                                                                                  +
                                                                                  +
                                                                                  + +
                                                                                  +
                                                                                  + +
                                                                                  + + + + + + + + + + + + + + +
                                                                                  + + +
                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-07-floating-point.html b/clones/llthw.common-lisp.dev/1-06-07-floating-point.html new file mode 100644 index 00000000..9210612c --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-07-floating-point.html @@ -0,0 +1,1875 @@ + + + + + + + Floating-point Numbers ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                  +
                                                                                  + + + + + + + + +
                                                                                  + +
                                                                                  + +
                                                                                  + + + + + + + + +
                                                                                  +
                                                                                  + +
                                                                                  +
                                                                                  + +
                                                                                  + +

                                                                                  Exercise 1.6.7

                                                                                  +

                                                                                  Floating-Point Numbers

                                                                                  +

                                                                                  In the REPL

                                                                                  +
                                                                                  .1
                                                                                  +
                                                                                  +1.5
                                                                                  +
                                                                                  +1.1234
                                                                                  +
                                                                                  +(typep 1.1234 'number)
                                                                                  +
                                                                                  +(typep 1.1234 'integer)
                                                                                  +
                                                                                  +(type-of 1.1234)
                                                                                  +
                                                                                  +(/ 6.44444444444 2)
                                                                                  +
                                                                                  +(+ .5000001 .4000009)
                                                                                  +
                                                                                  +

                                                                                  What You Should See

                                                                                  +

                                                                                  Floating point numbers are also among the Common Lisp numeric types.

                                                                                  +
                                                                                  * .1
                                                                                  +0.1
                                                                                  +
                                                                                  +* 1.5
                                                                                  +1.5
                                                                                  +
                                                                                  +* 1.1234
                                                                                  +1.1234
                                                                                  +
                                                                                  +* (typep 1.1234 'number)
                                                                                  +T
                                                                                  +
                                                                                  +* (typep 1.1234 'integer)
                                                                                  +NIL
                                                                                  +
                                                                                  +* (type-of 1.1234)
                                                                                  +SINGLE-FLOAT
                                                                                  +
                                                                                  +

                                                                                  They suffer all the same precision issues here as in every other language you've seen them at work.

                                                                                  +
                                                                                  * (/ 6.44444444444 2)
                                                                                  +3.2222223
                                                                                  +
                                                                                  +* (+ .5000001 .4000009)
                                                                                  +0.90000105
                                                                                  +
                                                                                  +

                                                                                  So, as always, careful.

                                                                                  + + +
                                                                                  + +
                                                                                  +
                                                                                  +
                                                                                  + +

                                                                                  results matching ""

                                                                                  +
                                                                                    + +
                                                                                    +
                                                                                    + +

                                                                                    No results matching ""

                                                                                    + +
                                                                                    +
                                                                                    +
                                                                                    + +
                                                                                    +
                                                                                    + +
                                                                                    + + + + + + + + + + + + + + +
                                                                                    + + +
                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-08-constants.html b/clones/llthw.common-lisp.dev/1-06-08-constants.html new file mode 100644 index 00000000..b4bbb39a --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-08-constants.html @@ -0,0 +1,1864 @@ + + + + + + + Numeric Constants ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                    +
                                                                                    + + + + + + + + +
                                                                                    + +
                                                                                    + +
                                                                                    + + + + + + + + +
                                                                                    +
                                                                                    + +
                                                                                    +
                                                                                    + +
                                                                                    + +

                                                                                    Exercise 1.6.8

                                                                                    +

                                                                                    Numeric Constants

                                                                                    +

                                                                                    In the REPL

                                                                                    +
                                                                                    pi
                                                                                    +
                                                                                    +(= pi pi)
                                                                                    +
                                                                                    +(eq pi pi)
                                                                                    +
                                                                                    +(eql pi pi)
                                                                                    +
                                                                                    +(equal pi pi)
                                                                                    +
                                                                                    +(equalp pi pi)
                                                                                    +
                                                                                    +

                                                                                    What You Should See

                                                                                    +

                                                                                    The constant pi is defined for you.

                                                                                    +
                                                                                    * pi
                                                                                    +3.141592653589793d0
                                                                                    +
                                                                                    +

                                                                                    It's always equal to itself, obviously, but its exact representation depends on the float precision of a particular Lisp implementation.

                                                                                    +
                                                                                    * (= pi pi)
                                                                                    +T
                                                                                    +
                                                                                    +* (eq pi pi)
                                                                                    +T
                                                                                    +
                                                                                    +* (eql pi pi)
                                                                                    +T
                                                                                    +
                                                                                    +* (equal pi pi)
                                                                                    +T
                                                                                    +
                                                                                    +* (equalp pi pi)
                                                                                    +T
                                                                                    +
                                                                                    + + +
                                                                                    + +
                                                                                    +
                                                                                    +
                                                                                    + +

                                                                                    results matching ""

                                                                                    +
                                                                                      + +
                                                                                      +
                                                                                      + +

                                                                                      No results matching ""

                                                                                      + +
                                                                                      +
                                                                                      +
                                                                                      + +
                                                                                      +
                                                                                      + +
                                                                                      + + + + + + + + + + + + + + +
                                                                                      + + +
                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-09-complex-numbers.html b/clones/llthw.common-lisp.dev/1-06-09-complex-numbers.html new file mode 100644 index 00000000..c74418c0 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-09-complex-numbers.html @@ -0,0 +1,1848 @@ + + + + + + + Complex Numbers ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                      +
                                                                                      + + + + + + + + +
                                                                                      + +
                                                                                      + +
                                                                                      + + + + + + + + +
                                                                                      +
                                                                                      + +
                                                                                      +
                                                                                      + +
                                                                                      + +

                                                                                      Exercise 1.6.9

                                                                                      +

                                                                                      Complex Numbers

                                                                                      +

                                                                                      Common Lisp has built-in support for Complex Numbers. You can perform arithmetic on them just like any other number type.

                                                                                      +

                                                                                      In the REPL

                                                                                      +
                                                                                      (sqrt -1)
                                                                                      +
                                                                                      +(+ #C(0.0 1.0) #C(0.0 1.0))
                                                                                      +
                                                                                      +(* #C(0.0 1.0) #C(0.0 1.0))
                                                                                      +
                                                                                      +

                                                                                      What You Should See

                                                                                      +
                                                                                      * (sqrt -1)
                                                                                      +#C(0.0 1.0)
                                                                                      +
                                                                                      +* (+ #C(0.0 1.0) #C(0.0 1.0))
                                                                                      +#C(0.0 2.0)
                                                                                      +
                                                                                      +* (* #C(0.0 1.0) #C(0.0 1.0))
                                                                                      +#C(-1.0 0.0)
                                                                                      +
                                                                                      + + +
                                                                                      + +
                                                                                      +
                                                                                      +
                                                                                      + +

                                                                                      results matching ""

                                                                                      +
                                                                                        + +
                                                                                        +
                                                                                        + +

                                                                                        No results matching ""

                                                                                        + +
                                                                                        +
                                                                                        +
                                                                                        + +
                                                                                        +
                                                                                        + +
                                                                                        + + + + + + + + + + + + + + +
                                                                                        + + +
                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-10-arithmetic.html b/clones/llthw.common-lisp.dev/1-06-10-arithmetic.html new file mode 100644 index 00000000..fc399c71 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-10-arithmetic.html @@ -0,0 +1,1879 @@ + + + + + + + Arithmetic ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                        +
                                                                                        + + + + + + + + +
                                                                                        + +
                                                                                        + +
                                                                                        + + + + + + + + +
                                                                                        +
                                                                                        + +
                                                                                        +
                                                                                        + +
                                                                                        + +

                                                                                        Exercise 1.6.10

                                                                                        +

                                                                                        Arithmetic

                                                                                        +

                                                                                        Now that you've had a chance to explore some more number types built in to Common Lisp, let's take another look at what you can do with them.

                                                                                        +

                                                                                        In the REPL

                                                                                        +
                                                                                        (+ 1 1)
                                                                                        +
                                                                                        +(1+ 1)
                                                                                        +
                                                                                        +(- 1 1)
                                                                                        +
                                                                                        +(- 1)
                                                                                        +
                                                                                        +(* 2 2)
                                                                                        +
                                                                                        +(/ 2 2)
                                                                                        +
                                                                                        +(/ 10 2)
                                                                                        +
                                                                                        +(/ 9 2)
                                                                                        +
                                                                                        +

                                                                                        What You Should See

                                                                                        +
                                                                                        * (+ 1 1)
                                                                                        +2
                                                                                        +
                                                                                        +* (1+ 1)
                                                                                        +2
                                                                                        +
                                                                                        +* (- 1 1)
                                                                                        +0
                                                                                        +
                                                                                        +* (1- 1)
                                                                                        +0
                                                                                        +
                                                                                        +* (- 1)
                                                                                        +-1
                                                                                        +
                                                                                        +* (* 2 2)
                                                                                        +4
                                                                                        +
                                                                                        +* (/ 2 2)
                                                                                        +1
                                                                                        +
                                                                                        +* (/ 10 2)
                                                                                        +5
                                                                                        +
                                                                                        +* (/ 9 2)
                                                                                        +9/2
                                                                                        +
                                                                                        +

                                                                                        You can non-destructively increment or decrement a value with the built-in functions 1+ and 1-, respectively.

                                                                                        +

                                                                                        You can negate a number by passing it as the only argument to the subtraction function. This may seem verbose compared to the much simpler -n syntax for negative integers, however, this allows any number that can be negated to be, and also allows for user-supplied values to be negated.

                                                                                        +

                                                                                        Division normally returns a rational number, the canonical representation of which could be either an integer or a ratio.

                                                                                        + + +
                                                                                        + +
                                                                                        +
                                                                                        +
                                                                                        + +

                                                                                        results matching ""

                                                                                        +
                                                                                          + +
                                                                                          +
                                                                                          + +

                                                                                          No results matching ""

                                                                                          + +
                                                                                          +
                                                                                          +
                                                                                          + +
                                                                                          +
                                                                                          + +
                                                                                          + + + + + + + + + + + + + + +
                                                                                          + + +
                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-11-more-arithmetic.html b/clones/llthw.common-lisp.dev/1-06-11-more-arithmetic.html new file mode 100644 index 00000000..be3b4c0d --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-11-more-arithmetic.html @@ -0,0 +1,1873 @@ + + + + + + + More Arithmetic ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                          +
                                                                                          + + + + + + + + +
                                                                                          + +
                                                                                          + +
                                                                                          + + + + + + + + +
                                                                                          +
                                                                                          + +
                                                                                          +
                                                                                          + +
                                                                                          + +

                                                                                          Exercise 1.6.11

                                                                                          +

                                                                                          More Arithmetic

                                                                                          +

                                                                                          In the REPL

                                                                                          +
                                                                                          (+ 1 1.0)
                                                                                          +
                                                                                          +(+ 1 #C(0.0 1.0))
                                                                                          +
                                                                                          +(/ 9 2.0)
                                                                                          +
                                                                                          +(floor 9/2)
                                                                                          +
                                                                                          +(floor 9 2)
                                                                                          +
                                                                                          +(ceiling 9/2)
                                                                                          +
                                                                                          +(ceiling 9 2)
                                                                                          +
                                                                                          +

                                                                                          What You Should See

                                                                                          +
                                                                                          * (+ 1 1.0)
                                                                                          +2.0
                                                                                          +
                                                                                          +* (+ 1 #C(0.0 1.0))
                                                                                          +#C(1.0 1.0)
                                                                                          +
                                                                                          +* (/ 9 2.0)
                                                                                          +4.5
                                                                                          +
                                                                                          +* (floor 9/2)
                                                                                          +4
                                                                                          +1/2
                                                                                          +
                                                                                          +* (floor 9 2)
                                                                                          +4
                                                                                          +1
                                                                                          +
                                                                                          +* (ceiling 9/2)
                                                                                          +5
                                                                                          +-1/2
                                                                                          +
                                                                                          +* (ceiling 9 2)
                                                                                          +5
                                                                                          +-1
                                                                                          +
                                                                                          +

                                                                                          You can perform arithmetic across multiple number types, as Common Lisp takes into consideration the law of propagation of floats; while normally division returns a rational number, as stated in the previous exercise, if you supply a Real number represented as a Float, you will get a float back instead of a rational.

                                                                                          +

                                                                                          Common Lisp also supports Floor and Ceiling division, which return the quotient and remainder as multiple values---although sometimes that remainder can be deceptive. These functions also can take a single rational number, rounding down or up to the nearest integer and returning the remainder as a ratio.

                                                                                          + + +
                                                                                          + +
                                                                                          +
                                                                                          +
                                                                                          + +

                                                                                          results matching ""

                                                                                          +
                                                                                            + +
                                                                                            +
                                                                                            + +

                                                                                            No results matching ""

                                                                                            + +
                                                                                            +
                                                                                            +
                                                                                            + +
                                                                                            +
                                                                                            + +
                                                                                            + + + + + + + + + + + + + + +
                                                                                            + + +
                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-12-even-more-arithmetic.html b/clones/llthw.common-lisp.dev/1-06-12-even-more-arithmetic.html new file mode 100644 index 00000000..545fb752 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-12-even-more-arithmetic.html @@ -0,0 +1,1842 @@ + + + + + + + Even More Arithmetic ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                            +
                                                                                            + + + + + + + + +
                                                                                            + +
                                                                                            + +
                                                                                            + + + + + + + + +
                                                                                            +
                                                                                            + +
                                                                                            +
                                                                                            + +
                                                                                            + +

                                                                                            Exercise 1.6.12

                                                                                            +

                                                                                            Even More Arithmetic

                                                                                            +

                                                                                            In the REPL

                                                                                            +
                                                                                            (mod (+ 10 2) 2)
                                                                                            +
                                                                                            +(mod (+ 55 20) 60)
                                                                                            +
                                                                                            +

                                                                                            What You Should See

                                                                                            +
                                                                                            * (mod (+ 10 2) 2)
                                                                                            +0
                                                                                            +
                                                                                            +* (mod (+ 55 20) 60)
                                                                                            +15
                                                                                            +
                                                                                            + + +
                                                                                            + +
                                                                                            +
                                                                                            +
                                                                                            + +

                                                                                            results matching ""

                                                                                            +
                                                                                              + +
                                                                                              +
                                                                                              + +

                                                                                              No results matching ""

                                                                                              + +
                                                                                              +
                                                                                              +
                                                                                              + +
                                                                                              +
                                                                                              + +
                                                                                              + + + + + + + + + + + + + + +
                                                                                              + + +
                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-13-exponents.html b/clones/llthw.common-lisp.dev/1-06-13-exponents.html new file mode 100644 index 00000000..ff3df119 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-13-exponents.html @@ -0,0 +1,1847 @@ + + + + + + + Exponents ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                              +
                                                                                              + + + + + + + + +
                                                                                              + +
                                                                                              + +
                                                                                              + + + + + + + + +
                                                                                              +
                                                                                              + +
                                                                                              +
                                                                                              + +
                                                                                              + +

                                                                                              Exercise 1.6.13

                                                                                              +

                                                                                              Exponents

                                                                                              +

                                                                                              In the REPL

                                                                                              +
                                                                                              (expt 2 2)
                                                                                              +
                                                                                              +(expt 10 28)
                                                                                              +
                                                                                              +(exp 28)
                                                                                              +
                                                                                              +

                                                                                              What You Should See

                                                                                              +
                                                                                              * (expt 2 2)
                                                                                              +4
                                                                                              +
                                                                                              +* (expt 10 28)
                                                                                              +10000000000000000000000000000
                                                                                              +
                                                                                              +* (exp 28)
                                                                                              +1.4462571e12
                                                                                              +
                                                                                              + + +
                                                                                              + +
                                                                                              +
                                                                                              +
                                                                                              + +

                                                                                              results matching ""

                                                                                              +
                                                                                                + +
                                                                                                +
                                                                                                + +

                                                                                                No results matching ""

                                                                                                + +
                                                                                                +
                                                                                                +
                                                                                                + +
                                                                                                +
                                                                                                + +
                                                                                                + + + + + + + + + + + + + + +
                                                                                                + + +
                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-14-logarithms.html b/clones/llthw.common-lisp.dev/1-06-14-logarithms.html new file mode 100644 index 00000000..0dc48827 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-14-logarithms.html @@ -0,0 +1,1847 @@ + + + + + + + Logarithms ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                +
                                                                                                + + + + + + + + +
                                                                                                + +
                                                                                                + +
                                                                                                + + + + + + + + +
                                                                                                +
                                                                                                + +
                                                                                                +
                                                                                                + +
                                                                                                + +

                                                                                                Exercise 1.6.14

                                                                                                +

                                                                                                Logarithms

                                                                                                +

                                                                                                In the REPL

                                                                                                +
                                                                                                (log 2)
                                                                                                +
                                                                                                +(log 2 10)
                                                                                                +
                                                                                                +(log 2 2)
                                                                                                +
                                                                                                +

                                                                                                What You Should See

                                                                                                +
                                                                                                * (log 2)
                                                                                                +0.6931472
                                                                                                +
                                                                                                +* (log 2 10)
                                                                                                +0.30103
                                                                                                +
                                                                                                +* (log 2 2)
                                                                                                +1.0
                                                                                                +
                                                                                                + + +
                                                                                                + +
                                                                                                +
                                                                                                +
                                                                                                + +

                                                                                                results matching ""

                                                                                                +
                                                                                                  + +
                                                                                                  +
                                                                                                  + +

                                                                                                  No results matching ""

                                                                                                  + +
                                                                                                  +
                                                                                                  +
                                                                                                  + +
                                                                                                  +
                                                                                                  + +
                                                                                                  + + + + + + + + + + + + + + +
                                                                                                  + + +
                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-15-trigonometry.html b/clones/llthw.common-lisp.dev/1-06-15-trigonometry.html new file mode 100644 index 00000000..619f35ad --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-15-trigonometry.html @@ -0,0 +1,1852 @@ + + + + + + + Trigonometry ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                  +
                                                                                                  + + + + + + + + +
                                                                                                  + +
                                                                                                  + +
                                                                                                  + + + + + + + + +
                                                                                                  +
                                                                                                  + +
                                                                                                  +
                                                                                                  + +
                                                                                                  + +

                                                                                                  Exercise 1.6.15

                                                                                                  +

                                                                                                  Trigonometry

                                                                                                  +

                                                                                                  In the REPL

                                                                                                  +
                                                                                                  pi
                                                                                                  +
                                                                                                  +(sin pi)
                                                                                                  +
                                                                                                  +(cos pi)
                                                                                                  +
                                                                                                  +(tan pi)
                                                                                                  +
                                                                                                  +

                                                                                                  What You Should See

                                                                                                  +
                                                                                                  * pi
                                                                                                  +3.141592653589793d0
                                                                                                  +
                                                                                                  +* (sin pi)
                                                                                                  +1.2246467991473532d-16
                                                                                                  +
                                                                                                  +* (cos pi)
                                                                                                  +-1.0d0
                                                                                                  +
                                                                                                  +* (tan pi)
                                                                                                  +-1.2246467991473532d-16
                                                                                                  +
                                                                                                  + + +
                                                                                                  + +
                                                                                                  +
                                                                                                  +
                                                                                                  + +

                                                                                                  results matching ""

                                                                                                  +
                                                                                                    + +
                                                                                                    +
                                                                                                    + +

                                                                                                    No results matching ""

                                                                                                    + +
                                                                                                    +
                                                                                                    +
                                                                                                    + +
                                                                                                    +
                                                                                                    + +
                                                                                                    + + + + + + + + + + + + + + +
                                                                                                    + + +
                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-06-16-psuedorandom-numbers.html b/clones/llthw.common-lisp.dev/1-06-16-psuedorandom-numbers.html new file mode 100644 index 00000000..6ebf4bff --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-06-16-psuedorandom-numbers.html @@ -0,0 +1,1865 @@ + + + + + + + Pseudo-Random Numbers ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                    +
                                                                                                    + + + + + + + + +
                                                                                                    + +
                                                                                                    + +
                                                                                                    + + + + + + + + +
                                                                                                    +
                                                                                                    + +
                                                                                                    +
                                                                                                    + +
                                                                                                    + +

                                                                                                    Exercise 1.6.16

                                                                                                    +

                                                                                                    Pseudo-Random Numbers

                                                                                                    +

                                                                                                    Pseudo-Random number generation is available with the random function; you +pass it a limit, which can either be a positive integer or float, and it returns +to you a number of the same type as the limit.

                                                                                                    +

                                                                                                    In the REPL

                                                                                                    +
                                                                                                    (random 10)
                                                                                                    +
                                                                                                    +(random 10)
                                                                                                    +
                                                                                                    +(random 10)
                                                                                                    +
                                                                                                    +(random 10)
                                                                                                    +
                                                                                                    +(random 10)
                                                                                                    +
                                                                                                    +(random 10)
                                                                                                    +
                                                                                                    +

                                                                                                    What You Should See

                                                                                                    +
                                                                                                    * (random 10)
                                                                                                    +3
                                                                                                    +
                                                                                                    +* (random 10)
                                                                                                    +1
                                                                                                    +
                                                                                                    +* (random 10)
                                                                                                    +5
                                                                                                    +
                                                                                                    +* (random 10)
                                                                                                    +9
                                                                                                    +
                                                                                                    +* (random 10)
                                                                                                    +6
                                                                                                    +
                                                                                                    +* (random 10)
                                                                                                    +2
                                                                                                    +
                                                                                                    + + +
                                                                                                    + +
                                                                                                    +
                                                                                                    +
                                                                                                    + +

                                                                                                    results matching ""

                                                                                                    +
                                                                                                      + +
                                                                                                      +
                                                                                                      + +

                                                                                                      No results matching ""

                                                                                                      + +
                                                                                                      +
                                                                                                      +
                                                                                                      + +
                                                                                                      +
                                                                                                      + +
                                                                                                      + + + + + + + + + + + + + + +
                                                                                                      + + +
                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-07-0-arrays.html b/clones/llthw.common-lisp.dev/1-07-0-arrays.html new file mode 100644 index 00000000..e013b570 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-07-0-arrays.html @@ -0,0 +1,1923 @@ + + + + + + + Extra Credit: Arrays and Vectors ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                      +
                                                                                                      + + + + + + + + +
                                                                                                      + +
                                                                                                      + +
                                                                                                      + + + + + + + + +
                                                                                                      +
                                                                                                      + +
                                                                                                      +
                                                                                                      + +
                                                                                                      + +

                                                                                                      Chapter 1.7 --- Extra Credit

                                                                                                      +

                                                                                                      Arrays and Vectors

                                                                                                      +
                                                                                                      +

                                                                                                      "As with any tool, merit or demerit lies in how it is used."

                                                                                                      +
                                                                                                      Robert A. Heinlein, Friday
                                                                                                      + +
                                                                                                      +

                                                                                                      When you need to squeeze extra efficiency out of your Lisp program, usually the first place to turn after minimizing consing-operations is to migrate your list data structures to arrays and vectors. You will lose the flexibility of lists, but you do gain in performance and reduce memory usage.

                                                                                                      +

                                                                                                      Just like Lists, Arrays descend from the Sequence type, and vectors are a special type of array with only one dimension, so all sequence operations will also work on arrays and vectors. List operations, however, will not. Luckily, Common Lisp includes a number of utilities for working with arrays and vectors---and you should get to know them immediately so that you can start improving your codebase right away.

                                                                                                      +

                                                                                                      This chapter will contain exercises on:

                                                                                                      +
                                                                                                        +
                                                                                                      • Sequences, Arrays, and Vectors
                                                                                                      • +
                                                                                                      • Making Arrays
                                                                                                      • +
                                                                                                      • Element-Types of Arrays
                                                                                                      • +
                                                                                                      • Fixed-Size Arrays
                                                                                                      • +
                                                                                                      • Extensible Arrays
                                                                                                      • +
                                                                                                      • Fill-Pointers
                                                                                                      • +
                                                                                                      • Splicing Arrays
                                                                                                      • +
                                                                                                      • Splitting Arrays
                                                                                                      • +
                                                                                                      • Concatenating Arrays
                                                                                                      • +
                                                                                                      • Matrices
                                                                                                      • +
                                                                                                      • Matrix Multiplication
                                                                                                      • +
                                                                                                      • Octet Vectors
                                                                                                      • +
                                                                                                      • Octet Vectors and Streams
                                                                                                      • +
                                                                                                      +

                                                                                                      Exercise 1.7.1

                                                                                                      +

                                                                                                      Sequences Revisited: Arrays and Vectors

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.2

                                                                                                      +

                                                                                                      Arrays

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.3

                                                                                                      +

                                                                                                      More Arrays: Element-Type

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.4

                                                                                                      +

                                                                                                      More Arrays: Dimension

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.5

                                                                                                      +

                                                                                                      More Arrays: Extensible

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.6

                                                                                                      +

                                                                                                      More Arrays: Fill-Pointers

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.7

                                                                                                      +

                                                                                                      Splicing Arrays

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.8

                                                                                                      +

                                                                                                      Splitting Arrays

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.9

                                                                                                      +

                                                                                                      Concatenating Arrays

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.10

                                                                                                      +

                                                                                                      Matrices

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.11

                                                                                                      +

                                                                                                      Matrix Multiplication

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.12

                                                                                                      +

                                                                                                      Octet-Vectors

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.13

                                                                                                      +

                                                                                                      More Octet-Vectors

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      +

                                                                                                      Exercise 1.7.14

                                                                                                      +

                                                                                                      Vectors and Binary Streams

                                                                                                      +
                                                                                                      
                                                                                                      +
                                                                                                      +
                                                                                                      + + +
                                                                                                      + +
                                                                                                      +
                                                                                                      +
                                                                                                      + +

                                                                                                      results matching ""

                                                                                                      +
                                                                                                        + +
                                                                                                        +
                                                                                                        + +

                                                                                                        No results matching ""

                                                                                                        + +
                                                                                                        +
                                                                                                        +
                                                                                                        + +
                                                                                                        +
                                                                                                        + +
                                                                                                        + + + + + + + + + + + + + + +
                                                                                                        + + +
                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-08-0-variables.html b/clones/llthw.common-lisp.dev/1-08-0-variables.html new file mode 100644 index 00000000..8294c360 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-08-0-variables.html @@ -0,0 +1,1900 @@ + + + + + + + Variables, Parameters, and Constants ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                        +
                                                                                                        + + + + + + + + +
                                                                                                        + +
                                                                                                        + +
                                                                                                        + + + + + + + + +
                                                                                                        +
                                                                                                        + +
                                                                                                        +
                                                                                                        + +
                                                                                                        + +

                                                                                                        Chapter 1.8

                                                                                                        +

                                                                                                        Variables, Parameters, and Constants

                                                                                                        +
                                                                                                        +

                                                                                                        "In a dilemma, it is helpful to change any variable, then reexamine the problem."

                                                                                                        +
                                                                                                        Robert A. Heinlein, Have Space Suit---Will Travel
                                                                                                        + +
                                                                                                        +

                                                                                                        By this point, you may be pretty tired of having to manually re-type all your data every time you want to use them---but don't worry, you won't have to do that anymore. Whenever you want to use or re-use data---say, a string, number, list, or whatever else your program might need to pass around---you can bind a symbol and assign a value to it.

                                                                                                        +

                                                                                                        In keeping with the idea that "Lisp is different," variables are very different in Lisp from other programming languages. Some Lisp Hackers like to compare them to pointers in C and C++, but I have found that such a comparison overcomplicates a much simpler system. Once you know that the variable's symbol is not the variable itself, it is easy to see that the variable's assignment is a literal pointer to a memory address, without worrying about the extra complications that come with pointers in C or C++.

                                                                                                        +

                                                                                                        You may have also heard that Common Lisp is a "Lisp-2"; while all Lisp-family languages have lexical scope---a neat feature that we will cover in this chapter's exercises as well as extend upon in the following chapter---other Lisps such as Clojure, Scheme, Racket, and Emacs Lisp don't have separate namespaces for variables and functions within the same lexical scope. So, for example, in Common Lisp you can have both a function and a variable with the same name in the same scope; context tells the Lisp reader which definition to use.

                                                                                                        +

                                                                                                        This chapter will contain exercises on:

                                                                                                        +
                                                                                                          +
                                                                                                        • Symbols
                                                                                                        • +
                                                                                                        • Binding and Assignment
                                                                                                        • +
                                                                                                        • (Global) Dynamic Variables
                                                                                                        • +
                                                                                                        • (Local) Lexical Variables
                                                                                                        • +
                                                                                                        • Re-assigning Values to Variables
                                                                                                        • +
                                                                                                        • Parameters
                                                                                                        • +
                                                                                                        • Constants
                                                                                                        • +
                                                                                                        +

                                                                                                        Exercise 1.8.1

                                                                                                        +

                                                                                                        Symbols

                                                                                                        +
                                                                                                        
                                                                                                        +(intern "FOO")
                                                                                                        +FOO
                                                                                                        +NIL
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.2

                                                                                                        +

                                                                                                        Symbol Tables and Inspecting Objects

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.3

                                                                                                        +

                                                                                                        More Symbols: Binding and Assignment

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.4

                                                                                                        +

                                                                                                        Even More Symbols: Namespaces

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.5

                                                                                                        +

                                                                                                        DEFVAR: Dynamic Binding of Variables

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.6

                                                                                                        +

                                                                                                        LET: Lexical Binding of Variables

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.7

                                                                                                        +

                                                                                                        SETQ vs SETF

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.8

                                                                                                        +

                                                                                                        DEFPARAMETER: Dynamic Binding Revisited

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.9

                                                                                                        +

                                                                                                        DEFCONSTANT

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        +

                                                                                                        Exercise 1.8.10

                                                                                                        +

                                                                                                        Function Parameters

                                                                                                        +
                                                                                                        
                                                                                                        +
                                                                                                        +
                                                                                                        + + +
                                                                                                        + +
                                                                                                        +
                                                                                                        +
                                                                                                        + +

                                                                                                        results matching ""

                                                                                                        +
                                                                                                          + +
                                                                                                          +
                                                                                                          + +

                                                                                                          No results matching ""

                                                                                                          + +
                                                                                                          +
                                                                                                          +
                                                                                                          + +
                                                                                                          +
                                                                                                          + +
                                                                                                          + + + + + + + + + + + + + + +
                                                                                                          + + +
                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-09-0-closures.html b/clones/llthw.common-lisp.dev/1-09-0-closures.html new file mode 100644 index 00000000..9187d6f8 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-09-0-closures.html @@ -0,0 +1,1917 @@ + + + + + + + Extra Credit: Closures ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                          +
                                                                                                          + + + + + + + + +
                                                                                                          + +
                                                                                                          + +
                                                                                                          + + + + + + + + +
                                                                                                          +
                                                                                                          + +
                                                                                                          +
                                                                                                          + +
                                                                                                          + +

                                                                                                          Chapter 1.9 --- Extra Credit

                                                                                                          +

                                                                                                          Closures

                                                                                                          +
                                                                                                          +

                                                                                                          "Everything is theoretically impossible, until it is done."

                                                                                                          +
                                                                                                          Robert A. Heinlein, The Rolling Stones
                                                                                                          + +
                                                                                                          +

                                                                                                          One of the neater features of Lisp that result from lexical scope are Closures---you may have even heard of them before, since "closure" has been a big buzz-word in the tech world lately---particularly in the Node.js community. In the jargon of Computer Science, a Closure is a lambda expression (or, anonymous function), which has its open bindings bound in the lexical environment where it was defined. For now, you can think of them as a means to preserve state in functional programming.

                                                                                                          +

                                                                                                          Closures were first developed to manually evaluate expressions in Lambda Calculus, and included as a language feature in the first version of Scheme. The feature was added to Common Lisp during the ANSI standardization process, and nowadays can be found in all Lisp-family languages. Naturally, they are also fully supported in Erlang and Haskell. This feature has become so popular in recent years that it has been adopted and shimmied into many other programming and scripting languages, including C++11, Java 8, JavaScript, EcmaScript, Smalltalk, ML, Ruby, Perl, Objective-C (and the Apple extensions to C and C++), C#, D, Swift, and to a limited extent, Python---although the S-Expression syntax of Lisp-family languages makes Closures far more natural to express than with the syntaxes of other languages.

                                                                                                          +

                                                                                                          In this chapter we will further explore the concepts of dynamic and lexical scope, introduce the concept of first-class functions, and walk through a number of interesting examples of Closures to make sure you have a good understanding of their use and potential. You'll also get a sneak peak at functions, giving you more confidence in the material before you tackle the next chapter!

                                                                                                          +

                                                                                                          Exercise 1.9.1

                                                                                                          +

                                                                                                          Lexical Environments and Scope

                                                                                                          +
                                                                                                          ;; let's look at lexical scoping
                                                                                                          +(let ((one 1))
                                                                                                          +  (let ((two (+ one one)))
                                                                                                          +    (let ((three (+ one two)))
                                                                                                          +      (let ((one 1.0))
                                                                                                          +        (+ one two three)))))
                                                                                                          +6.0
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.2

                                                                                                          +

                                                                                                          LET Revisited

                                                                                                          +
                                                                                                          (let ((one 1)
                                                                                                          +      (two 2)
                                                                                                          +      (three 3))
                                                                                                          +  (- three two one))
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.3

                                                                                                          +

                                                                                                          LET*: Nested Lexical Scope

                                                                                                          +
                                                                                                          (let* ((one 1)
                                                                                                          +       (two (+ one one))
                                                                                                          +       (three (+ two one)))
                                                                                                          +  (* three three))
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.4

                                                                                                          +

                                                                                                          Pure Functions

                                                                                                          +
                                                                                                            +
                                                                                                          • No side-effects
                                                                                                          • +
                                                                                                          • No reliance on external state
                                                                                                          • +
                                                                                                          • Same input => same output, every time
                                                                                                          • +
                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.5

                                                                                                          +

                                                                                                          First-Class Functions

                                                                                                          +

                                                                                                          Functions can be passed as an argument to another function.

                                                                                                          +
                                                                                                          (map 'vector #'+ '(1 2 3 4) '(10 20 30 40))
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.6

                                                                                                          +

                                                                                                          Functors: Function Objects

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.7

                                                                                                          +

                                                                                                          LABEL and BLOCK

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.8

                                                                                                          +

                                                                                                          Functions as Arguments

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.9

                                                                                                          +

                                                                                                          Your First Closure

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.10

                                                                                                          +

                                                                                                          Dancing Closures

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.11

                                                                                                          +

                                                                                                          The Macroexpansion of DEFUN

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.12

                                                                                                          +

                                                                                                          Extending Closures: Continuations

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          +

                                                                                                          Exercise 1.9.13

                                                                                                          +

                                                                                                          Extending Closures: Partials

                                                                                                          +
                                                                                                          
                                                                                                          +
                                                                                                          +
                                                                                                          + + +
                                                                                                          + +
                                                                                                          +
                                                                                                          +
                                                                                                          + +

                                                                                                          results matching ""

                                                                                                          +
                                                                                                            + +
                                                                                                            +
                                                                                                            + +

                                                                                                            No results matching ""

                                                                                                            + +
                                                                                                            +
                                                                                                            +
                                                                                                            + +
                                                                                                            +
                                                                                                            + +
                                                                                                            + + + + + + + + + + + + + + +
                                                                                                            + + +
                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-10-0-functions.html b/clones/llthw.common-lisp.dev/1-10-0-functions.html new file mode 100644 index 00000000..f6789d1f --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-10-0-functions.html @@ -0,0 +1,1936 @@ + + + + + + + Functions and Macros ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                            +
                                                                                                            + + + + + + + + +
                                                                                                            + +
                                                                                                            + +
                                                                                                            + + + + + + + + +
                                                                                                            +
                                                                                                            + +
                                                                                                            +
                                                                                                            + +
                                                                                                            + +

                                                                                                            Chapter 1.10

                                                                                                            +

                                                                                                            Functions and Macros

                                                                                                            +
                                                                                                            +

                                                                                                            "The greatest productive force is human selfishness."

                                                                                                            +
                                                                                                            Robert A. Heinlein, Time Enough For Love
                                                                                                            + +
                                                                                                            +

                                                                                                            At the end of the day, most of the Lisp code you write will probably be Function or Macro definitions; after all, not only will they finally enable you to start doing some interesting programming, they are---arguably---the core of Lambda Calculus, Functional Programming, and the Lisp-family of programming languages. Even if you choose to favor Object-Oriented Programming as your go-to paradigm, you'll be using what you've learned here in this chapter.

                                                                                                            +

                                                                                                            You've already seen some functions and macros in action; other than the low-level special forms, most of the Lisp language as defined in the ANSI Standard is actually implemented in Common Lisp as functions in the COMMON-LISP package---in other words, Common Lisp is primarily a self-defined language, built on top of a small set of primitives. When working at the REPL, these functions are all imported for you into your own personal namespace, CL-USER. But some of the Common Lisp language is also implemented as Macros---remember with-open-file? That is a common use of Macros as used in the Common Lisp language itself, with-... forms. But also, every definition form, even defun and defmacro, are also macros themselves.

                                                                                                            +

                                                                                                            You can think of Functions as lexically closed blocks of code. You write functions to extend the vocabulary of Lisp.

                                                                                                            +

                                                                                                            Macros are, at least on the surface, very similar to functions; however, they also allow the programmer to use backtick syntax, a highly expressive notation for marking-up code transformation. Due to the expressive power of macros in Common Lisp, you can say that Lisp macros not only allow you to extend the vocabulary, but also modify the syntax of Lisp to your heart's desire. Macros are often used to reduce repetitive, predictable code to a single line; combine related functionality into a simple call that expands into Lisp procedurally based on input; and for writing Domain-Specific Languages, a topic we will cover exclusively in Chapter 1.19.

                                                                                                            +

                                                                                                            For now, we will focus on the core of writing anonymous and named functions with dynamic and lexical scope, writing recursive functions, tail-call optimization, and writing your first macros to keep your code tidy and expressive.

                                                                                                            +

                                                                                                            This chapter will contain exercises on:

                                                                                                            +
                                                                                                              +
                                                                                                            • LAMBDA: Anonymous Functions
                                                                                                            • +
                                                                                                            • Global Functions/top-level forms
                                                                                                            • +
                                                                                                            • Local Functions/lexical forms
                                                                                                            • +
                                                                                                            • Recursive Functions
                                                                                                            • +
                                                                                                            • Tail-Call Optimization
                                                                                                            • +
                                                                                                            • Defining Macros
                                                                                                            • +
                                                                                                            • Backtick syntax
                                                                                                            • +
                                                                                                            +

                                                                                                            Exercise 1.10.1

                                                                                                            +

                                                                                                            LAMBDA: Anonymous Functions

                                                                                                            +
                                                                                                            (lambda (x) (+ x x))
                                                                                                            +
                                                                                                            +((lambda (x) (+ x x)) 2)
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.2

                                                                                                            +

                                                                                                            More LAMBDA

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.3

                                                                                                            +

                                                                                                            Even More Lambda

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.4

                                                                                                            +

                                                                                                            DEFUN: Function Definitions

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.5

                                                                                                            +

                                                                                                            More DEFUN

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.6

                                                                                                            +

                                                                                                            Even More DEFUN

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.7

                                                                                                            +

                                                                                                            FLET: Lexical Function Definitions

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.8

                                                                                                            +

                                                                                                            Recursive Functions

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.9

                                                                                                            +

                                                                                                            More Recursive Functions

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.10

                                                                                                            +

                                                                                                            The Y-Combinator: Recursive Anonymous Functions

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.11

                                                                                                            +

                                                                                                            Tail-Call Optimization

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.12

                                                                                                            +

                                                                                                            Defining Macros

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.13

                                                                                                            +

                                                                                                            Macro Expansion

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.14

                                                                                                            +

                                                                                                            Backtick Syntax

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.15

                                                                                                            +

                                                                                                            Unquoting

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.16

                                                                                                            +

                                                                                                            Splicing

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            +

                                                                                                            Exercise 1.10.17

                                                                                                            +

                                                                                                            Nested Expansions

                                                                                                            +
                                                                                                            
                                                                                                            +
                                                                                                            +
                                                                                                            + + +
                                                                                                            + +
                                                                                                            +
                                                                                                            +
                                                                                                            + +

                                                                                                            results matching ""

                                                                                                            +
                                                                                                              + +
                                                                                                              +
                                                                                                              + +

                                                                                                              No results matching ""

                                                                                                              + +
                                                                                                              +
                                                                                                              +
                                                                                                              + +
                                                                                                              +
                                                                                                              + +
                                                                                                              + + + + + + + + + + + + + + +
                                                                                                              + + +
                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-11-0-text-adventure.html b/clones/llthw.common-lisp.dev/1-11-0-text-adventure.html new file mode 100644 index 00000000..64eaf234 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-11-0-text-adventure.html @@ -0,0 +1,1906 @@ + + + + + + + Extra Credit: A Simple Text Adventure ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                              +
                                                                                                              + + + + + + + + +
                                                                                                              + +
                                                                                                              + +
                                                                                                              + + + + + + + + +
                                                                                                              +
                                                                                                              + +
                                                                                                              +
                                                                                                              + +
                                                                                                              + +

                                                                                                              Chapter 1.11 --- Extra Credit

                                                                                                              +

                                                                                                              A Simple Text Adventure

                                                                                                              +
                                                                                                              +

                                                                                                              "Morals—all correct moral laws—derive from the instinct to survive. Moral behavior is survival behavior above the individual level."

                                                                                                              +
                                                                                                              Robert A. Heinlein, Starship Troopers
                                                                                                              + +
                                                                                                              +

                                                                                                              Now that you're about half-way through Part One, it's time to have a little fun and write a game. You now know how to write your own functions to extend the Lisp language, write macros that expand into the code you need at compile-time, store your data in variables, prompt your users for input, and do some fun stuff with math and strings---so now it's time to put it all together to write a classic console text-based Adventure game that you can share with your friends, family, and other L(λ)THW students.

                                                                                                              +

                                                                                                              A really important aspect of this chapter is to write a game of your very own---but first you need to understand the steps required to write a game of any kind. As such, you'll have to go through this chapter at least twice---the first time, follow along with me and implement the game exactly as I have, and stick to the five steps of the Hard Way methodology as normal; the second time, replace my game's theme, story, characters, and world with your own, and get creative with the code---experiment, innovate, and don't be afraid to break the program, take this as an opportunity to practice your debugging skills too.

                                                                                                              +

                                                                                                              Once you're done working through this chapter for the second time and you get your own unique game to run, and you can play through it from beginning to end, feel free to create a repo or gist and share it in the comments below. But remember, no cheating! Make sure you've gone through this chapter at least twice, and successfully played through your own game, before you poke around through other people's code for ideas.

                                                                                                              +
                                                                                                              + Note: +

                                                                                                              This chapter will guide you through writing a straightforward, hard-coded game; in other words, it will have to be recompiled every time you make a change to the source. This doesn't necessarily represent best practices for game development. In Parts Two and Three, alternate implementations of game engines will be presented that will load game resources on the fly from your computer's file system, so that you only have to re-compile the game when you change the program logic, and not the game content. +

                                                                                                              + +

                                                                                                              This chapter will contain exercises on:

                                                                                                              +
                                                                                                                +
                                                                                                              • ASCII-art and Text Adventure Aesthetics
                                                                                                              • +
                                                                                                              • Building your game interface
                                                                                                              • +
                                                                                                              • Your game's theme, story, and characters
                                                                                                              • +
                                                                                                              • Your game's world
                                                                                                              • +
                                                                                                              • Movement through the game world
                                                                                                              • +
                                                                                                              • Interacting with the game world
                                                                                                              • +
                                                                                                              • Collecting and using items in the game world
                                                                                                              • +
                                                                                                              • Non-player Characters
                                                                                                              • +
                                                                                                              • Quick and Dirty AI enemies
                                                                                                              • +
                                                                                                              • Packaging and Running your game
                                                                                                              • +
                                                                                                              +

                                                                                                              Exercise 1.11.1

                                                                                                              +

                                                                                                              ASCII-Art and ANSI Escape Codes

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.2

                                                                                                              +

                                                                                                              The Game Interface

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.3

                                                                                                              +

                                                                                                              Theme, Story, and Characters

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.4

                                                                                                              +

                                                                                                              The Game World

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.5

                                                                                                              +

                                                                                                              Movement in the Game World

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.6

                                                                                                              +

                                                                                                              Interacting with the Game World

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.7

                                                                                                              +

                                                                                                              Collecting and Using Items in the Game World

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.8

                                                                                                              +

                                                                                                              Non-Player Characters

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.9

                                                                                                              +

                                                                                                              Quick and Dirty AI Enemies

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              +

                                                                                                              Exercise 1.11.10

                                                                                                              +

                                                                                                              Packaging and Running Your Game

                                                                                                              +
                                                                                                              
                                                                                                              +
                                                                                                              +
                                                                                                              + + +
                                                                                                              + +
                                                                                                              +
                                                                                                              +
                                                                                                              + +

                                                                                                              results matching ""

                                                                                                              +
                                                                                                                + +
                                                                                                                +
                                                                                                                + +

                                                                                                                No results matching ""

                                                                                                                + +
                                                                                                                +
                                                                                                                +
                                                                                                                + +
                                                                                                                +
                                                                                                                + +
                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                + + +
                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-12-0-namespaces.html b/clones/llthw.common-lisp.dev/1-12-0-namespaces.html new file mode 100644 index 00000000..7916706e --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-12-0-namespaces.html @@ -0,0 +1,2351 @@ + + + + + + + Namespaces, Symbols, Packages, and Systems ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                +
                                                                                                                + + + + + + + + +
                                                                                                                + +
                                                                                                                + +
                                                                                                                + + + + + + + + +
                                                                                                                +
                                                                                                                + +
                                                                                                                +
                                                                                                                + +
                                                                                                                + +

                                                                                                                Chapter 1.12

                                                                                                                +

                                                                                                                Namespaces, Symbols, Packages, and Systems

                                                                                                                +
                                                                                                                +

                                                                                                                "Every law that was ever written opened up a new way to graft."

                                                                                                                +
                                                                                                                Robert A. Heinlein, Red Planet
                                                                                                                + +
                                                                                                                +

                                                                                                                As briefly introduced in previous chapters, Common Lisp is a Lisp-2: that is to say, within any given package, you can use the same symbol to refer to both a function and a variable, if you like, because functions and variables have separate namespaces. The namespaces for functions and variables are managed by the symbol object itself, which exist within a package.

                                                                                                                +

                                                                                                                Obviously, scope is important too. A symbol inside a function body may not have the same definition as in the top-level. This is by design---and whenever you use a symbol, it is important to remember dynamic and lexical scope. Not all enclosing forms introduce a new lexical scope like defun does.

                                                                                                                +

                                                                                                                So, as you can see, what a symbol happens to mean is highly contextual---and for the most part, the Lisp reader is very good at figuring out which definition of a symbol you happen to mean in any given context. When you want to stray from the norm, Lisp has tools to help you be more specific.

                                                                                                                +

                                                                                                                We will also cover some basic aspects of packaging your Lisp code for the wild, and working with ASDF and the Quicklisp package manager built on top of it.

                                                                                                                +

                                                                                                                Exercise 1.12.1

                                                                                                                +

                                                                                                                Dynamic and Lexical Scope, Revisited

                                                                                                                +

                                                                                                                All symbols in Common Lisp are namespaced in packages, and within a namespace, symbols are also scoped. Scope refers to how the Lisp reader looks up symbol definitions in the current environment.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (defparameter one #x01)
                                                                                                                +
                                                                                                                +(let ((one 1))
                                                                                                                +  (let ((one 1.0))
                                                                                                                +    (let ((one "one"))
                                                                                                                +      (format t "~a~%" one))
                                                                                                                +    (format t "~a~%" one))
                                                                                                                +  (format t "~a~%" one))
                                                                                                                +
                                                                                                                +(format t "#x~X~%" one)
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                * (defparameter one #x01)
                                                                                                                +ONE
                                                                                                                +
                                                                                                                +* (let ((one 1))
                                                                                                                +    (let ((one 1.0))
                                                                                                                +      (let ((one "one"))
                                                                                                                +        (format t "~a~%" one))
                                                                                                                +      (format t "~a~%" one))
                                                                                                                +    (format t "~a~%" one))
                                                                                                                +one
                                                                                                                +1.0
                                                                                                                +1
                                                                                                                +NIL
                                                                                                                +
                                                                                                                +* (format t "#x~2,'0,,X~%" one)
                                                                                                                +#x01
                                                                                                                +NIL
                                                                                                                +
                                                                                                                +

                                                                                                                There are two flavours of scope---dynamic and lexical. Lexical scope is tightly integrated with the structure of Lisp code and the lambda calculus from which it descends; it is spatial to the establishing form. Dynamic scope is special, because it has indefinite scope and dynamic extent, which is to say that dynamically scoped symbols are not lexically contained to their establishing form and they live in the dynamic environment.

                                                                                                                +

                                                                                                                Remember that Lexical Scope shadows Dynamic scope, as well as surrounding lexical scopes. Unless you specify otherwise, the innermost binding of a symbol is the one that is found by the Lisp reader.

                                                                                                                +

                                                                                                                Exercise 1.12.2

                                                                                                                +

                                                                                                                Implicit Lexical Scope

                                                                                                                +

                                                                                                                Many forms in Common Lisp introduce an implicit lexical scope. That is, you do not have explicitly call a let or flet to introduce a new nested scope; they provide a means for binding and assignment that is more intuitive for their particular use-case. You have already seen a few of these forms, like the DEFUN macro. You will also find implicit lexical scoping in BLOCK forms, and destructuring macros such as DESTRUCTURING-BIND, to name a few.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (block ta-da!
                                                                                                                +  (cond ((= (+ 1 1) 2)
                                                                                                                +         (return-from ta-da! t))
                                                                                                                +        ((= (+ 1 1) 3)
                                                                                                                +         (return-from ta-da! nil))
                                                                                                                +        (t
                                                                                                                +         (return-from ta-da! "Wait, what?"))))
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                (block ta-da!
                                                                                                                +  (cond ((= (+ 1 1) 2)
                                                                                                                +         (return-from ta-da! t))
                                                                                                                +        ((= (+ 1 1) 3)
                                                                                                                +         (return-from ta-da! nil))
                                                                                                                +        (t
                                                                                                                +         (return-from ta-da! "Wait, what?"))))
                                                                                                                +T
                                                                                                                +
                                                                                                                +

                                                                                                                Exercise 1.12.3

                                                                                                                +

                                                                                                                Function and Variable Namespaces, Revisited

                                                                                                                +

                                                                                                                Common Lisp has seprate namespaces for Functions and Variables. This means that you can define a function and variable within the same dynamic or lexical scope that share the same symbol name, and Lisp will generally figure out on its own which you mean by its context---i.e., where in an S-Expression the symbol appears.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (defparameter nonce 1.4)
                                                                                                                +
                                                                                                                +(defun nonce (n)
                                                                                                                +  (* (random 128) n))
                                                                                                                +
                                                                                                                +(inspect 'nonce)
                                                                                                                +> 2
                                                                                                                +> u
                                                                                                                +> 3
                                                                                                                +> 0
                                                                                                                +> u
                                                                                                                +> 1
                                                                                                                +> q
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +

                                                                                                                You can inspect any object in Lisp. When you inspect a symbol, you get its symbol table in the form of a menu with a new prompt, >. This allows you to choose an entry in the table by number, and see more information about it. You can return to the Common Lisp REPL by entering q, or navigate back up a level with u. When you've defined both a variable and a function with the same name, you can then see them both in the symbol table and inspect every object that they consist of.

                                                                                                                +
                                                                                                                (defparameter nonce 1.4)
                                                                                                                +NONCE
                                                                                                                +
                                                                                                                +(defun nonce (n)
                                                                                                                +  (* (random 128) n))
                                                                                                                +NONCE
                                                                                                                +
                                                                                                                +(inspect 'nonce)
                                                                                                                +The object is a SYMBOL.
                                                                                                                +0. Name: "NONCE"
                                                                                                                +1. Package: #<PACKAGE "COMMON-LISP-USER">
                                                                                                                +2. Value: 1.4
                                                                                                                +3. Function: #<FUNCTION NONCE>
                                                                                                                +4. Plist: NIL
                                                                                                                +> 2
                                                                                                                +
                                                                                                                +The object is an ATOM:
                                                                                                                +  1.4
                                                                                                                +> u
                                                                                                                +...
                                                                                                                +
                                                                                                                +> 3
                                                                                                                +
                                                                                                                +The object is a FUNCTION named NONCE.
                                                                                                                +0. Lambda-list: (N)
                                                                                                                +1. Ftype: (FUNCTION (T) (VALUES NUMBER &OPTIONAL))
                                                                                                                +> 0
                                                                                                                +
                                                                                                                +The object is a CONS.
                                                                                                                +0. CAR: N
                                                                                                                +1. CDR: NIL
                                                                                                                +> u
                                                                                                                +...
                                                                                                                +
                                                                                                                +> 1
                                                                                                                +
                                                                                                                +The object is a proper list of length 3.
                                                                                                                +0. 0: FUNCTION
                                                                                                                +1. 1: (T)
                                                                                                                +2. 2: (VALUES NUMBER &OPTIONAL)
                                                                                                                +> q
                                                                                                                +
                                                                                                                +

                                                                                                                Exercise 1.12.4

                                                                                                                +

                                                                                                                First-Class Functions

                                                                                                                +

                                                                                                                As mentioned in the previous exercise, Lisp will assume that when a symbol appears in the operator position of a list, it refers to a function, and when it appears in the lambda list, it refers to the variable value. But Common Lisp supports first-class functions, so naturally there must be a way, in parameter position, for the Lisp reader to recognize when you mean the function namespace in parameter position.

                                                                                                                +

                                                                                                                This is the reader macro #'. Prepend it to a symbol, and the Lisp reader will know to treat that parameter as a first-class function instead of as a variable.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (mapcar #'nonce '(128 123 118 113 108 103 98 93))
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                * (mapcar #'nonce '(128 123 118 113 108 103 98 93))
                                                                                                                +(13184 12300 10502 13786 3564 1751 4998 5115)
                                                                                                                +
                                                                                                                +

                                                                                                                First-class functions are very different than a function application that happens to be in parameter position. Lisp code is evaluated innermost-form first, so a form in source-code can almost always be replaced by its return value---and as far as Lisp is concerned, it is. This is known in Comp-Sci parlance as "pass-by-value" or "call-by-value", which is to say that a form is actually evaluated to a result, and the result itself is passed to the parent form and copied---anything done to that value has no effect on the original. For a function application, this doesn't mean much because the evaluation usually computes this original value in the first place---but for first-class function objects and variables, this is quite important.

                                                                                                                +

                                                                                                                Exercise 1.12.5

                                                                                                                +

                                                                                                                Symbol Names

                                                                                                                +

                                                                                                                Symbol names are stored as case-sensitive strings in the symbol table. Typically, the Lisp reader upcases symbol-names when a symbol is created unless forced to do otherwise, such as with the INTERN function.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (symbol-name 'pi)
                                                                                                                +
                                                                                                                +(intern "myCamelCaseSymbol")
                                                                                                                +
                                                                                                                +(symbol-name '|myCamelCaseSymbol|)
                                                                                                                +
                                                                                                                +(symbol-name 'cl-user::|myCamelCaseSymbol|)
                                                                                                                +
                                                                                                                +(export '|myCamelCaseSymbol|)
                                                                                                                +
                                                                                                                +(symbol-name 'cl-user:|myCamelCaseSymbol|)
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                (symbol-name 'pi)
                                                                                                                +"PI"
                                                                                                                +
                                                                                                                +(intern "myCamelCaseSymbol")
                                                                                                                +|myCamelCaseSymbol|
                                                                                                                +NIL
                                                                                                                +
                                                                                                                +(symbol-name '|myCamelCaseSymbol|)
                                                                                                                +"myCamelCaseSymbol"
                                                                                                                +
                                                                                                                +;; this symbol hasn't been exported yet, so we have to refer to it using package-internal namespacing
                                                                                                                +(symbol-name 'cl-user::|myCamelCaseSymbol|)
                                                                                                                +"myCamelCaseSymbol"
                                                                                                                +
                                                                                                                +(export '|myCamelCaseSymbol|)
                                                                                                                +T
                                                                                                                +
                                                                                                                +;; now that we've exported |myCamelCaseSymbol|, we can call it with package-external namespacing and import it into other packages
                                                                                                                +(symbol-name 'cl-user:|myCamelCaseSymbol|)
                                                                                                                +"myCamelCaseSymbol"
                                                                                                                +
                                                                                                                +

                                                                                                                Symbols exist within packages, so their full name is prefixed with their package. When your working package is the same namespace as where the symbol was interned, you can omit the package prefix---but it is still there.

                                                                                                                +

                                                                                                                Exercise 1.12.6

                                                                                                                +

                                                                                                                Packages

                                                                                                                +

                                                                                                                In addition to the separate Function and Variable namespaces offered by Common Lisp, your code can be organized into packages. Packages allow you to design an interface to your code-base under a common name, separating the functions, variables, and other units of code from the Common Lisp language and from other libraries; as a result, they can help eliminate symbol collision as well.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (defpackage my-new-package)
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +
                                                                                                                +(cl:defparameter *hello-world*
                                                                                                                +  (cl:format cl:nil "Hello ~A!" 'multiverse))
                                                                                                                +
                                                                                                                +(cl:export '*hello-world*)
                                                                                                                +
                                                                                                                +(cl:in-package :cl-user)
                                                                                                                +
                                                                                                                +my-new-package:*hello-world*
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +(defpackage my-new-package)
                                                                                                                +#<PACKAGE "MY-NEW-PACKAGE">
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +#<COMMON-LISP:PACKAGE "MY-NEW-PACKAGE">
                                                                                                                +
                                                                                                                +(cl:defparameter *hello-world*
                                                                                                                +  (cl:format cl:nil "Hello ~A!" 'multiverse))
                                                                                                                +*HELLO-WORLD*
                                                                                                                +
                                                                                                                +(cl:export '*hello-world*)
                                                                                                                +T
                                                                                                                +
                                                                                                                +(cl:in-package :cl-user)
                                                                                                                +#<PACKAGE "COMMON-LISP-USER">
                                                                                                                +
                                                                                                                +my-new-package:*hello-world*
                                                                                                                +"Hello MULTIVERSE!"
                                                                                                                +
                                                                                                                +

                                                                                                                Note how in your new package, you have to explicitly namespace-resolve symbols from the Common Lisp package now in order to use them. This can be both useful and irritating, so we will introduce how to use another package's exported symbols as if they were local symbols in a few exercises.

                                                                                                                +

                                                                                                                Exercise 1.12.7

                                                                                                                +

                                                                                                                More Packages: Nicknames

                                                                                                                +

                                                                                                                You can give your packages shorter, alternative nicknames which can be used for namespace-resolution on symbols, instead of having to type the full package name every single time. You have already seen this in the previous exercise, where you had to refer to Common Lisp functions and variables prefixed with cl. This is a package nickname for the COMMON-LISP package.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (defpackage my-new-package
                                                                                                                +  (:nicknames :mnp :newpack))
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +
                                                                                                                +(cl:defparameter *hello-world*
                                                                                                                +  (cl:format cl:nil "Hello ~A!" 'multiverse))
                                                                                                                +
                                                                                                                +(cl:in-package :cl-user)
                                                                                                                +
                                                                                                                +my-new-package::*hello-world*
                                                                                                                +
                                                                                                                +mnp::*hello-world*
                                                                                                                +
                                                                                                                +newpack::*hello-world*
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +

                                                                                                                You define a package's nicknames inside the defpackage macro. You can have as many nicknames as you want; but like package names themselves, they have to be unique.

                                                                                                                +
                                                                                                                (defpackage my-new-package
                                                                                                                +  (:nicknames :mnp :newpack))
                                                                                                                +#<PACKAGE "MY-NEW-PACKAGE">
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +#<COMMON-LISP:PACKAGE "MY-NEW-PACKAGE">
                                                                                                                +
                                                                                                                +(cl:defparameter *hello-world*
                                                                                                                +  (cl:format cl:nil "Hello ~A!" 'multiverse))
                                                                                                                +*HELLO-WORLD*
                                                                                                                +
                                                                                                                +(cl:in-package :cl-user)
                                                                                                                +#<PACKAGE "COMMON-LISP-USER">
                                                                                                                +
                                                                                                                +my-new-package::*hello-world*
                                                                                                                +"Hello MULTIVERSE!"
                                                                                                                +
                                                                                                                +mnp::*hello-world*
                                                                                                                +"Hello MULTIVERSE!"
                                                                                                                +
                                                                                                                +newpack::*hello-world*
                                                                                                                +"Hello MULTIVERSE!"
                                                                                                                +
                                                                                                                +

                                                                                                                Exercise 1.12.8

                                                                                                                +

                                                                                                                More Packages: Exporting Symbols

                                                                                                                +

                                                                                                                Technically, once a package and all its source code has been loaded into your Lisp image, you can call any unit of code within it by using the full symbol, <package-name>::<symbol-name>; but it is more convenient to export an interface to your users, which they can then import into their packages individually, or use your entire library's API.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (defpackage my-new-package
                                                                                                                +  (:nicknames :mnp :newpack)
                                                                                                                +  (:export #:*hello-world*))
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +
                                                                                                                +(cl:defparameter *hello-world*
                                                                                                                +  (cl:format cl:nil "Hello ~A!" 'multiverse))
                                                                                                                +
                                                                                                                +(cl:in-package :cl-user)
                                                                                                                +
                                                                                                                +my-new-package:*hello-world*
                                                                                                                +
                                                                                                                +mnp:*hello-world*
                                                                                                                +
                                                                                                                +newpack:*hello-world*
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                (defpackage my-new-package
                                                                                                                +  (:nicknames :mnp :newpack)
                                                                                                                +  (:export #:*hello-world*))
                                                                                                                +#<PACKAGE "MY-NEW-PACKAGE">
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +#<COMMON-LISP:PACKAGE "MY-NEW-PACKAGE">
                                                                                                                +
                                                                                                                +(cl:defparameter *hello-world*
                                                                                                                +  (cl:format cl:nil "Hello ~A!" 'multiverse))
                                                                                                                +*HELLO-WORLD*
                                                                                                                +
                                                                                                                +(cl:in-package :cl-user)
                                                                                                                +#<PACKAGE "COMMON-LISP-USER">
                                                                                                                +
                                                                                                                +my-new-package:*hello-world*
                                                                                                                +"Hello MULTIVERSE!"
                                                                                                                +
                                                                                                                +mnp:*hello-world*
                                                                                                                +"Hello MULTIVERSE!"
                                                                                                                +
                                                                                                                +newpack:*hello-world*
                                                                                                                +"Hello MULTIVERSE!"
                                                                                                                +
                                                                                                                +

                                                                                                                You can export your defined units of code either with the export form, or specifying symbols to export in your package definition; if you try to export the same symbol twice, once from the package definition and again with export form, you'll trigger a condition. Generally speaking it's considered best practice to export all your symbols from the package definition form, so that your library's API is clear and together in one place.

                                                                                                                +

                                                                                                                Exercise 1.12.9

                                                                                                                +

                                                                                                                More Packages: Using Other Packages

                                                                                                                +

                                                                                                                When you use a package in your package, you are telling Lisp to add all the exported symbols of that package to your current package-internal namespace, so that you can call any unit of code locally as if you defined it yourself in your current package.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                (defpackage my-new-package
                                                                                                                +  (:nicknames :mnp :newpack)
                                                                                                                +  (:use :cl :cl-user)
                                                                                                                +  (:export #:*hello-world*))
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +
                                                                                                                +(defparameter *hello-world*
                                                                                                                +  (format nil "Hello ~A!" 'multiverse))
                                                                                                                +
                                                                                                                +(in-package :cl-user)
                                                                                                                +
                                                                                                                +my-new-package:*hello-world*
                                                                                                                +
                                                                                                                +mnp:*hello-world*
                                                                                                                +
                                                                                                                +newpack:*hello-world*
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                (defpackage my-new-package
                                                                                                                +  (:nicknames :mnp :newpack)
                                                                                                                +  (:use :cl :cl-user)
                                                                                                                +  (:export #:*hello-world*))
                                                                                                                +
                                                                                                                +(in-package :my-new-package)
                                                                                                                +
                                                                                                                +(defparameter *hello-world*
                                                                                                                +  (format nil "Hello ~A!" 'multiverse))
                                                                                                                +
                                                                                                                +(in-package :cl-user)
                                                                                                                +
                                                                                                                +my-new-package:*hello-world*
                                                                                                                +
                                                                                                                +mnp:*hello-world*
                                                                                                                +
                                                                                                                +newpack:*hello-world*
                                                                                                                +
                                                                                                                +

                                                                                                                The first thing you should notice is that now you no longer have to refer to symbols from the Common Lisp language proper using their package namespace from within your new package. You will (almost) always want to, at minimum, use the COMMON-LISP package in your packages; and since you will be working a lot in the REPL from your new package, you will also want to use the COMMON-LISP-USER package as well, since in addition to the full Common Lisp language, it includes all the utilities that your Lisp implementation includes for a more complete experience.

                                                                                                                +

                                                                                                                While you develop your library, it can be useful to call out units of code from other packages and libraries explicitly, using their full package-namespaced symbol, so that there is no confusion on your dev team as to what code is being called---if you find that you're relying heavily enough on a library that typing out its package nickname before each symbol becomes tedious, annoying, and a source of existential woe, that is a good indicator the library should be used, and your full dev team made deeply familiar with its interface.

                                                                                                                +

                                                                                                                Once development is complete, you will want to remove the COMMON-LISP-USER package from your packages before release unless you explicitly need it.

                                                                                                                +

                                                                                                                Exercise 1.12.10

                                                                                                                +

                                                                                                                More Packages: Importing Specific Symbols

                                                                                                                +

                                                                                                                You won't always need to use a full library; more often than not, you will only need to import a handful of specific symbols. This is another advantage of typing out the full symbol, package namespace included, while developing your library---you can search through your source code for references to a given package, and make a judgment call as to whether you need to use it or only import the symbols you need. This helps to avoid cluttering your namespace, among other things.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Exercise 1.12.11

                                                                                                                +

                                                                                                                More Packages: Shadowing-Imports

                                                                                                                +

                                                                                                                Sometimes, you will come across naming collisions between libraries you need to use, which at first glance may seem to force you to manually import, symbol by symbol, everything from a library except the offender. That's not very efficient, however, so Lisp has you covered---you can shadow-import, which lets you tell Lisp exactly which symbol from which package you want to favour in the case of a naming collision.

                                                                                                                +

                                                                                                                In the REPL

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Extra Credit Exercise 1.12.12

                                                                                                                +

                                                                                                                ASDF and Systems

                                                                                                                +

                                                                                                                ASDF is, essentially, a build-system for Common Lisp---but that doesn't really do it justice. For our purposes, it is a necessary tool for defining libraries for the Quicklisp package manager.

                                                                                                                +

                                                                                                                ASDF focuses on the concept of a System. A System is a collection of Lisp source-code files, which may or may not include a number of packages, wrapped up with some meta-data.

                                                                                                                +

                                                                                                                ASDF Systems are typically defined in their own *.asd files, instead of *.lisp. However, they are still written using Common Lisp syntax.

                                                                                                                +

                                                                                                                In a New File

                                                                                                                +

                                                                                                                In your ~/quicklisp/local-projects/ directory, create a subdirectory called my-new-project/, and in it, create a new file called my-new-project.asd. The contents of this file should look like the following, with the appropriate personalizations completed:

                                                                                                                +
                                                                                                                (in-package :cl-user)
                                                                                                                +
                                                                                                                +(defpackage my-new-project-asd
                                                                                                                +  (:use :cl :cl-user :asdf))
                                                                                                                +
                                                                                                                +(in-package :my-new-project-asd)
                                                                                                                +
                                                                                                                +(defsystem my-new-project
                                                                                                                +  :version "1.0.0"
                                                                                                                +  :license "MIT"
                                                                                                                +  :author "A.B. <a.b@example.org>")
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Extra Credit Exercise 1.12.13

                                                                                                                +

                                                                                                                ASDF Systems: Dependencies

                                                                                                                +

                                                                                                                ASDF allows you to specify library dependencies in your system definition; the project will then not compile unless these dependencies are available. The Quicklisp package manager uses this information to automatically resolve all dependencies when quickloading a library.

                                                                                                                +

                                                                                                                If you use a library in any package within your project, you must include it in the system's :depends-on form, to ensure that it is available to your project wherever it is run or installed.

                                                                                                                +

                                                                                                                In the File

                                                                                                                +

                                                                                                                Revise my-new-project.asd to look like the following:

                                                                                                                +
                                                                                                                (in-package :cl-user)
                                                                                                                +
                                                                                                                +(defpackage my-new-project-asd
                                                                                                                +  (:use :cl :cl-user :asdf))
                                                                                                                +
                                                                                                                +(in-package :my-new-project-asd)
                                                                                                                +
                                                                                                                +(defsystem my-new-project
                                                                                                                +  :version "1.0.0"
                                                                                                                +  :license "MIT"
                                                                                                                +  :author "A.B. <a.b@example.org>"
                                                                                                                +  :depends-on (:ironclad))
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Extra Credit Exercise 1.12.14

                                                                                                                +

                                                                                                                ASDF Systems: Files

                                                                                                                +

                                                                                                                In the same directory as my-new-project.asd, create empty files for packages.lisp and my-new-project.lisp.

                                                                                                                +

                                                                                                                You don't have to specify that the files you're including in components are *.lisp files, you only have to specify their names, without the file extension.

                                                                                                                +

                                                                                                                In the File

                                                                                                                +

                                                                                                                Revise my-new-project.asd to look like the following:

                                                                                                                +
                                                                                                                (in-package :cl-user)
                                                                                                                +
                                                                                                                +(defpackage my-new-project-asd
                                                                                                                +  (:use :cl :cl-user :asdf))
                                                                                                                +
                                                                                                                +(in-package :my-new-project-asd)
                                                                                                                +
                                                                                                                +(defsystem my-new-project
                                                                                                                +  :version "1.0.0"
                                                                                                                +  :license "MIT"
                                                                                                                +  :author "A.B. <a.b@example.org>"
                                                                                                                +  :depends-on (:ironclad)
                                                                                                                +  :serial t
                                                                                                                +  :components ((:file "packages")
                                                                                                                +               (:file "my-new-project")))
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Extra Credit Exercise 1.12.15

                                                                                                                +

                                                                                                                ASDF Systems: Modules

                                                                                                                +

                                                                                                                Modules in ASDF system definitions correspond to subdirectories of your project folder. Your modules may correspond to their own packages---and this is a common design pattern---but they don't have to. This is fairly different from other programming languages, where project directory structure corresponds rigidly to namespacing. Lisp is more flexible---you can span your entire project with a single package namespace, you can give each and every file its own package, or anywhere in-between.

                                                                                                                +

                                                                                                                In the File

                                                                                                                +

                                                                                                                Revise my-new-project.asd to look like the following:

                                                                                                                +
                                                                                                                (in-package :cl-user)
                                                                                                                +
                                                                                                                +(defpackage my-new-project-asd
                                                                                                                +  (:use :cl :cl-user :asdf))
                                                                                                                +
                                                                                                                +(in-package :my-new-project-asd)
                                                                                                                +
                                                                                                                +(defsystem my-new-project
                                                                                                                +  :version "1.0.0"
                                                                                                                +  :license "MIT"
                                                                                                                +  :author "A.B. <a.b@example.org>"
                                                                                                                +  :depends-on (:ironclad)
                                                                                                                +  :serial t
                                                                                                                +  :components ((:file "packages")
                                                                                                                +               (:module "src"
                                                                                                                +                :serial t
                                                                                                                +                :components ((:file "utils")
                                                                                                                +                             (:file "api")))
                                                                                                                +               (:file "my-new-project")))
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                The important thing to remember about ASDF is that it has no bearing on your project's namespace and organization. It exists to collect metadata and compilation instructions---and it doesn't care about what packages you use, or how many. It only needs to know where to find your source-code to compile it, in the right order.

                                                                                                                +

                                                                                                                Extra Credit Exercise 1.12.16

                                                                                                                +

                                                                                                                ASDF Systems: Serial mode vs. Dependency Tree

                                                                                                                +

                                                                                                                You may have noticed in the preceding exercises a casual inclusion of the keyword :serial in the defsystem forms, set to t. This is actually quite significant, as it forces each sequential file and module in the system definition to be compiled in the order that they appear.

                                                                                                                +

                                                                                                                You do not have to serialize the compilation, however; and in some cases, you will not want to. For such cases, you can explicitly define a dependency tree for each file and module, so that ASDF can work its magic in optimizing the compilation process.

                                                                                                                +

                                                                                                                In the File

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                
                                                                                                                +
                                                                                                                +
                                                                                                                +

                                                                                                                Extra Credit Exercise 1.12.17

                                                                                                                +

                                                                                                                The Quicklisp Package Manager

                                                                                                                +

                                                                                                                Now that you have your new project configured for ASDF, you can automatically load it and all its dependencies into your current Lisp image through the Quicklisp package manager.

                                                                                                                +

                                                                                                                Quicklisp runs inside your Lisp image, not from the command-line.

                                                                                                                +

                                                                                                                From the REPL

                                                                                                                +
                                                                                                                (ql:quickload :my-new-project)
                                                                                                                +
                                                                                                                +(in-package :my-new-project)
                                                                                                                +
                                                                                                                +

                                                                                                                What You Should See

                                                                                                                +
                                                                                                                (ql:quickload :my-new-project)
                                                                                                                +To load "my-new-project":
                                                                                                                +  Load 1 ASDF system:
                                                                                                                +    my-new-project
                                                                                                                +; Loading "my-new-project"
                                                                                                                +..................................................
                                                                                                                +[package base58]..................................
                                                                                                                +[package cl-base64]...............................
                                                                                                                +[package nibbles].................................
                                                                                                                +[package ironclad]................................
                                                                                                                +..................................................
                                                                                                                +..................................................
                                                                                                                +..................................................
                                                                                                                +[package my-new-project]..
                                                                                                                +(:MY-NEW-PROJECT)
                                                                                                                +
                                                                                                                +(in-package :my-new-project)
                                                                                                                +#<PACKAGE "MY-NEW-PROJECT">
                                                                                                                +
                                                                                                                +

                                                                                                                It is considered best practice to not call Quicklisp inside your Lisp source-code, but to rely on ASDF and portable Common Lisp; for deploying executables, tools such as BUILDAPP will use Quicklisp automatically to retrieve dependencies and include them in your binary, without adding the overhead of the Quicklisp system to your binary. The Lisp API to Quicklisp, however, is very useful for testing, exploring, and interactively programming with Lisp libraries from the REPL. For example, you can now automatically load the library you've created in this chapter into a new Lisp image, and start playing with it right away.

                                                                                                                + + +
                                                                                                                + +
                                                                                                                +
                                                                                                                +
                                                                                                                + +

                                                                                                                results matching ""

                                                                                                                +
                                                                                                                  + +
                                                                                                                  +
                                                                                                                  + +

                                                                                                                  No results matching ""

                                                                                                                  + +
                                                                                                                  +
                                                                                                                  +
                                                                                                                  + +
                                                                                                                  +
                                                                                                                  + +
                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                  + + +
                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-13-0-simple-web-app.html b/clones/llthw.common-lisp.dev/1-13-0-simple-web-app.html new file mode 100644 index 00000000..9bf2e904 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-13-0-simple-web-app.html @@ -0,0 +1,1882 @@ + + + + + + + Extra Credit: A Simple Web Application ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                  +
                                                                                                                  + + + + + + + + +
                                                                                                                  + +
                                                                                                                  + +
                                                                                                                  + + + + + + + + +
                                                                                                                  +
                                                                                                                  + +
                                                                                                                  +
                                                                                                                  + +
                                                                                                                  + +

                                                                                                                  Chapter 1.13 --- Extra Credit

                                                                                                                  +

                                                                                                                  A Simple Web Application

                                                                                                                  +
                                                                                                                  +

                                                                                                                  "Life is short, but the years are long."

                                                                                                                  +
                                                                                                                  Robert A. Heinlein, Methuselah's Children
                                                                                                                  + +
                                                                                                                  +

                                                                                                                  Now that you've gotten a taste for Lisp, how would you like to write a web-app just like the Learn Lisp The Hard Way site? If you already know HTML5, CSS3, JavaScript, and one of the many options available for server-side Web Application programming available these days, such as Ruby on Rails, Python and Django, or PHP, you may be surprised, horrified, and maybe a little pleased to know that you can replace every disparate language of the Web with Common Lisp. And if you've never done any web development before, you can take a moment to celebrate that learning Lisp lets you program seamlessly everywhere.

                                                                                                                  +

                                                                                                                  I know, that might be a lot to take in all at once, so let's step back and say that again.

                                                                                                                  +

                                                                                                                  You can write a straightforward web application entirely in Common Lisp. You don't have to write any HTML, CSS, or JavaScript. Lisp can write the markup, styling, and scripting code for you.

                                                                                                                  +

                                                                                                                  You can take what you've learned so far about Macros in Lisp to bundle your template code into convenient Web UI widgets. Pair this with front-end JavaScript libraries such as Twitter Bootstrap, jQuery UI, or D3, and you have some pretty powerful UI tools with very little code.

                                                                                                                  +

                                                                                                                  And, if you were so inclined, you could even re-write popular front-end JavaScript libraries in Lisp, so that the end-user only has to download the rendered JavaScript code that they need for their browser and the widgets you've included in the current view, instead of the whole library. Mobile users with limited bandwidth will certainly thank you for the greatly improved browsing experience.

                                                                                                                  +

                                                                                                                  This chapter will contain exercises on:

                                                                                                                  +
                                                                                                                    +
                                                                                                                  • Sockets
                                                                                                                  • +
                                                                                                                  • Introducing Hunchentoot
                                                                                                                  • +
                                                                                                                  • Hunchentoot's Easy-Handler framework
                                                                                                                  • +
                                                                                                                  • Serving Static Files
                                                                                                                  • +
                                                                                                                  • REGEX Dispatchers
                                                                                                                  • +
                                                                                                                  • Intro to Domain-Specific Languages (more in Ch. 1.19)
                                                                                                                  • +
                                                                                                                  • Coding HTML5, CSS3, and JavaScript in Lisp
                                                                                                                  • +
                                                                                                                  • Parsing Markdown
                                                                                                                  • +
                                                                                                                  • Writing a simple web-app with Hunchentoot, CL-WHO, CL-CSS, Parenscript, and 3bmd
                                                                                                                  • +
                                                                                                                  +

                                                                                                                  Exercise 1.13.1

                                                                                                                  +

                                                                                                                  Sockets and Streams

                                                                                                                  +

                                                                                                                  Exercise 1.13.2

                                                                                                                  +

                                                                                                                  More Sockets

                                                                                                                  +

                                                                                                                  Exercise 1.13.3

                                                                                                                  +

                                                                                                                  More Sockets: A Simple Echo Server

                                                                                                                  +

                                                                                                                  Exercise 1.13.4

                                                                                                                  +

                                                                                                                  Introducing Hunchentoot

                                                                                                                  +

                                                                                                                  Exercise 1.13.5

                                                                                                                  +

                                                                                                                  Hunchentoot's Easy-Handler Framework

                                                                                                                  +

                                                                                                                  Exercise 1.13.6

                                                                                                                  +

                                                                                                                  Serving Static Files

                                                                                                                  +

                                                                                                                  Exercise 1.13.7

                                                                                                                  +

                                                                                                                  REGEX Dispatchers

                                                                                                                  +

                                                                                                                  Exercise 1.13.8

                                                                                                                  +

                                                                                                                  A Brief Introduction to Domain-Specific Languages

                                                                                                                  +

                                                                                                                  Exercise 1.13.9

                                                                                                                  +

                                                                                                                  CL-WHO: HTML5 in Lisp

                                                                                                                  +

                                                                                                                  Exercise 1.13.10

                                                                                                                  +

                                                                                                                  CL-CSS: CSS3 in Lisp

                                                                                                                  +

                                                                                                                  Exercise 1.13.11

                                                                                                                  +

                                                                                                                  Parenscript: JavaScript in Lisp

                                                                                                                  +

                                                                                                                  Exercise 1.13.12

                                                                                                                  +

                                                                                                                  3bmd: Parsing Markdown in Lisp

                                                                                                                  +

                                                                                                                  Exercise 1.13.13

                                                                                                                  +

                                                                                                                  Your First Web Application

                                                                                                                  +

                                                                                                                  Extra Credit Exercise 1.13.14

                                                                                                                  +

                                                                                                                  Configuring NGINX for Your Lisp Web App

                                                                                                                  +

                                                                                                                  Extra Credit Exercise 1.13.15

                                                                                                                  +

                                                                                                                  A Distributed Lisp Web Application

                                                                                                                  + + +
                                                                                                                  + +
                                                                                                                  +
                                                                                                                  +
                                                                                                                  + +

                                                                                                                  results matching ""

                                                                                                                  +
                                                                                                                    + +
                                                                                                                    +
                                                                                                                    + +

                                                                                                                    No results matching ""

                                                                                                                    + +
                                                                                                                    +
                                                                                                                    +
                                                                                                                    + +
                                                                                                                    +
                                                                                                                    + +
                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                    + + +
                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-14-0-conditionals.html b/clones/llthw.common-lisp.dev/1-14-0-conditionals.html new file mode 100644 index 00000000..4b59c355 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-14-0-conditionals.html @@ -0,0 +1,1890 @@ + + + + + + + Conditionals ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                    +
                                                                                                                    + + + + + + + + +
                                                                                                                    + +
                                                                                                                    + +
                                                                                                                    + + + + + + + + +
                                                                                                                    +
                                                                                                                    + +
                                                                                                                    +
                                                                                                                    + +
                                                                                                                    + +

                                                                                                                    Chapter 1.14

                                                                                                                    +

                                                                                                                    Conditionals

                                                                                                                    +
                                                                                                                    +

                                                                                                                    "Man is not a rational animal, he is a rationalizing animal."

                                                                                                                    +
                                                                                                                    Robert A. Heinlein, Assignment in Eternity
                                                                                                                    + +
                                                                                                                    +

                                                                                                                    There are a lot of times when you need to control if, when, or how a particular piece of code will be evaluated. Your code, after all, could depend on some file existing on your computer before it can run; or it expects a very specific type of data to work right; or maybe you need a very specific value, like the command parser of the Text Adventure we wrote a few chapters earlier. If you carefully consider your expectations ahead of time, and conditionalize your code accordingly, you can eliminate many common bugs before they become compiled into your application.

                                                                                                                    +

                                                                                                                    Conditionals are a loose, unofficial name for a subset of Control Flow functions in Common Lisp. Their purpose is to force Lisp to pass a test before they hand over the code inside for evaluation---if the test fails, then the code within is ignored. It's a simple idea, but an awfully important one.

                                                                                                                    +

                                                                                                                    These tests are called Predicate Functions. All they ever do is return t or nil, which in this context you can read as the boolean values True or False. Predicate Functions take one or more parameters that you want to test, and respond with the result of that test. Of course, in Lisp, everything that isn't nil (or its equivalent, the empty list '()), is descended from t in the type/class hierarchy---so a test can also be any function that returns an object if successful, or nil if it fails. This is useful, because it allows you to write a bare-bones simple test such as (if monkey ...); if you've bound the symbol monkey as a variable, and assigned it a value, monkey is seen as t---but if you've bound it and assigned nothing to it, then it will return nil, the test will fail, and the if form will skip past the implicit 'then' expression and look for an 'else' expression. The special operator if will be examined in detail later this chapter, after a deeper exploration of predicate functions.

                                                                                                                    +

                                                                                                                    All high-level programming languages have Conditionals by necessity for Turing Completeness---but Lisp really goes the extra mile, providing some unique conditional forms that you won't find elsewhere. And where Lisp doesn't provide an out-of-the-box solution, it is surprisingly easy to write the predicate functions and conditional forms you desire.

                                                                                                                    +

                                                                                                                    This chapter will contain exercises on:

                                                                                                                    +
                                                                                                                      +
                                                                                                                    • Predicate Functions
                                                                                                                    • +
                                                                                                                    • IF, WHEN, UNLESS
                                                                                                                    • +
                                                                                                                    • COND
                                                                                                                    • +
                                                                                                                    • CASE
                                                                                                                    • +
                                                                                                                    +

                                                                                                                    Extra Credit exercises (mostly from Alexandria):

                                                                                                                    +
                                                                                                                      +
                                                                                                                    • Exclusive-Or predicate function
                                                                                                                    • +
                                                                                                                    • An implementation of WHILE
                                                                                                                    • +
                                                                                                                    • SWITCH
                                                                                                                    • +
                                                                                                                    • Conditional lexical variable binding
                                                                                                                    • +
                                                                                                                    • DESTRUCTURING-CASE
                                                                                                                    • +
                                                                                                                    +

                                                                                                                    Exercise 1.14.1

                                                                                                                    +

                                                                                                                    Predicate Functions

                                                                                                                    +

                                                                                                                    Exercise 1.14.2

                                                                                                                    +

                                                                                                                    Equality Predicates

                                                                                                                    +

                                                                                                                    Exercise 1.14.3

                                                                                                                    +

                                                                                                                    Equality Predicates: EQ

                                                                                                                    +

                                                                                                                    Exercise 1.14.4

                                                                                                                    +

                                                                                                                    Equality Predicates: EQL

                                                                                                                    +

                                                                                                                    Exercise 1.14.5

                                                                                                                    +

                                                                                                                    Equality Predicates: EQUAL

                                                                                                                    +

                                                                                                                    Exercise 1.14.6

                                                                                                                    +

                                                                                                                    Equality Predicates: EQUALP

                                                                                                                    +

                                                                                                                    Exercise 1.14.7

                                                                                                                    +

                                                                                                                    Numerical Equality

                                                                                                                    +

                                                                                                                    Exercise 1.14.8

                                                                                                                    +

                                                                                                                    IF Special Forms

                                                                                                                    +

                                                                                                                    Exercise 1.14.9

                                                                                                                    +

                                                                                                                    WHEN Macro

                                                                                                                    +

                                                                                                                    Exercise 1.14.10

                                                                                                                    +

                                                                                                                    UNLESS Macro

                                                                                                                    +

                                                                                                                    Exercise 1.14.11

                                                                                                                    +

                                                                                                                    COND

                                                                                                                    +

                                                                                                                    Exercise 1.14.12

                                                                                                                    +

                                                                                                                    CASE

                                                                                                                    +

                                                                                                                    Extra Credit Exercise 1.14.13

                                                                                                                    +

                                                                                                                    Additional Conditional Forms in Alexandria

                                                                                                                    +

                                                                                                                    Extra Credit Exercise 1.14.14

                                                                                                                    +

                                                                                                                    XOR Predicate

                                                                                                                    +

                                                                                                                    Extra Credit Exercise 1.14.15

                                                                                                                    +

                                                                                                                    WHILE

                                                                                                                    +

                                                                                                                    Extra Credit Exercise 1.14.16

                                                                                                                    +

                                                                                                                    Switches

                                                                                                                    +

                                                                                                                    Extra Credit Exercise 1.14.17

                                                                                                                    +

                                                                                                                    Conditional Bindings

                                                                                                                    +

                                                                                                                    Extra Credit Exercise 1.14.18

                                                                                                                    +

                                                                                                                    DESTRUCTURING-CASE

                                                                                                                    + + +
                                                                                                                    + +
                                                                                                                    +
                                                                                                                    +
                                                                                                                    + +

                                                                                                                    results matching ""

                                                                                                                    +
                                                                                                                      + +
                                                                                                                      +
                                                                                                                      + +

                                                                                                                      No results matching ""

                                                                                                                      + +
                                                                                                                      +
                                                                                                                      +
                                                                                                                      + +
                                                                                                                      +
                                                                                                                      + +
                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                      + + +
                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-15-0-command-line-utility.html b/clones/llthw.common-lisp.dev/1-15-0-command-line-utility.html new file mode 100644 index 00000000..3eb1b249 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-15-0-command-line-utility.html @@ -0,0 +1,1865 @@ + + + + + + + Extra Credit: Command-Line Utilities ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                      +
                                                                                                                      + + + + + + + + +
                                                                                                                      + +
                                                                                                                      + +
                                                                                                                      + + + + + + + + +
                                                                                                                      +
                                                                                                                      + +
                                                                                                                      +
                                                                                                                      + +
                                                                                                                      + +

                                                                                                                      Chapter 1.15 --- Extra Credit

                                                                                                                      +

                                                                                                                      Command-Line Utilities

                                                                                                                      +
                                                                                                                      +

                                                                                                                      "The trouble with lessons from history is that we usually read them best after falling flat on our chins."

                                                                                                                      +
                                                                                                                      Robert A. Heinlein, Starship Troopers
                                                                                                                      + +
                                                                                                                      +

                                                                                                                      Underlying every modern operating system is some sort of command-line. You may never have seen it before you began your journey with Lisp, but it's always been there---the real interface to your computer, on top of which all others are built. Compared to what you can do from the command-line, graphical user interfaces (no matter how sleek and intuitive), are clunky and slow, and hold you back.

                                                                                                                      +

                                                                                                                      As a programmer, all you need is this command-line---and it's worth your time to make it your best friend. You may have even noticed how power-users seem to go out of their way to strip out the GUI from their workspace, retrofitting their OS into a souped-up 80s-style text-only terminal. This is no mere affectation---it's all about productivity.

                                                                                                                      +

                                                                                                                      So now we're going to begin our journey of creating distributable Lisp binaries by creating a useful utility application that you can run from the command-line yourself, without having to open up Lisp first. It will run like any other program on your computer---and, if you have access to Windows, OS X, and Linux, you can create binary distributions of your software and provide them to your users instead of a source code release.

                                                                                                                      +

                                                                                                                      Command-Line Interfaces may not seem like a big deal to you, at first glance. You enter a few words in the terminal, and you get your output. Where's the challenge in that, right?

                                                                                                                      +

                                                                                                                      I suppose it is a matter of opinion, but in my experience, crafting a useful, productive command-line interface to an application is a much greater challenge than designing a point-and-click or touch-based GUI. After all, when the only thing your users have to guide them is what's output by the --help flag, the terminal can be a scary, lonely place if you didn't put enough thought into the arguments and documentation for your application.

                                                                                                                      +

                                                                                                                      This chapter will contain exercises on:

                                                                                                                      +
                                                                                                                        +
                                                                                                                      • Manually parsing arguments from the command-line
                                                                                                                      • +
                                                                                                                      • Introducing CLON: The Command-Line Options Nuker
                                                                                                                      • +
                                                                                                                      • Loading Quicklisp in Lisp Scripts, but mention that it is considered 'bad practice'
                                                                                                                      • +
                                                                                                                      • Defining Your Application's Synopsis
                                                                                                                      • +
                                                                                                                      • Defining Your Application's Event Loop
                                                                                                                      • +
                                                                                                                      • Dumping Binaries
                                                                                                                      • +
                                                                                                                      • Distributing your Text-Adventure as a Binary
                                                                                                                      • +
                                                                                                                      • Deploying your Web App as a Daemon
                                                                                                                      • +
                                                                                                                      +

                                                                                                                      Exercise 1.15.1

                                                                                                                      +

                                                                                                                      Manually parsing arguments from the command-line

                                                                                                                      +

                                                                                                                      Exercise 1.15.2

                                                                                                                      +

                                                                                                                      Introducing CLON: The Command-Line Options Nuker

                                                                                                                      +

                                                                                                                      Exercise 1.15.3

                                                                                                                      +

                                                                                                                      CLON: Synopsis

                                                                                                                      +

                                                                                                                      Exercise 1.15.4

                                                                                                                      +

                                                                                                                      CLON: Event Loop

                                                                                                                      +

                                                                                                                      Exercise 1.15.5

                                                                                                                      +

                                                                                                                      Introducing Buildapp

                                                                                                                      +

                                                                                                                      Exercise 1.15.6

                                                                                                                      +

                                                                                                                      Rewrite Your Text-Adventure to Use CLON and Buildapp

                                                                                                                      +

                                                                                                                      Exercise 1.15.7

                                                                                                                      +

                                                                                                                      Rewrite Your Web App as a Daemon

                                                                                                                      + + +
                                                                                                                      + +
                                                                                                                      +
                                                                                                                      +
                                                                                                                      + +

                                                                                                                      results matching ""

                                                                                                                      +
                                                                                                                        + +
                                                                                                                        +
                                                                                                                        + +

                                                                                                                        No results matching ""

                                                                                                                        + +
                                                                                                                        +
                                                                                                                        +
                                                                                                                        + +
                                                                                                                        +
                                                                                                                        + +
                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                        + + +
                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-16-0-map-loop.html b/clones/llthw.common-lisp.dev/1-16-0-map-loop.html new file mode 100644 index 00000000..3a0b8b54 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-16-0-map-loop.html @@ -0,0 +1,1892 @@ + + + + + + + Mapping and Looping ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                        +
                                                                                                                        + + + + + + + + +
                                                                                                                        + +
                                                                                                                        + +
                                                                                                                        + + + + + + + + +
                                                                                                                        +
                                                                                                                        + +
                                                                                                                        +
                                                                                                                        + +
                                                                                                                        + +

                                                                                                                        Chapter 1.16

                                                                                                                        +

                                                                                                                        Mapping and Looping

                                                                                                                        +
                                                                                                                        +

                                                                                                                        "Excuse me, Doctor; I did not mean to criticize your planet."

                                                                                                                        +
                                                                                                                        Robert A. Heinlein, The Moon Is a Harsh Mistress
                                                                                                                        + +
                                                                                                                        +

                                                                                                                        As a contrast to Conditionals, sometimes you'll want to do exactly the same thing to each item in a whole list or sequence; or maybe not exactly the same thing, but very similar things. Once again, Lisp has you covered---there are quite a few built-in options for iteration over lists, sets, sequences, hash tables, and other such objects. Basic iteration is covered by the "DO" series of functions.

                                                                                                                        +

                                                                                                                        Mapping is a different beast than iteration, but you may find a certain synchronicity between the two topics that help you understand both better. For example, if you have two lists, and you want to pair the values of one list with the values of the other, you can map them together using the cons function to get an alist as key-value pairs---and you can see here the similarity between mapping and looping.

                                                                                                                        +

                                                                                                                        Lisp also has the functions apply and reduce, of course---apply takes a function as its first argument, and then applies that function to the rest of the arguments you pass it, the last of which must be a list; reduce is somewhat similar, but it works with sequences and allows you to specify a number of extra parameters for finer control.

                                                                                                                        +

                                                                                                                        And then there's the infamous and oft-criticized LOOP macro---it gets a lot of flak for not being "Lispy" enough, but it's so powerful that it has stuck around. It has its own internal syntax that looks more like imperative languages than like Lisp, however, it includes the functionality for every possible iterative construct you could ever hope or dream for.

                                                                                                                        +

                                                                                                                        This chapter will contain exercises on:

                                                                                                                        +
                                                                                                                          +
                                                                                                                        • DO and DO*
                                                                                                                        • +
                                                                                                                        • DOTIMES
                                                                                                                        • +
                                                                                                                        • DOLIST
                                                                                                                        • +
                                                                                                                        • MAP
                                                                                                                        • +
                                                                                                                        • MAPC and MAPL
                                                                                                                        • +
                                                                                                                        • Other Mapping Functions
                                                                                                                        • +
                                                                                                                        • APPLY and REDUCE
                                                                                                                        • +
                                                                                                                        • The LOOP Macro
                                                                                                                        • +
                                                                                                                        +

                                                                                                                        Exercise 1.16.1

                                                                                                                        +

                                                                                                                        Iteration

                                                                                                                        +

                                                                                                                        Exercise 1.16.2

                                                                                                                        +

                                                                                                                        DO

                                                                                                                        +

                                                                                                                        Exercise 1.16.3

                                                                                                                        +

                                                                                                                        DO*

                                                                                                                        +

                                                                                                                        Exercise 1.16.4

                                                                                                                        +

                                                                                                                        DOTIMES

                                                                                                                        +

                                                                                                                        Exercise 1.16.5

                                                                                                                        +

                                                                                                                        DOLIST

                                                                                                                        +

                                                                                                                        Exercise 1.16.6

                                                                                                                        +

                                                                                                                        Mapping

                                                                                                                        +

                                                                                                                        Exercise 1.16.7

                                                                                                                        +

                                                                                                                        MAP

                                                                                                                        +

                                                                                                                        Exercise 1.16.8

                                                                                                                        +

                                                                                                                        MAPC

                                                                                                                        +

                                                                                                                        Exercise 1.16.9

                                                                                                                        +

                                                                                                                        MAPL

                                                                                                                        +

                                                                                                                        Exercise 1.16.10

                                                                                                                        +

                                                                                                                        MAPCAR

                                                                                                                        +

                                                                                                                        Exercise 1.16.11

                                                                                                                        +

                                                                                                                        MAPCAN

                                                                                                                        +

                                                                                                                        Exercise 1.16.12

                                                                                                                        +

                                                                                                                        MAPHASH

                                                                                                                        +

                                                                                                                        Exercise 1.16.13

                                                                                                                        +

                                                                                                                        MAPCON

                                                                                                                        +

                                                                                                                        Exercise 1.16.14

                                                                                                                        +

                                                                                                                        MAP-INTO

                                                                                                                        +

                                                                                                                        Exercise 1.16.15

                                                                                                                        +

                                                                                                                        APPLY

                                                                                                                        +

                                                                                                                        Exercise 1.16.16

                                                                                                                        +

                                                                                                                        More APPLY

                                                                                                                        +

                                                                                                                        Exercise 1.16.17

                                                                                                                        +

                                                                                                                        REDUCE

                                                                                                                        +

                                                                                                                        Exercise 1.16.18

                                                                                                                        +

                                                                                                                        More REDUCE

                                                                                                                        +

                                                                                                                        Exercise 1.16.19

                                                                                                                        +

                                                                                                                        The LOOP Macro

                                                                                                                        +

                                                                                                                        Exercise 1.16.20

                                                                                                                        +

                                                                                                                        More LOOP

                                                                                                                        +

                                                                                                                        Exercise 1.16.21

                                                                                                                        +

                                                                                                                        Even More LOOP

                                                                                                                        + + +
                                                                                                                        + +
                                                                                                                        +
                                                                                                                        +
                                                                                                                        + +

                                                                                                                        results matching ""

                                                                                                                        +
                                                                                                                          + +
                                                                                                                          +
                                                                                                                          + +

                                                                                                                          No results matching ""

                                                                                                                          + +
                                                                                                                          +
                                                                                                                          +
                                                                                                                          + +
                                                                                                                          +
                                                                                                                          + +
                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                          + + +
                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-17-0-iterate.html b/clones/llthw.common-lisp.dev/1-17-0-iterate.html new file mode 100644 index 00000000..2ab53095 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-17-0-iterate.html @@ -0,0 +1,1876 @@ + + + + + + + Extra Credit: Revisiting Loops with Iterate ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                          +
                                                                                                                          + + + + + + + + +
                                                                                                                          + +
                                                                                                                          + +
                                                                                                                          + + + + + + + + +
                                                                                                                          +
                                                                                                                          + +
                                                                                                                          +
                                                                                                                          + +
                                                                                                                          + +

                                                                                                                          Chapter 1.17 --- Extra Credit

                                                                                                                          +

                                                                                                                          Revisiting Loops with Iterate

                                                                                                                          +
                                                                                                                          +

                                                                                                                          "People do what they want to, every time. If it pains them to make a choice---if the choice looks like a 'sacrifice'---you can be sure that it is no nobler than the discomfort caused by greediness... the necessity of deciding between two things you want when you can't have both."

                                                                                                                          +
                                                                                                                          Robert A. Heinlein, Stranger In a Strange Land
                                                                                                                          + +
                                                                                                                          +

                                                                                                                          Despite the power and expressiveness of the Loop Macro, a lot of Lisp Hackers simply hate it---naturally, in the roll-your-own-solution spirit of the Lisp community, many alternatives to the Loop Macro exist. The most popular and Lispy of these is the ITERATE package. It's aim is to provide all the power and expressiveness of the Loop Macro, without changing the fundamental syntax of the language for its own internal use---this implies, among other things of course, that you can build macros on top of Iterate and expand S-Expression code the way you normally would, instead of having to use strange hacks and bad style to achieve your desired effect with Loop.

                                                                                                                          +

                                                                                                                          Iterate is also extensible by design, so if it's missing some construct you happen to need, you can roll-your-own driver and use it like any other Iterate driver; or go the extra mile and package a number of Iterate extensions together in a contrib-library. That's a feature that the built-in Loop macro can't provide.

                                                                                                                          +

                                                                                                                          After learning how to use the Iterate library and trying it out in a few projects, some Lisp Hackers still end up going back to Loop; but this is not an exercise in vain---learning Iterate and its strategy to iteration compared to the built-in Loop macro is an extremely useful exercise. And at the end of this chapter, you will have a much better understanding of both Iterate and Loop, and which solution fits your needs the best.

                                                                                                                          +

                                                                                                                          This chapter will contain exercises on:

                                                                                                                          +
                                                                                                                            +
                                                                                                                          • Setting up your package to use Iterate
                                                                                                                          • +
                                                                                                                          • A few side-by-side examples with Loop
                                                                                                                          • +
                                                                                                                          • Iterate Clauses
                                                                                                                          • +
                                                                                                                          • Iterate Drivers
                                                                                                                          • +
                                                                                                                          • Variable Binding and Setting in Iterate
                                                                                                                          • +
                                                                                                                          • Gathering Clauses
                                                                                                                          • +
                                                                                                                          • Multiple Accumulations
                                                                                                                          • +
                                                                                                                          • Parallel Binding and Stepping
                                                                                                                          • +
                                                                                                                          • Types and Declarations
                                                                                                                          • +
                                                                                                                          +

                                                                                                                          Exercise 1.17.1

                                                                                                                          +

                                                                                                                          Configuring Packages for Iterate

                                                                                                                          +

                                                                                                                          Exercise 1.17.2

                                                                                                                          +

                                                                                                                          Iterate vs. Loop

                                                                                                                          +

                                                                                                                          Exercise 1.17.3

                                                                                                                          +

                                                                                                                          Clauses

                                                                                                                          +

                                                                                                                          Exercise 1.17.4

                                                                                                                          +

                                                                                                                          More Clauses

                                                                                                                          +

                                                                                                                          Exercise 1.17.5

                                                                                                                          +

                                                                                                                          Even More Clauses

                                                                                                                          +

                                                                                                                          Exercise 1.17.6

                                                                                                                          +

                                                                                                                          Drivers

                                                                                                                          +

                                                                                                                          Exercise 1.17.7

                                                                                                                          +

                                                                                                                          More Drivers

                                                                                                                          +

                                                                                                                          Exercise 1.17.8

                                                                                                                          +

                                                                                                                          Binding and Assignment

                                                                                                                          +

                                                                                                                          Exercise 1.17.9

                                                                                                                          +

                                                                                                                          Accumulation

                                                                                                                          +

                                                                                                                          Exercise 1.17.10

                                                                                                                          +

                                                                                                                          Multiple Accumulation

                                                                                                                          +

                                                                                                                          Exercise 1.17.11

                                                                                                                          +

                                                                                                                          Parallel Binding

                                                                                                                          +

                                                                                                                          Exercise 1.17.12

                                                                                                                          +

                                                                                                                          Stepping

                                                                                                                          +

                                                                                                                          Exercise 1.17.13

                                                                                                                          +

                                                                                                                          Types and Declarations

                                                                                                                          + + +
                                                                                                                          + +
                                                                                                                          +
                                                                                                                          +
                                                                                                                          + +

                                                                                                                          results matching ""

                                                                                                                          +
                                                                                                                            + +
                                                                                                                            +
                                                                                                                            + +

                                                                                                                            No results matching ""

                                                                                                                            + +
                                                                                                                            +
                                                                                                                            +
                                                                                                                            + +
                                                                                                                            +
                                                                                                                            + +
                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                            + + +
                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-18-0-format.html b/clones/llthw.common-lisp.dev/1-18-0-format.html new file mode 100644 index 00000000..75175b1f --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-18-0-format.html @@ -0,0 +1,1881 @@ + + + + + + + Format Strings ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                            +
                                                                                                                            + + + + + + + + +
                                                                                                                            + +
                                                                                                                            + +
                                                                                                                            + + + + + + + + +
                                                                                                                            +
                                                                                                                            + +
                                                                                                                            +
                                                                                                                            + +
                                                                                                                            + +

                                                                                                                            Chapter 1.18

                                                                                                                            +

                                                                                                                            Format Strings

                                                                                                                            +
                                                                                                                            +

                                                                                                                            "Logic is a feeble reed, friend. 'Logic' proved that airplanes can't fly and that H-bombs won't work and that stones don't fall out of the sky. Logic is a way of saying that anything which didn't happen yesterday won't happen tomorrow."

                                                                                                                            +
                                                                                                                            Robert A. Heinlein, Glory Road
                                                                                                                            + +
                                                                                                                            +

                                                                                                                            You already got a small taste of format in Chapter 1.2, but we barely scratched the surface of what it can do. Like the Loop macro, format has many detractors in the Lisp community---but it's one of those tools that is so ridiculously powerful and concise, it's worth getting to know and using, no matter how scary it might look at first.

                                                                                                                            +

                                                                                                                            Almost everything you can do in Common Lisp, you can also do inside a format string. It gives you so much programmatic control over your application's textual output, that it could rightly be considered its own programming language for manipulating strings---but you get it for free as part of Lisp. The syntax of format strings is, in-fact, a full Domain-Specific Language.

                                                                                                                            +

                                                                                                                            But don't let that scare you---you already know the basics of writing format strings, and now you know enough about Lisp to make use of format's most powerful features.

                                                                                                                            +

                                                                                                                            This chapter will contain exercises on:

                                                                                                                            +
                                                                                                                              +
                                                                                                                            • The FORMAT Function
                                                                                                                            • +
                                                                                                                            • Conditionals
                                                                                                                            • +
                                                                                                                            • Iteration
                                                                                                                            • +
                                                                                                                            • Numbers
                                                                                                                            • +
                                                                                                                            • Unprintable Objects
                                                                                                                            • +
                                                                                                                            • Etc.
                                                                                                                            • +
                                                                                                                            +

                                                                                                                            Exercise 1.18.1

                                                                                                                            +

                                                                                                                            The FORMAT Function

                                                                                                                            +

                                                                                                                            Exercise 1.18.2

                                                                                                                            +

                                                                                                                            The Stream Parameter

                                                                                                                            +

                                                                                                                            Exercise 1.18.3

                                                                                                                            +

                                                                                                                            Format Strings

                                                                                                                            +

                                                                                                                            Exercise 1.18.4

                                                                                                                            +

                                                                                                                            Format Directives

                                                                                                                            +

                                                                                                                            Exercise 1.18.5

                                                                                                                            +

                                                                                                                            Consuming and Non-Consuming Directives

                                                                                                                            +

                                                                                                                            Exercise 1.18.6

                                                                                                                            +

                                                                                                                            Arguments to Format Strings

                                                                                                                            +

                                                                                                                            Exercise 1.18.7

                                                                                                                            +

                                                                                                                            Numbers

                                                                                                                            +

                                                                                                                            Exercise 1.18.8

                                                                                                                            +

                                                                                                                            Printing

                                                                                                                            +

                                                                                                                            Exercise 1.18.9

                                                                                                                            +

                                                                                                                            Case Conversion

                                                                                                                            +

                                                                                                                            Exercise 1.18.10

                                                                                                                            +

                                                                                                                            Layout

                                                                                                                            +

                                                                                                                            Exercise 1.18.11

                                                                                                                            +

                                                                                                                            Conditionals

                                                                                                                            +

                                                                                                                            Exercise 1.18.12

                                                                                                                            +

                                                                                                                            Iteration

                                                                                                                            +

                                                                                                                            Exercise 1.18.13

                                                                                                                            +

                                                                                                                            Control Flow

                                                                                                                            +

                                                                                                                            Exercise 1.18.14

                                                                                                                            +

                                                                                                                            Pretty-Printing

                                                                                                                            +

                                                                                                                            Exercise 1.18.15

                                                                                                                            +

                                                                                                                            Unprintable Objects

                                                                                                                            +

                                                                                                                            Exercise 1.18.16

                                                                                                                            +

                                                                                                                            Recursive Processing

                                                                                                                            +

                                                                                                                            Exercise 1.18.17

                                                                                                                            +

                                                                                                                            Function Calls

                                                                                                                            + + +
                                                                                                                            + +
                                                                                                                            +
                                                                                                                            +
                                                                                                                            + +

                                                                                                                            results matching ""

                                                                                                                            +
                                                                                                                              + +
                                                                                                                              +
                                                                                                                              + +

                                                                                                                              No results matching ""

                                                                                                                              + +
                                                                                                                              +
                                                                                                                              +
                                                                                                                              + +
                                                                                                                              +
                                                                                                                              + +
                                                                                                                              + + + + + + + + + + + + + + +
                                                                                                                              + + +
                                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-19-0-dsl.html b/clones/llthw.common-lisp.dev/1-19-0-dsl.html new file mode 100644 index 00000000..9c77c3cf --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-19-0-dsl.html @@ -0,0 +1,1897 @@ + + + + + + + Extra Credit: Domain Specific Languages ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                              +
                                                                                                                              + + + + + + + + +
                                                                                                                              + +
                                                                                                                              + +
                                                                                                                              + + + + + + + + +
                                                                                                                              +
                                                                                                                              + +
                                                                                                                              +
                                                                                                                              + +
                                                                                                                              + +

                                                                                                                              Chapter 1.19 --- Extra Credit

                                                                                                                              +

                                                                                                                              Domain-Specific Languages

                                                                                                                              +
                                                                                                                              +

                                                                                                                              "Most of us know the code is wrong; almost everybody breaks it. But we pay Danegeld by feeling guilty and giving lip service. Willy-nilly, the code rides us, dead and stinking, an albatross around the neck."

                                                                                                                              +
                                                                                                                              Robert A. Heinlein, Stranger In a Strange Land
                                                                                                                              + +
                                                                                                                              +

                                                                                                                              You've already seen a number of Domain-Specific Languages in Lisp---to recap, a DSL is a convenient, embedded syntax, purpose-designed to achieve natural expression of a problem domain that falls outside the realm of the host programming language and its native syntax. Common Lisp even comes with two notable DSLs baked into the core language specification---the Loop macro and Format strings. Love 'em or hate 'em, Loop and Format were purpose-designed, provide essential functionality, and fulfill their purposes with internally consistent syntaxes.

                                                                                                                              +

                                                                                                                              But you've also had a chance to play with DSLs for HTML/XML, CSS, and JavaScript. Lisp makes it surprisingly easy, compared to other programming languages, to roll-your-own DSL for whatever problem domain you have to deal with. This goes above and beyond writing a library of functions, macros, classes and methods. You write a Domain-Specific Language when even a full, native Lisp library won't solve your problem---because the problem requires a different way of thinking to express. The DSLs for HTML/XML, CSS, and JavaScript are good examples to illustrate this point---after all, if they weren't absolutely necessary to make the world-wide-web of today a reality, they wouldn't exist.

                                                                                                                              +

                                                                                                                              Structured Data is fundamental to the web; search engines rely on it to correctly parse and catalogue every website on the internet, so that you can get to the information you need when you need it. But XML can be a tedious language to work with, if you find yourself having to hand-edit it; this is why so many full-time XML developers avoid doing so---they prefer using expensive software to manage their XML code in a sensible way, visually. HTML is much the same---even though it is not as tedious to work with as the full XML spec, many professional web developers prefer using WYSIWYG editors to develop their web templates, never even looking at a single line of HTML if they can help it.

                                                                                                                              +

                                                                                                                              CSS is just as important---it is purpose-designed for dictating the rendering rules for structured data in HTML and XML, for multiple output formats. And then there's JavaScript---the little web scripting language that has taken the world by storm, despite its obvious limitations and logical problems.

                                                                                                                              +

                                                                                                                              The problem domains that these web languages handle are real---and obviously, they meet their need or people wouldn't use them. Now, I've said before that you can replace them all with Lisp, and as you've seen, it's much easier to manage a single Lisp code-base than having to constantly shift gears to switch between the distinct paradigms required for writing Markup, Styling, Scripting, and Logic code. But that being said, it's important to remember the distinct problem domains; when you approach a DSL, you have to make sure it solves the problem on its own terms and not the terms of the host language.

                                                                                                                              +

                                                                                                                              Now it's time to learn how to write your own DSL. It's a much bigger challenge than anything else we've covered so far---but the rewards are equal to the effort. Being able to write a clean, native Lisp interface to any imaginable problem-domain is one of the language's greatest strengths.

                                                                                                                              +

                                                                                                                              This chapter will contain exercises on:

                                                                                                                              +
                                                                                                                                +
                                                                                                                              • Lisp Macros and DSLs
                                                                                                                              • +
                                                                                                                              • A brief tour of popular problem-domains
                                                                                                                              • +
                                                                                                                              • Overview of S-SQL, a DSL for writing SQL queries with S-Expressions
                                                                                                                              • +
                                                                                                                              • Write your own DSL!
                                                                                                                                  +
                                                                                                                                • Choosing a problem domain
                                                                                                                                • +
                                                                                                                                • Identify a domain's most natural expression
                                                                                                                                • +
                                                                                                                                • Write out how you would like the DSL to work
                                                                                                                                • +
                                                                                                                                • Implementing the syntax of your DSL
                                                                                                                                • +
                                                                                                                                +
                                                                                                                              • +
                                                                                                                              +

                                                                                                                              Exercise 1.19.1

                                                                                                                              +

                                                                                                                              Lisp Macros and DSLs:

                                                                                                                              +

                                                                                                                              When standard functions fail to meet your needs, using the macro definition syntax you learned in Chapter 1.10 you can manipulate Lisp syntax in order to create a DSL that's perfectly suited to your needs and a specialized problem domain. You have already seen several DSLs in action, two of which are built right into the Common Lisp standard: LOOP and FORMAT strings. They also represent two different approaches to DSLs---inline syntax and string-parsing.

                                                                                                                              +

                                                                                                                              One advantage to string-parsing is that you can write functions to parse your strings instead of writing macros. This is how FORMAT is implemented in Common Lisp.

                                                                                                                              +
                                                                                                                              (format nil "~A" 'format)
                                                                                                                              +
                                                                                                                              +

                                                                                                                              Of course with inline syntax, your DSLs expand to native Common Lisp code, instead of having to be parsed before you can build an abstract syntax tree; and while the LOOP macro doesn't use S-Expressions in its internal syntax, you can certainly take advantage of them in your DSL to get all the other benefits of Lisp you've learned so far.

                                                                                                                              +
                                                                                                                              (loop for x below 10 collect x)
                                                                                                                              +
                                                                                                                              +

                                                                                                                              Compare this again to an S-Expression syntax using Iterate:

                                                                                                                              +
                                                                                                                              (ql:quickload "iterate")
                                                                                                                              +(use-package 'iterate)
                                                                                                                              +(iterate (for x below 10)
                                                                                                                              +         (collect x))
                                                                                                                              +
                                                                                                                              +

                                                                                                                              Note: If you get errors 'using' the iterate package, follow the debugger instructions to shadow the cl-user package functions with iterate.

                                                                                                                              +

                                                                                                                              These LOOP and Iterate examples are equivalent, and are both equally fast. The main advantage to Iterate over the built-in LOOP macro is that it uses S-Expressions, so you can more easily embed Iterate in other macros, and reason about Iterate code through code-walking. These are important points to consider when designing your own DSL.

                                                                                                                              +

                                                                                                                              Exercise 1.19.2

                                                                                                                              +

                                                                                                                              A brief tour of popular problem-domains:

                                                                                                                              +
                                                                                                                                +
                                                                                                                              • Logic Programming
                                                                                                                              • +
                                                                                                                              • Graphics Programming
                                                                                                                              • +
                                                                                                                              • Mark-up
                                                                                                                              • +
                                                                                                                              • Assembly and Byte-Code
                                                                                                                              • +
                                                                                                                              +

                                                                                                                              Exercise 1.19.3

                                                                                                                              +

                                                                                                                              Overview of S-SQL, a DSL for writing SQL queries in S-Expression syntax:

                                                                                                                              +
                                                                                                                                +
                                                                                                                              • Keyword Expressions
                                                                                                                              • +
                                                                                                                              • SQL Queries
                                                                                                                              • +
                                                                                                                              • Re-ordering of Expressions
                                                                                                                              • +
                                                                                                                              • Handling results
                                                                                                                              • +
                                                                                                                              +

                                                                                                                              Exercise 1.19.4

                                                                                                                              +

                                                                                                                              Write your own DSL! Overview of Methodology:

                                                                                                                              +

                                                                                                                              Exercise 1.19.5

                                                                                                                              +

                                                                                                                              Write your own DSL! Choosing a problem domain:

                                                                                                                              +

                                                                                                                              Exercise 1.19.6

                                                                                                                              +

                                                                                                                              Write your own DSL! Identify a domain's most natural expression:

                                                                                                                              +

                                                                                                                              Exercise 1.19.7

                                                                                                                              +

                                                                                                                              Write your own DSL! Write out how you would like the DSL to work:

                                                                                                                              +

                                                                                                                              Exercise 1.19.8

                                                                                                                              +

                                                                                                                              Write your own DSL! Implementing the syntax of your DSL:

                                                                                                                              + + +
                                                                                                                              + +
                                                                                                                              +
                                                                                                                              +
                                                                                                                              + +

                                                                                                                              results matching ""

                                                                                                                              +
                                                                                                                                + +
                                                                                                                                +
                                                                                                                                + +

                                                                                                                                No results matching ""

                                                                                                                                + +
                                                                                                                                +
                                                                                                                                +
                                                                                                                                + +
                                                                                                                                +
                                                                                                                                + +
                                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                                + + +
                                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/1-20-0-review.html b/clones/llthw.common-lisp.dev/1-20-0-review.html new file mode 100644 index 00000000..86458a58 --- /dev/null +++ b/clones/llthw.common-lisp.dev/1-20-0-review.html @@ -0,0 +1,1845 @@ + + + + + + + Part One in Review ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                +
                                                                                                                                + + + + + + + + +
                                                                                                                                + +
                                                                                                                                + +
                                                                                                                                + + + + + + + + +
                                                                                                                                +
                                                                                                                                + +
                                                                                                                                +
                                                                                                                                + +
                                                                                                                                + +

                                                                                                                                Chapter 1.20

                                                                                                                                +

                                                                                                                                Part One in Review

                                                                                                                                +
                                                                                                                                +

                                                                                                                                "To the scientific mind, experimental proof is all important and theory is merely a convenience in description, to be junked when it no longer fits."

                                                                                                                                +
                                                                                                                                Robert A. Heinlein, Life-Line
                                                                                                                                + +
                                                                                                                                +

                                                                                                                                You've finally reached the end of Part One. By this point, you should have a solid grounding in the fundamentals of Lisp, be able to write and distribute your own text-based Lisp applications as both source code libraries and self-contained binaries, and run your own Lisp-powered web sites. You've even got a few games to play!

                                                                                                                                +

                                                                                                                                But you're not done yet. To make sure you're ready for Part Two, and the rest of the Lisp language, you need to assess how deeply you've internalized Lisp so far. I present to you three challenges that will push you and your new-found skills to their limits:

                                                                                                                                +
                                                                                                                                  +
                                                                                                                                • First Challenge: review, categorize, and memorize all Symbols used in Part One
                                                                                                                                • +
                                                                                                                                • Second Challenge: describe Lisp Syntax from memory, and categorize by theme
                                                                                                                                • +
                                                                                                                                • Third Challenge: code review of random CL library---compare its style with the style guide, profile improvements, get it to run
                                                                                                                                • +
                                                                                                                                +

                                                                                                                                If any of these challenges stump you, you may need to go back and re-do the related exercises before moving on to Part Two. But once you can complete these three challenges, it's time to give yourself a pat on the back and celebrate! You're now a novice Lisp Hacker!

                                                                                                                                +

                                                                                                                                Also be sure to save your notes from these three challenges, and take a week off to let this material sink in. Once you're ready to start Part Two, you can refer to your notes to trigger your memory.

                                                                                                                                +

                                                                                                                                See you in Part Two!

                                                                                                                                + + +
                                                                                                                                + +
                                                                                                                                +
                                                                                                                                +
                                                                                                                                + +

                                                                                                                                results matching ""

                                                                                                                                +
                                                                                                                                  + +
                                                                                                                                  +
                                                                                                                                  + +

                                                                                                                                  No results matching ""

                                                                                                                                  + +
                                                                                                                                  +
                                                                                                                                  +
                                                                                                                                  + +
                                                                                                                                  +
                                                                                                                                  + +
                                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                                  + + +
                                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-0-0-overview.html b/clones/llthw.common-lisp.dev/2-0-0-overview.html new file mode 100644 index 00000000..58d7b6ba --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-0-0-overview.html @@ -0,0 +1,1862 @@ + + + + + + + The Suffusion of Blue ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                  +
                                                                                                                                  + + + + + + + + +
                                                                                                                                  + +
                                                                                                                                  + +
                                                                                                                                  + + + + + + + + +
                                                                                                                                  +
                                                                                                                                  + +
                                                                                                                                  +
                                                                                                                                  + +
                                                                                                                                  + +

                                                                                                                                  PART TWO

                                                                                                                                  +

                                                                                                                                  The Suffusion of Blue

                                                                                                                                  +
                                                                                                                                  +

                                                                                                                                  "The door dilated."

                                                                                                                                  +
                                                                                                                                  Robert A. Heinlein, Beyond This Horizon
                                                                                                                                  + +
                                                                                                                                  +

                                                                                                                                  It's time to take your Lisp skills up a notch. Hopefully, you took some time off after Part One as suggested, to let the material sink in deep into your unconscious. By this point, you may be thinking and dreaming in Lisp---literally. And when faced with any problem, you may find yourself automatically plotting in your mind how this problem could be represented in S-Expressions. Ideally, you even may have begun to notice the drastic and startling phenomenon of "Grokking"---each new chapter in Part One adding a new degree of seeming mystic revelation to the already magickal experience that is Lisp.

                                                                                                                                  +

                                                                                                                                  As Zen Buddhism teaches, however, it is important to not get sucked in to the particular tokens of these revelatory experiences---they are, after all, a product of your imagination fuelled by the power and expressiveness of Lisp syntax. To really harness and master Lisp, however, you need to push past these tokens to the phenomenon known as the Clear Light or the Suffusion of Blue---it doesn't really have a colour, of course, and it's not really light or even true enlightenment. It's just the threshold, as you take your first step on your journey as a Lisp Hacker. And on this journey, you will learn to see not the black and white extremes encapsulated in the symbol of the Yin-Yang---but every colour in the space between.

                                                                                                                                  +

                                                                                                                                  But enough with the metaphors for now. From a practical standpoint, in Part Two you'll be learning all the advanced features of the Common Lisp language---the secrets of multi-paradigm programming; CLOS, the Common Lisp Object System; Regular Expressions and Pattern Matching; Persistent storage and serialization; writing custom types; parellel processing; advanced mathematics and logic; working with binary, assembly language, and the compiler; the foreign-function interface; and a whole lot more.

                                                                                                                                  +

                                                                                                                                  Chapters

                                                                                                                                  +
                                                                                                                                    +
                                                                                                                                  1. Programming Paradigms
                                                                                                                                  2. +
                                                                                                                                  3. Regular Expressions
                                                                                                                                  4. +
                                                                                                                                  5. Objects and Control Structures
                                                                                                                                  6. +
                                                                                                                                  7. Persistence and Databases
                                                                                                                                  8. +
                                                                                                                                  9. Extended Types
                                                                                                                                  10. +
                                                                                                                                  11. Concurrency and Memoization
                                                                                                                                  12. +
                                                                                                                                  13. Logic and Advanced Math
                                                                                                                                  14. +
                                                                                                                                  15. Number Theory
                                                                                                                                  16. +
                                                                                                                                  17. Binary Streams, Octet-Vectors, and Bit-Vectors
                                                                                                                                  18. +
                                                                                                                                  19. An Improved Text Adventure Engine
                                                                                                                                  20. +
                                                                                                                                  21. Conditions and Error Handling
                                                                                                                                  22. +
                                                                                                                                  23. Write a 2D Game
                                                                                                                                  24. +
                                                                                                                                  25. The Compiler
                                                                                                                                  26. +
                                                                                                                                  27. Write a Tree-Shaker
                                                                                                                                  28. +
                                                                                                                                  29. Documentation and Inspection
                                                                                                                                  30. +
                                                                                                                                  31. Foreign Libraries in Lisp
                                                                                                                                  32. +
                                                                                                                                  33. Debugging and Unit Testing
                                                                                                                                  34. +
                                                                                                                                  35. Write a Foreign Function Interface
                                                                                                                                  36. +
                                                                                                                                  37. Essential Lisp Libraries
                                                                                                                                  38. +
                                                                                                                                  39. Packaging Lisp Libraries
                                                                                                                                  40. +
                                                                                                                                  41. Detailed Syntax Review
                                                                                                                                  42. +
                                                                                                                                  + + +
                                                                                                                                  + +
                                                                                                                                  +
                                                                                                                                  +
                                                                                                                                  + +

                                                                                                                                  results matching ""

                                                                                                                                  +
                                                                                                                                    + +
                                                                                                                                    +
                                                                                                                                    + +

                                                                                                                                    No results matching ""

                                                                                                                                    + +
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    + +
                                                                                                                                    +
                                                                                                                                    + +
                                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                                    + + +
                                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-01-0-programming-paradigms.html b/clones/llthw.common-lisp.dev/2-01-0-programming-paradigms.html new file mode 100644 index 00000000..782b13af --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-01-0-programming-paradigms.html @@ -0,0 +1,1923 @@ + + + + + + + Programming Paradigms ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                    +
                                                                                                                                    + + + + + + + + +
                                                                                                                                    + +
                                                                                                                                    + +
                                                                                                                                    + + + + + + + + +
                                                                                                                                    +
                                                                                                                                    + +
                                                                                                                                    +
                                                                                                                                    + +
                                                                                                                                    + +

                                                                                                                                    Chapter 2.1

                                                                                                                                    +

                                                                                                                                    Programming Paradigms

                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    "A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects."

                                                                                                                                    +
                                                                                                                                    Robert A. Heinlein, Time Enough for Love
                                                                                                                                    + +
                                                                                                                                    +

                                                                                                                                    The way that you structure a problem dictates and limits its possible solutions. Most programming lanugages have a single, or a very small set of built-in approaches to programming---their syntax restricts the lanuage to a single paradigm---and as a result, they limit you as a programmer, and artificially stunt your productivity and ingenuity, because they impose a single methodology for approaching all problems. Human language is much the same in this regard---it is a well-known and established fact in developmental psychology, that the more languages a child learns to speak early on, the broader their thinking ends up becoming. This is because all languages, human or computer, include certain underlying assumptions about the world that are not directly expressed, but are always there "between the lines" in the untranslatable elements of language. When you learn to look at the world through different lenses, as the saying goes, you can see it much more clearly. This also happens to be the scientific perspective.

                                                                                                                                    +

                                                                                                                                    Lisp is different from other programming lanugages---it is multi-paradigm by nature, which means in practice that you are free to approach any given problem by every potential angle; the simplicity of its syntax, the homoiconicity of S-Expressions for representing both code and data also allow for the natural and intuitive representation of all programming paradigms; and in the Lisp REPL, you can try out each potential paradigm side-by-side until you find the right combination of clarity, expressiveness, and simplicity. As you work more with Lisp and various paradigms through it, you will begin to develop an intuition for problem-solving; then, as you look at a problem and consider its implementation, you will get a feel for "just knowing" which paradigm best suits the job in front of you---just like an artist intuitively knows what colour palette to use as well as which brush.

                                                                                                                                    +

                                                                                                                                    The ability to switch paradigms in Lisp may strike you, at first, as a source of great confusion. You might ask yourself, "how am I supposed to look over a piece of code and know what's going on? What if I mistake one paradigm for another, and mess up a library?" Obviously, experience will help---the more you work with Lisp and the multi-paradigm approach, the more quickly you will be able to spot the paradigms being used. But that's not as difficult as it sounds---every paradigm comes with its unique hallmarks, and once you learn them, they're easy to spot.

                                                                                                                                    +

                                                                                                                                    In Part One, we primarily used the functional programming paradigm for convenience; but as I've said before, Lisp is not a functional language---the functional paradigm is just one of many at your disposal. In this chapter we will go through exercises that illustrate the use of various paradigms in software design and system architecture, and show how in Lisp you can freely mix-and-match paradigms without confusing either the compiler or another programmer reviewing your code.

                                                                                                                                    +

                                                                                                                                    This chapter will contain exercises on:

                                                                                                                                    +
                                                                                                                                      +
                                                                                                                                    • The Multi-Paradigm Approach
                                                                                                                                    • +
                                                                                                                                    • Imperative vs. Declarative
                                                                                                                                    • +
                                                                                                                                    • Procedural Programming
                                                                                                                                    • +
                                                                                                                                    • Object-Oriented Programming
                                                                                                                                    • +
                                                                                                                                    • Functional Programming
                                                                                                                                    • +
                                                                                                                                    • Alternate Paradigms of Interest
                                                                                                                                    • +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.1

                                                                                                                                    +

                                                                                                                                    The Multi-Paradigm Approach

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.2

                                                                                                                                    +

                                                                                                                                    Imperative Programming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.3

                                                                                                                                    +

                                                                                                                                    Declarative Programming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.4

                                                                                                                                    +

                                                                                                                                    Procedural Programming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.5

                                                                                                                                    +

                                                                                                                                    Object-Oriented Programming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.6

                                                                                                                                    +

                                                                                                                                    Pure Functional Programming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.7

                                                                                                                                    +

                                                                                                                                    Functional Programming in Practice

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.8

                                                                                                                                    +

                                                                                                                                    Metaprogramming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.9

                                                                                                                                    +

                                                                                                                                    Combining Paradigms: the wrong way

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.10

                                                                                                                                    +

                                                                                                                                    Combining Paradigms: the right way

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.11

                                                                                                                                    +

                                                                                                                                    The Style Guide, revisited

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.12

                                                                                                                                    +

                                                                                                                                    Alternate Paradigms: Aspect-Oriented

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.13

                                                                                                                                    +

                                                                                                                                    Alternate Paradigms: Agent-Oriented

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.14

                                                                                                                                    +

                                                                                                                                    Alternate Paradigms: Flow-Based Programming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    +

                                                                                                                                    Exercise 2.1.15

                                                                                                                                    +

                                                                                                                                    Alternate Paradigms: Functional--Reactive Programming

                                                                                                                                    +
                                                                                                                                    
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    + + +
                                                                                                                                    + +
                                                                                                                                    +
                                                                                                                                    +
                                                                                                                                    + +

                                                                                                                                    results matching ""

                                                                                                                                    +
                                                                                                                                      + +
                                                                                                                                      +
                                                                                                                                      + +

                                                                                                                                      No results matching ""

                                                                                                                                      + +
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      + +
                                                                                                                                      +
                                                                                                                                      + +
                                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                                      + + +
                                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-02-0-regex.html b/clones/llthw.common-lisp.dev/2-02-0-regex.html new file mode 100644 index 00000000..6b11b554 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-02-0-regex.html @@ -0,0 +1,1901 @@ + + + + + + + Extra Credit: Regular Expressions ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                      +
                                                                                                                                      + + + + + + + + +
                                                                                                                                      + +
                                                                                                                                      + +
                                                                                                                                      + + + + + + + + +
                                                                                                                                      +
                                                                                                                                      + +
                                                                                                                                      +
                                                                                                                                      + +
                                                                                                                                      + +

                                                                                                                                      Chapter 2.2 --- Extra Credit

                                                                                                                                      +

                                                                                                                                      Regular Expressions and Pattern Matching

                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      "Paymasters come in only two sizes: one sort shows you where the book says that you can't have what you've got coming to you; the second sort digs through the book until he finds a paragraph that lets you have what you need even if you don't rate it."

                                                                                                                                      +
                                                                                                                                      Robert A. Heinlein, The Door Into Summer
                                                                                                                                      + +
                                                                                                                                      +

                                                                                                                                      Regular Expressions and Pattern Matching are important features in any programming language; but surprisingly few come with robust support for high-level pattern matching out of the box. Lisp comes with all the low-level building blocks necessary for high-level pattern matching, but high-level pattern matching was not included in the ANSI Standard.

                                                                                                                                      +

                                                                                                                                      Obviously, the gold-standard of pattern matching is Perl's Regular Expressions---and they are fully integrated with the Perl language so they can be used in-line everywhere. The main complaint about regular expressions is that they quickly become dense and unreadable. So many other strategies for pattern matching exist, which aim to increase legibility.

                                                                                                                                      +

                                                                                                                                      Perhaps one of the less well-known, but most important, facts about Lisp, is that Lisp is better at regular expressions than Perl---consider that! Perl is fast, concise, and highly optimized; and regular expressions originate from Perl. But the de-facto implementation of Perl-compatible regular expressions for Common Lisp, CL-PPCRE, is on average twice as fast as Perl itself. This is just one of the many examples that illustrate, with hard benchmark results for proof, that Lisp is better than C for squeezing out maximum performance of your code.

                                                                                                                                      +

                                                                                                                                      In this Extra Credit chapter, we will take a tour of writing Perl-compatible regular expressions with the CL-PPCRE library, introduce alternative, more Lispy approaches to pattern matching with the Optima and ESRAP libraries, and then take a look at the CL21 project---which includes in-line regular expressions, amongst its many other cool features.

                                                                                                                                      +

                                                                                                                                      This chapter will contain exercises on using:

                                                                                                                                      +
                                                                                                                                        +
                                                                                                                                      • CL-PPCRE
                                                                                                                                      • +
                                                                                                                                      • Optima
                                                                                                                                      • +
                                                                                                                                      • ESRAP
                                                                                                                                      • +
                                                                                                                                      • CL21
                                                                                                                                      • +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.1

                                                                                                                                      +

                                                                                                                                      Pattern Matching

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.2

                                                                                                                                      +

                                                                                                                                      Pattern Matching with Regular Expressions

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.3

                                                                                                                                      +

                                                                                                                                      Regular Expression Syntax

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.4

                                                                                                                                      +

                                                                                                                                      String Escapes

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.5

                                                                                                                                      +

                                                                                                                                      In-line Regular Expressions with CL21

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.6

                                                                                                                                      +

                                                                                                                                      Optimized Pattern Matching with Optima

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.7

                                                                                                                                      +

                                                                                                                                      More Optima

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.8

                                                                                                                                      +

                                                                                                                                      Even More Optima

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.9

                                                                                                                                      +

                                                                                                                                      Pattern Matching with ESRAP

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.10

                                                                                                                                      +

                                                                                                                                      More ESRAP

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      +

                                                                                                                                      Exercise 2.2.11

                                                                                                                                      +

                                                                                                                                      Even More ESRAP

                                                                                                                                      +
                                                                                                                                      
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      + + +
                                                                                                                                      + +
                                                                                                                                      +
                                                                                                                                      +
                                                                                                                                      + +

                                                                                                                                      results matching ""

                                                                                                                                      +
                                                                                                                                        + +
                                                                                                                                        +
                                                                                                                                        + +

                                                                                                                                        No results matching ""

                                                                                                                                        + +
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        + +
                                                                                                                                        +
                                                                                                                                        + +
                                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                                        + + +
                                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-03-0-objects-control.html b/clones/llthw.common-lisp.dev/2-03-0-objects-control.html new file mode 100644 index 00000000..4e35cb0c --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-03-0-objects-control.html @@ -0,0 +1,1978 @@ + + + + + + + Objects and Control Structures ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                        +
                                                                                                                                        + + + + + + + + +
                                                                                                                                        + +
                                                                                                                                        + +
                                                                                                                                        + + + + + + + + +
                                                                                                                                        +
                                                                                                                                        + +
                                                                                                                                        +
                                                                                                                                        + +
                                                                                                                                        + +

                                                                                                                                        Chapter 2.3

                                                                                                                                        +

                                                                                                                                        Objects and Control Structures

                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        "Wisdom includes not getting angry unnecessarily. The Law ignores trifles and the wise man does, too."

                                                                                                                                        +
                                                                                                                                        Robert A. Heinlein, Job: A Comedy of Justice
                                                                                                                                        + +
                                                                                                                                        +

                                                                                                                                        Despite the common misconception that Lisp is a functional programming lanugage, Lisp has rich support for the Imperative and Object-Oriented paradigms---and these days, you'll find more fully Object-Oriented Lisp applications and libraries than purely-functional ones. While the tools for Imperative and Procedural programming are included alongside all the other standard features of Common Lisp, Object-oriented programming is encapsulated by CLOS: The Common Lisp Object System. As it turns out, you can also define CLOS classes and use them as types---but, fair warning, the inverse doesn't hold.

                                                                                                                                        +

                                                                                                                                        To differentiate from the purely-functional style, it will be helpful to introduce some new terminology as well. Some of these terms are baked right into the language specification, while others are adopted simply for convenience. Where official Lisp terminology differs from the mainstream, I will endeavour to make note of it.

                                                                                                                                        +

                                                                                                                                        First of all, when a function you write causes or relies upon side-effects in the dynamic scope, we will call that function a procedure. Some of these are also called destructive or in-place operations, if they modify an object in memory instead of returning a new object.

                                                                                                                                        +

                                                                                                                                        In CLOS, Functions that are specialized for a particular class and its descendents are called methods. Lisp also allows you to define unspecified generic functions, which act as a template for all methods of the same name in the current package. Typically, one writes generic functions to establish the public and private API of a class for its package---while there is no special distinction in CLOS for public and private methods, you establish the public methods on a class by exporting those symbols from your package, as normal.

                                                                                                                                        +

                                                                                                                                        Structs in Lisp are essentially the same in principle and use as Structs in C, or Prototype Functions in JavaScript. They're a quick and lightweight option when you just need a structured type to track state in your program; they are also useful for building full-blown state machines. Defining a Struct comes with a lot of automatically generated code that is representative of the sane defaults that in other languages you would have to define manually, such as type predicates, constructors, copiers, readers and writers. But the limitations of Structs can often be frustrating. Unless you're certain ahead of time that your application only needs the purposely limited feature-set of Structs, you should always start with CLOS.

                                                                                                                                        +

                                                                                                                                        Structs and Classes in Lisp have slots for data, which are similar to data members or class variables in other object-oriented programming languages. When defining a Struct or Class in Lisp, you are defining their slots. Generic functions and methods on classes are defined separately. One might say that the main difference between Structs and Classes in Lisp is that Classes allow for this specialization of generic functions; but of course, that is an over-simplification. As you will come to see, there are many fundamental differences between structs and classes that will inform your choices while developing software in Lisp.

                                                                                                                                        +

                                                                                                                                        You can always access the slots in a struct or class manually, but this is considered bad style---and sometimes it can even be dangerous. As mentioned above, the Struct definition macro automatically creates accessors for all the slots you define; CLOS offers you a choice, and in so doing, allows you to create separate reader and writer methods, or a bi-directional accessor method. CLOS classes also offer special initialization methods, and method wrapping, for fine-tuning control flow in the life-time of your objects.

                                                                                                                                        +

                                                                                                                                        CLOS, along with the Meta-Object Protocol, are considered the be-all and end-all of Object-Oriented Programming systems, far improving on the object-oriented programming experience you'd get from SmallTalk, Java, C#, C++, or Objective-C. While they can be daunting at first, the design of CLOS is actually quite elegant and fits perfectly into the Lisp ecosystem---typically you will never need to worry about the MOP, but on those rare cases you do, you'll be glad it's there.

                                                                                                                                        +

                                                                                                                                        Exercise 2.3.1

                                                                                                                                        +

                                                                                                                                        Blocks

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.2

                                                                                                                                        +

                                                                                                                                        More Blocks

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.3

                                                                                                                                        +

                                                                                                                                        Macroexpand: Hidden Blocks

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.4

                                                                                                                                        +

                                                                                                                                        Tagbodys

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.5

                                                                                                                                        +

                                                                                                                                        GO

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.6

                                                                                                                                        +

                                                                                                                                        More Tagbodys and GO

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.7

                                                                                                                                        +

                                                                                                                                        PROGN

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.8

                                                                                                                                        +

                                                                                                                                        More PROGN

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.9

                                                                                                                                        +

                                                                                                                                        PROG, PROG*, PROG1, and PROG2

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.10

                                                                                                                                        +

                                                                                                                                        PROGV

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.11

                                                                                                                                        +

                                                                                                                                        Structs

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.12

                                                                                                                                        +

                                                                                                                                        More Structs

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.13

                                                                                                                                        +

                                                                                                                                        Even More Structs

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.14

                                                                                                                                        +

                                                                                                                                        CLOS: Classes

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.15

                                                                                                                                        +

                                                                                                                                        CLOS: Slots

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.16

                                                                                                                                        +

                                                                                                                                        CLOS: More Slots

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.17

                                                                                                                                        +

                                                                                                                                        CLOS: Even More Slots

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.18

                                                                                                                                        +

                                                                                                                                        CLOS: Readers

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.19

                                                                                                                                        +

                                                                                                                                        CLOS: Writers

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.20

                                                                                                                                        +

                                                                                                                                        CLOS: Accessors

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.21

                                                                                                                                        +

                                                                                                                                        CLOS: Inheritance

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.22

                                                                                                                                        +

                                                                                                                                        CLOS: Multiple-Inheritance

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.23

                                                                                                                                        +

                                                                                                                                        CLOS: Generic Functions

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.24

                                                                                                                                        +

                                                                                                                                        CLOS: Methods

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.25

                                                                                                                                        +

                                                                                                                                        CLOS: More Methods

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.26

                                                                                                                                        +

                                                                                                                                        :BEFORE and :AFTER Methods

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        +

                                                                                                                                        Exercise 2.3.27

                                                                                                                                        +

                                                                                                                                        The Meta-Object Protocol

                                                                                                                                        +
                                                                                                                                        
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        + + +
                                                                                                                                        + +
                                                                                                                                        +
                                                                                                                                        +
                                                                                                                                        + +

                                                                                                                                        results matching ""

                                                                                                                                        +
                                                                                                                                          + +
                                                                                                                                          +
                                                                                                                                          + +

                                                                                                                                          No results matching ""

                                                                                                                                          + +
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          + +
                                                                                                                                          +
                                                                                                                                          + +
                                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                                          + + +
                                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-04-0-data-persistence.html b/clones/llthw.common-lisp.dev/2-04-0-data-persistence.html new file mode 100644 index 00000000..59cdec17 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-04-0-data-persistence.html @@ -0,0 +1,1925 @@ + + + + + + + Extra Credit: Persistence and Databases ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                          +
                                                                                                                                          + + + + + + + + +
                                                                                                                                          + +
                                                                                                                                          + +
                                                                                                                                          + + + + + + + + +
                                                                                                                                          +
                                                                                                                                          + +
                                                                                                                                          +
                                                                                                                                          + +
                                                                                                                                          + +

                                                                                                                                          Chapter 2.4 --- Extra Credit

                                                                                                                                          +

                                                                                                                                          Persistence and Databases

                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          "You have attributed conditions to villainy that simply result from stupidity."

                                                                                                                                          +
                                                                                                                                          Robert A. Heinlein, Logic of Empire
                                                                                                                                          + +
                                                                                                                                          +

                                                                                                                                          All applications that allow a user to create or modify data must also allow that user to store their data somewhere, either on their own filesystem, on a server in the cloud, or in a database, and load it back into memory again. After all, once an application quits, everything in its memory space is effectively lost. To have that data persist across sessions, it has to be stored somewhere, and loaded back into an application's memory when it is needed. Many strategies exist to achieve this---and we've looked at a couple simple ones already.

                                                                                                                                          +

                                                                                                                                          Another advantage of storing data outside of an application's memory space, is that it encourages you to validate all data before running it through your program. In any real-world application, this should be done anyway; but when you know the data is coming from an untrusted source (i.e., anyone who isn't you, the application developer), you're more likely to do things the right way. While validation of all program input is a non-trivial task, it is essential for building robust user experiences that can handle bad user input as well as malicious attacks against your software.

                                                                                                                                          +

                                                                                                                                          Whether you store your application's data in a file on a user's computer or in a database where a number of authorized users can access it, you need to spend some time thinking about every piece of data that your application might need to store. Imagine that the program is loading from scratch, and only has a saved file to restore everything from the last session to memory---if you've stored everything you need to, a user will be able to pick up right where they left off; if you missed anything, you might just annoy a user if it was nothing more than a trivial customization to the UI that you forgot to save, but you could just as easily crash the entire application and corrupt the user's data. Conversely, if data needs to be converted before being used, it's equally important to remember to convert both ways, on the way in, and on the way out.

                                                                                                                                          +

                                                                                                                                          Sometimes you may also want to serialize and store not just your data, but your code too---saving you the time and effort of rebuilding objects in memory from where they are stored. This is possible in Lisp because of its homoiconicity. Being able to treat code as data, and data as code can be just as much of a time-saver as it is a powerful tool for expressing code patterns in macros. Again, careful thought has to be put into your complete application's life-cycle---if you store executable code, expecting it to run in your application, you'll have to validate it before allowing it to be evaluated. This brings up the principle of secure programming---writing software with certain best practices up front, instead of merely adding security features on at the end.

                                                                                                                                          +

                                                                                                                                          Lastly, you can also dump an entire Lisp session to your file system, and run it instead of having to load everything into memory again. Everything you had in memory will be there again when you launch this dumped executable. This can be useful if you have a lot of customizations, or default packages that you use all the time---but naturally, this too comes with its caveats.

                                                                                                                                          +

                                                                                                                                          Exercise 2.4.1

                                                                                                                                          +

                                                                                                                                          Validating Input

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.2

                                                                                                                                          +

                                                                                                                                          More Validation

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.3

                                                                                                                                          +

                                                                                                                                          Even More Validation

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.4

                                                                                                                                          +

                                                                                                                                          Binary File Formats

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.5

                                                                                                                                          +

                                                                                                                                          Outputting Binary Files

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.6

                                                                                                                                          +

                                                                                                                                          Reading Binary Files

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.7

                                                                                                                                          +

                                                                                                                                          Binary Files as Programs

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.8

                                                                                                                                          +

                                                                                                                                          Hand Compilation

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.9

                                                                                                                                          +

                                                                                                                                          Custom Lisp Images

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.10

                                                                                                                                          +

                                                                                                                                          Dumping Custom Lisp Images

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.11

                                                                                                                                          +

                                                                                                                                          Loading Custom Lisp Images

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.12

                                                                                                                                          +

                                                                                                                                          Serializing Lisp Objects

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.13

                                                                                                                                          +

                                                                                                                                          More Serialization

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.14

                                                                                                                                          +

                                                                                                                                          Even More Serialization

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.15

                                                                                                                                          +

                                                                                                                                          Relational Databases

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.16

                                                                                                                                          +

                                                                                                                                          Document-based Databases

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          +

                                                                                                                                          Exercise 2.4.17

                                                                                                                                          +

                                                                                                                                          Graph Databases

                                                                                                                                          +
                                                                                                                                          
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          + + +
                                                                                                                                          + +
                                                                                                                                          +
                                                                                                                                          +
                                                                                                                                          + +

                                                                                                                                          results matching ""

                                                                                                                                          +
                                                                                                                                            + +
                                                                                                                                            +
                                                                                                                                            + +

                                                                                                                                            No results matching ""

                                                                                                                                            + +
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            + +
                                                                                                                                            +
                                                                                                                                            + +
                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                            + + +
                                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-05-0-extended-types.html b/clones/llthw.common-lisp.dev/2-05-0-extended-types.html new file mode 100644 index 00000000..613204bf --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-05-0-extended-types.html @@ -0,0 +1,1928 @@ + + + + + + + Extended Types ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                            +
                                                                                                                                            + + + + + + + + +
                                                                                                                                            + +
                                                                                                                                            + +
                                                                                                                                            + + + + + + + + +
                                                                                                                                            +
                                                                                                                                            + +
                                                                                                                                            +
                                                                                                                                            + +
                                                                                                                                            + +

                                                                                                                                            Chapter 2.5

                                                                                                                                            +

                                                                                                                                            Extended Types

                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            "Always listen to experts. They'll tell you what can't be done, and why. Then do it."

                                                                                                                                            +
                                                                                                                                            Robert A. Heinlein, Time Enough for Love
                                                                                                                                            + +
                                                                                                                                            +

                                                                                                                                            Besides the data types we've already seen---strings, integers, floats, complex numbers, vectors, arrays, lists, first-class functions, structs and CLOS classes---Common Lisp has a diverse set of specialized types to serve almost every need.

                                                                                                                                            +

                                                                                                                                            Many of these specialized data types have their own set of functions for working with them. While introducing each type, I will also be covering that type's specialized function interface, and various methods of type conversion.

                                                                                                                                            +

                                                                                                                                            Where the ANSI standard falls short of your needs, it provides a mature and rich type definition system. You can also, if needs must, mercilessly abuse CLOS to define your more complicated, structured types with classes---which also allows you to use generic functions and methods to provide operator overloading for them.

                                                                                                                                            +

                                                                                                                                            Exercise 2.5.1

                                                                                                                                            +

                                                                                                                                            Hash Tables

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.2

                                                                                                                                            +

                                                                                                                                            More Hash Tables

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.3

                                                                                                                                            +

                                                                                                                                            Even More Hash Tables

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.4

                                                                                                                                            +

                                                                                                                                            Sets

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.5

                                                                                                                                            +

                                                                                                                                            More Sets

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.6

                                                                                                                                            +

                                                                                                                                            Even More Sets

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.7

                                                                                                                                            +

                                                                                                                                            Simple Strings

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.8

                                                                                                                                            +

                                                                                                                                            More Simple Strings

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.9

                                                                                                                                            +

                                                                                                                                            Simple Arrays

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.10

                                                                                                                                            +

                                                                                                                                            More Simple Arrays

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.11

                                                                                                                                            +

                                                                                                                                            Byte Vectors

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.12

                                                                                                                                            +

                                                                                                                                            More Byte Vectors

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.13

                                                                                                                                            +

                                                                                                                                            Unsigned Bytes

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.14

                                                                                                                                            +

                                                                                                                                            Signed Bytes

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.15

                                                                                                                                            +

                                                                                                                                            Bit Vectors

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.16

                                                                                                                                            +

                                                                                                                                            More Bit Vectors

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.17

                                                                                                                                            +

                                                                                                                                            Defining Types

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            +

                                                                                                                                            Exercise 2.5.18

                                                                                                                                            +

                                                                                                                                            Defining Types with CLOS

                                                                                                                                            +
                                                                                                                                            
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            + + +
                                                                                                                                            + +
                                                                                                                                            +
                                                                                                                                            +
                                                                                                                                            + +

                                                                                                                                            results matching ""

                                                                                                                                            +
                                                                                                                                              + +
                                                                                                                                              +
                                                                                                                                              + +

                                                                                                                                              No results matching ""

                                                                                                                                              + +
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              + +
                                                                                                                                              +
                                                                                                                                              + +
                                                                                                                                              + + + + + + + + + + + + + + +
                                                                                                                                              + + +
                                                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-06-0-threads-memos-parallel.html b/clones/llthw.common-lisp.dev/2-06-0-threads-memos-parallel.html new file mode 100644 index 00000000..641ac0ef --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-06-0-threads-memos-parallel.html @@ -0,0 +1,1908 @@ + + + + + + + Extra Credit: Concurrency and Memoization ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                              +
                                                                                                                                              + + + + + + + + +
                                                                                                                                              + +
                                                                                                                                              + +
                                                                                                                                              + + + + + + + + +
                                                                                                                                              +
                                                                                                                                              + +
                                                                                                                                              +
                                                                                                                                              + +
                                                                                                                                              + +

                                                                                                                                              Chapter 2.6 --- Extra Credit

                                                                                                                                              +

                                                                                                                                              Concurrency and Memoization

                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              "I think the major problem in growing up is to become sophisticated without becoming cynical."

                                                                                                                                              +
                                                                                                                                              Robert A. Heinlein, I Will Fear No Evil
                                                                                                                                              + +
                                                                                                                                              +

                                                                                                                                              While John McCarthy had intended that the successor to the many different dialects of Lisp in the 70s and 80s would be a fully parallelized Lisp, his proposal for QLISP did not make it into the ANSI Common Lisp standard. Nevertheless, many libraries for threading and full concurrency exist for Common Lisp, and achieve the same ends.

                                                                                                                                              +

                                                                                                                                              Now, Memoization is a really useful tool to have that ties in well with the subject of concurrency. Memoization is a technique for caching the results of expensive computations, so that when a function is called again with the same arguments as one that has been memoized, it can pull the result from a cache instead of computing the function all over again. The usefulness of this scales exponentially against the computational difficulty of your program on one axis and the number of times you have to call the same function with the same arguments in a given session of your application on another.

                                                                                                                                              +

                                                                                                                                              Lastly, we will wrap up our first tour of concurrency in this chapter with a look at general asynchronous operations and event-oriented programming techniques. Using this, we will then create a very simple asynchronous web application!

                                                                                                                                              +

                                                                                                                                              Exercise 2.6.1

                                                                                                                                              +

                                                                                                                                              Threads

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.2

                                                                                                                                              +

                                                                                                                                              More Threads

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.3

                                                                                                                                              +

                                                                                                                                              Even More Threads

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.4

                                                                                                                                              +

                                                                                                                                              Memoization

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.5

                                                                                                                                              +

                                                                                                                                              More Memoization

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.6

                                                                                                                                              +

                                                                                                                                              Even More Memoization

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.7

                                                                                                                                              +

                                                                                                                                              Concurrency

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.8

                                                                                                                                              +

                                                                                                                                              More Concurrency

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.9

                                                                                                                                              +

                                                                                                                                              Even More Concurrency

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.10

                                                                                                                                              +

                                                                                                                                              Asynchronous Web Applications

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.11

                                                                                                                                              +

                                                                                                                                              Event Loops

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.12

                                                                                                                                              +

                                                                                                                                              Routes

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.13

                                                                                                                                              +

                                                                                                                                              Promises

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              +

                                                                                                                                              Exercise 2.6.14

                                                                                                                                              +

                                                                                                                                              Futures

                                                                                                                                              +
                                                                                                                                              
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              + + +
                                                                                                                                              + +
                                                                                                                                              +
                                                                                                                                              +
                                                                                                                                              + +

                                                                                                                                              results matching ""

                                                                                                                                              +
                                                                                                                                                + +
                                                                                                                                                +
                                                                                                                                                + +

                                                                                                                                                No results matching ""

                                                                                                                                                + +
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                + +
                                                                                                                                                +
                                                                                                                                                + +
                                                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                                                + + +
                                                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-07-0-logic-and-more-math.html b/clones/llthw.common-lisp.dev/2-07-0-logic-and-more-math.html new file mode 100644 index 00000000..5c09b7c7 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-07-0-logic-and-more-math.html @@ -0,0 +1,1945 @@ + + + + + + + Logic and Advanced Math ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                +
                                                                                                                                                + + + + + + + + +
                                                                                                                                                + +
                                                                                                                                                + +
                                                                                                                                                + + + + + + + + +
                                                                                                                                                +
                                                                                                                                                + +
                                                                                                                                                +
                                                                                                                                                + +
                                                                                                                                                + +

                                                                                                                                                Chapter 2.7

                                                                                                                                                +

                                                                                                                                                Logic and Advanced Math

                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                "...Mathematics need not have use; it was a game, like chess but more fun."

                                                                                                                                                +
                                                                                                                                                Robert A. Heinlein, Citizen of the Galaxy
                                                                                                                                                + +
                                                                                                                                                +

                                                                                                                                                Revision Note: Intro text needs complete rewrite.

                                                                                                                                                +

                                                                                                                                                We've dabbled in basic math already, and chances are high that in every-day programming, that might be all you ever need. However, there are many problem domains that require a sophisticated understanding of advanced logic, Lisp's built-in tools for modular arithmetic and trigonometry, and the implementation of functions to support number theory, linear algebra, and calculus; for example, game development, artificial intelligence, computational physics, cryptography, FINTECH, and everything in the Crypto-Currency space. Even as "just a web developer", on-line security is becoming ever more important as developers are pushed to get the web experience ever closer to the desktop experience---and cryptography plays a central role in that. As the saying goes, "the more you know..."

                                                                                                                                                +

                                                                                                                                                Of course, by this point you should no longer be afraid of math, since every line of code you write in Lisp, no matter the paradigm, is formally expressed as an S-Expression in the Lambda Calculus. While what you're doing may not conform to the conception of pure functional programming, every expression you write that is evaluated as a proper form returns some result. At the end of the day, that's all math really is---a set of formally expressed rules that operate on quantitative data. And everything in a computer is quantitative, whether you would normally think of it that way or not. That Lisp adapts a purely mathematical model underneath in its implementation, and allows qualitative logic to be built on top of a quantifiable system is a feature---and an exciting one. Lisp demonstrates how all qualitative systems can be reduced to quantitative. In the age-old debate of philisophy vs. science, the importance of this cannot be understated. And this should also serve as an explanation as to why Lisp Hackers always say that programming is math, while developers from other languages simply fail to see this basic tenet of computer science.

                                                                                                                                                +

                                                                                                                                                But Math is more important than even that, to all programmers. Every program that can be written can be abstracted and generalized to a formal mathematical definition, and in so doing, can be simplified and made more elegant. Consider the problem of 3D Graphics, whether for gaming, simulation, virtual reality, augmented reality, or immersive interfaces. You can use 3D Graphics applications such as CAD or Blender, or the myriad of robust proprietary alternatives, to visually create your 3D artwork and assets---there's nothing wrong with this, as for artists it is quite intuitive. However, a mathematician can achieve the same end with pure code. These 3D assets are all collections of vertices in cartesian space, and they can be generated procedurally just as easily---and sometimes more easily---than they can be created with a 3D graphics application. It just depends on how well you understand the math behind 3D graphics.

                                                                                                                                                +

                                                                                                                                                Lisp is particularly good for generating 3D graphics without having to use assets created in a third-party application. In fact, that was one of the greatest strengths of the fabled Lisp Machines. In Part Three we will be tackling this problem head-on, to create a complete 3D game without any third-party assets. Just code. This chapter will provide you with all the math you'll need to achieve that feat---any many, many more.

                                                                                                                                                +

                                                                                                                                                Exercise 2.7.1

                                                                                                                                                +

                                                                                                                                                Formal Logic

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.2

                                                                                                                                                +

                                                                                                                                                Boolean Logic on Integers

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.3

                                                                                                                                                +

                                                                                                                                                Boolean Logic on Bit-Vectors

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.4

                                                                                                                                                +

                                                                                                                                                Prime Numbers

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.5

                                                                                                                                                +

                                                                                                                                                Prime Factorization

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.6

                                                                                                                                                +

                                                                                                                                                Modular Arithmetic

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.7

                                                                                                                                                +

                                                                                                                                                Imaginary Numbers

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.8

                                                                                                                                                +

                                                                                                                                                Complex Numbers

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.9

                                                                                                                                                +

                                                                                                                                                Trigonometry

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.10

                                                                                                                                                +

                                                                                                                                                More Trigonometry

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.11

                                                                                                                                                +

                                                                                                                                                Geometry

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.12

                                                                                                                                                +

                                                                                                                                                More Geometry

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.13

                                                                                                                                                +

                                                                                                                                                Even More Geometry

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.14

                                                                                                                                                +

                                                                                                                                                The GSLL Library

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.15

                                                                                                                                                +

                                                                                                                                                Linear Algebra with GSLL

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.16

                                                                                                                                                +

                                                                                                                                                More Linear Algebra

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.17

                                                                                                                                                +

                                                                                                                                                Even More Linear Algebra

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.18

                                                                                                                                                +

                                                                                                                                                Calculus with GSLL

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.19

                                                                                                                                                +

                                                                                                                                                More Calculus

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.20

                                                                                                                                                +

                                                                                                                                                Even More Calculus

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                +

                                                                                                                                                Exercise 2.7.21

                                                                                                                                                +

                                                                                                                                                Further Explorations with GSLL

                                                                                                                                                +
                                                                                                                                                
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                + + +
                                                                                                                                                + +
                                                                                                                                                +
                                                                                                                                                +
                                                                                                                                                + +

                                                                                                                                                results matching ""

                                                                                                                                                +
                                                                                                                                                  + +
                                                                                                                                                  +
                                                                                                                                                  + +

                                                                                                                                                  No results matching ""

                                                                                                                                                  + +
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  + +
                                                                                                                                                  +
                                                                                                                                                  + +
                                                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                                                  + + +
                                                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-08-0-number-theory.html b/clones/llthw.common-lisp.dev/2-08-0-number-theory.html new file mode 100644 index 00000000..64b69b37 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-08-0-number-theory.html @@ -0,0 +1,1947 @@ + + + + + + + Extra Credit: Number Theory ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                  +
                                                                                                                                                  + + + + + + + + +
                                                                                                                                                  + +
                                                                                                                                                  + +
                                                                                                                                                  + + + + + + + + +
                                                                                                                                                  +
                                                                                                                                                  + +
                                                                                                                                                  +
                                                                                                                                                  + +
                                                                                                                                                  + +

                                                                                                                                                  Chapter 2.8 --- Extra Credit

                                                                                                                                                  +

                                                                                                                                                  Number Theory

                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  "Some people insist that 'mediocre' is better than 'best.' They delight in clipping wings because they themselves can't fly. They despise brains because they have none. Pfah!"

                                                                                                                                                  +
                                                                                                                                                  Robert A. Heinlein, Have Space Suit---Will Travel
                                                                                                                                                  + +
                                                                                                                                                  +

                                                                                                                                                  Number Theory is a fun, but challenging domain for computer scientists---many aspects of it pose intractable problems for classical computation, forcing us to look to novel technologies for solutions, such as Quantum Computation. But in the age of concurrency, there are some minor tweaks and adjustments that can be made to the established algorithms, so that while we still cannot efficiently factorize the multiplication of two large primes, we can at least push classical computing to its absolute limit.

                                                                                                                                                  +

                                                                                                                                                  Through the excercises in this chapter, we will put together a Number Theory library that can be included in other projects, and contains a number of useful techniques for algorithm design, optimization, unit testing, and further develops on the iterative, incremental development pattern encouraged in Lisp. We will approach each problem from its theoretical ideal, and then work towards a computational ideal that is as efficient as possible while retaining elegance in expression.

                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.1

                                                                                                                                                  +

                                                                                                                                                  Prime Numbers, Revisited

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.2

                                                                                                                                                  +

                                                                                                                                                  Alternate Approaches to Factorization

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.3

                                                                                                                                                  +

                                                                                                                                                  Factorizing Primes with Look-up Tables

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.4

                                                                                                                                                  +

                                                                                                                                                  Factorizing Primes with Pollard's Rho Algorithm

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.5

                                                                                                                                                  +

                                                                                                                                                  Factorizing Primes with Lenstra's Elliptical Curve

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.6

                                                                                                                                                  +

                                                                                                                                                  Factorizing Primes with the Quadratic Sieve

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.7

                                                                                                                                                  +

                                                                                                                                                  Factorizing Primes with the General Number Field Sieve

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.8

                                                                                                                                                  +

                                                                                                                                                  Automatic Factorization Algorithm Selection

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.9

                                                                                                                                                  +

                                                                                                                                                  Polynomials

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.10

                                                                                                                                                  +

                                                                                                                                                  More Polynomials

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.11

                                                                                                                                                  +

                                                                                                                                                  Even More Polynomials

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.12

                                                                                                                                                  +

                                                                                                                                                  Modular Exponentiation

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.13

                                                                                                                                                  +

                                                                                                                                                  More Modular Exponentiation

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.14

                                                                                                                                                  +

                                                                                                                                                  Inverse Modulus

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.15

                                                                                                                                                  +

                                                                                                                                                  The Jacobi Function

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.16

                                                                                                                                                  +

                                                                                                                                                  The Euler Totient Function

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.17

                                                                                                                                                  +

                                                                                                                                                  The Carmichael Functions

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.18

                                                                                                                                                  +

                                                                                                                                                  More Carmichael Functions

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.19

                                                                                                                                                  +

                                                                                                                                                  Even More Carmichael Functions

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.20

                                                                                                                                                  +

                                                                                                                                                  Optimizing for Performance

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.21

                                                                                                                                                  +

                                                                                                                                                  Optimizing for Memory Use

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  +

                                                                                                                                                  Exercise 2.8.22

                                                                                                                                                  +

                                                                                                                                                  Putting It All Together

                                                                                                                                                  +
                                                                                                                                                  
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  + + +
                                                                                                                                                  + +
                                                                                                                                                  +
                                                                                                                                                  +
                                                                                                                                                  + +

                                                                                                                                                  results matching ""

                                                                                                                                                  +
                                                                                                                                                    + +
                                                                                                                                                    +
                                                                                                                                                    + +

                                                                                                                                                    No results matching ""

                                                                                                                                                    + +
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    + +
                                                                                                                                                    +
                                                                                                                                                    + +
                                                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                                                    + + +
                                                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-09-0-binary-octets-bits.html b/clones/llthw.common-lisp.dev/2-09-0-binary-octets-bits.html new file mode 100644 index 00000000..ba04c1b4 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-09-0-binary-octets-bits.html @@ -0,0 +1,1923 @@ + + + + + + + Binary Streams, Octet-Vectors, and Bit-Vectors ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                    +
                                                                                                                                                    + + + + + + + + +
                                                                                                                                                    + +
                                                                                                                                                    + +
                                                                                                                                                    + + + + + + + + +
                                                                                                                                                    +
                                                                                                                                                    + +
                                                                                                                                                    +
                                                                                                                                                    + +
                                                                                                                                                    + +

                                                                                                                                                    Chapter 2.9

                                                                                                                                                    +

                                                                                                                                                    Binary Streams, Octet-Vectors, and Bit-Vectors

                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    "I counted to ten slowly, using binary notation."

                                                                                                                                                    +
                                                                                                                                                    Robert A. Heinlein, The Door Into Summer
                                                                                                                                                    + +
                                                                                                                                                    +

                                                                                                                                                    Everything that happens inside a computer, happens as binary-encoded instruction sequences---and everything that is stored in memory or on your filesystem, is also stored in binary. When people think of "machine language", they often think in terms of assembly language---but even that is a transliteration for the benefit of humans. The machine---your computer---only understands 1's and 0's.

                                                                                                                                                    +

                                                                                                                                                    You can do a lot with high-level programming constructs, but when performance is critical, or you need to get down to the nitty-gritty for fine-tuned control, binary is your friend. And naturally, Lisp makes it as simple as possible to work with binary data, whether working over a network, accessing the file system, or connecting to hardware with a driver.

                                                                                                                                                    +

                                                                                                                                                    In this chapter we will go into much more detail on the subject of binary streams, octet-vectors, and bit-vectors. We've seen them all before, but only in passing---now it's time to take on the subjects of signed and unsigned bytes, little-endian and big-endian bit ordering, manipulating bits, conversion between bit-vectors, octet-vectors, and their integer equivalents, and of course, bit-wise logic and binary arithmetic. We have also already covered the binary, octet, and hexadecimal notation system for integers, but a formal tour of those notations will also be helpful to this discussion, so we'll tackle that first.

                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.1

                                                                                                                                                    +

                                                                                                                                                    Base and Order

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.2

                                                                                                                                                    +

                                                                                                                                                    Byte-Vectors

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.3

                                                                                                                                                    +

                                                                                                                                                    Bit-Vectors

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.4

                                                                                                                                                    +

                                                                                                                                                    Integers as Bytes

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.5

                                                                                                                                                    +

                                                                                                                                                    Unsigned Bytes

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.6

                                                                                                                                                    +

                                                                                                                                                    Signed Bytes

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.7

                                                                                                                                                    +

                                                                                                                                                    Big-Endian Byte Ordering

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.8

                                                                                                                                                    +

                                                                                                                                                    Little-Endian Byte Ordering

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.9

                                                                                                                                                    +

                                                                                                                                                    Bit-Shifting

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.10

                                                                                                                                                    +

                                                                                                                                                    Bit-wise Logic

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.11

                                                                                                                                                    +

                                                                                                                                                    Byte-Vector Arithmetic

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.12

                                                                                                                                                    +

                                                                                                                                                    Bit-Vector Arithmetic

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.13

                                                                                                                                                    +

                                                                                                                                                    Binary Streams

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Exercise 2.9.14

                                                                                                                                                    +

                                                                                                                                                    Binary Sockets and Networks

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Extra Credit Exercise 2.9.15

                                                                                                                                                    +

                                                                                                                                                    Simulating Hardware in Lisp

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Extra Credit Exercise 2.9.16

                                                                                                                                                    +

                                                                                                                                                    Binary Instruction Sets

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    +

                                                                                                                                                    Extra Credit Exercise 2.9.17

                                                                                                                                                    +

                                                                                                                                                    Assembly Instructions

                                                                                                                                                    +
                                                                                                                                                    
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    + + +
                                                                                                                                                    + +
                                                                                                                                                    +
                                                                                                                                                    +
                                                                                                                                                    + +

                                                                                                                                                    results matching ""

                                                                                                                                                    +
                                                                                                                                                      + +
                                                                                                                                                      +
                                                                                                                                                      + +

                                                                                                                                                      No results matching ""

                                                                                                                                                      + +
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      + +
                                                                                                                                                      +
                                                                                                                                                      + +
                                                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                                                      + + +
                                                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-10-0-improved-text-adventure-engine.html b/clones/llthw.common-lisp.dev/2-10-0-improved-text-adventure-engine.html new file mode 100644 index 00000000..6e0add48 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-10-0-improved-text-adventure-engine.html @@ -0,0 +1,1904 @@ + + + + + + + Extra Credit: An Improved Text Adventure Engine ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                      +
                                                                                                                                                      + + + + + + + + +
                                                                                                                                                      + +
                                                                                                                                                      + +
                                                                                                                                                      + + + + + + + + +
                                                                                                                                                      +
                                                                                                                                                      + +
                                                                                                                                                      +
                                                                                                                                                      + +
                                                                                                                                                      + +

                                                                                                                                                      Chapter 2.10 --- Extra Credit

                                                                                                                                                      +

                                                                                                                                                      An Improved Text Adventure Engine

                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      "Oratory is a null program."

                                                                                                                                                      +
                                                                                                                                                      Robert A. Heinlein, The Moon Is a Harsh Mistress
                                                                                                                                                      + +
                                                                                                                                                      +

                                                                                                                                                      You've been working hard, and now it's time to reward yourself with some more fun! We will now take everything that we've learned so far and put it together to make a Game Engine---one which you can use to create any text-based adventure you like, just by filling out a plain-text game script file. This engine should also be general enough so that it can be extended later to include graphics and animation, but still lets you create your games with plain text files.

                                                                                                                                                      +

                                                                                                                                                      Let's consider a few aspects of games that make them the most fun. First of all, the game world should be comprehensively interactive. Players expect to be able to interact with everything they see as they journey through your game world---and they like to be rewarded for their curiosity. This point holds for characters, objects, and rooms---so, as we are implementing our game engine, we need to implement it in such a way that everything is interactive, and the game world is built dynamically from the objects, characters, and rooms you provide, without you having to manually, and redundantly, describe each room that is entered by a player. This kind of approach will also help you manage your environment better, since whenever an object is added to a room, or an NPC or enemy character enters a room, the player can experience these changes to the game world effectively in real-time. Players also like when a game keeps track of their journey through the game world, and notifies them of changes since the last time they were there. It is also a nice touch when the game differentiates between changes that the player made versus changes that other characters made to the environment. Players also like puzzles to solve, and various tests of their skills and progress---these challenges typically should scale to their ability, as well as scaling against their progress. Naturally, Players also expect NPCs to have at least a basic AI---so NPCs and enemies should be able to do anything the player can do in the game world, and come to these decisions on their own, or in response to player actions. Lastly, players also like to know that their progress can be saved, so that if they need to stop playing the game and get back to work, or a challenge bests them and they die, they can go back and pick up where they left off.

                                                                                                                                                      +

                                                                                                                                                      I know that seems like a lot of work! But Lisp helps manage the difficulty. To aid in our efforts, we will be using CLOS to write a fully object-oriented game engine---which will help us trim down the code to the minimum through class inheritence, generic functions, and methods specialized on those classes. Our games will then be built dynamically at run time from the game scripts we provide.

                                                                                                                                                      +

                                                                                                                                                      As a final note, it bears mentioning that this isn't a book on AI---so we'll simply be using the best techniques for the current job without much justification or explanation. For a broader introduction to specialized topics, you can turn to the References section of this website.

                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.1

                                                                                                                                                      +

                                                                                                                                                      The Player and Character Classes

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.2

                                                                                                                                                      +

                                                                                                                                                      The Room and Object Classes

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.3

                                                                                                                                                      +

                                                                                                                                                      Actions

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.4

                                                                                                                                                      +

                                                                                                                                                      The Game World

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.5

                                                                                                                                                      +

                                                                                                                                                      Navigation

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.6

                                                                                                                                                      +

                                                                                                                                                      Basic Agents

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.7

                                                                                                                                                      +

                                                                                                                                                      Agent Attitudes

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Exercise 2.10.8

                                                                                                                                                      +

                                                                                                                                                      Saved Game Files

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Extra Credit Exercise 2.10.9

                                                                                                                                                      +

                                                                                                                                                      Multi-User Dungeons

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Extra Credit Exercise 2.10.10

                                                                                                                                                      +

                                                                                                                                                      An Asynchronous Web App and Database

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Extra Credit Exercise 2.10.11

                                                                                                                                                      +

                                                                                                                                                      Accounts and Authentication

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Extra Credit Exercise 2.10.12

                                                                                                                                                      +

                                                                                                                                                      Auto-Save

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      +

                                                                                                                                                      Extra Credit Exercise 2.10.13

                                                                                                                                                      +

                                                                                                                                                      User-Created Assets

                                                                                                                                                      +
                                                                                                                                                      
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      + + +
                                                                                                                                                      + +
                                                                                                                                                      +
                                                                                                                                                      +
                                                                                                                                                      + +

                                                                                                                                                      results matching ""

                                                                                                                                                      +
                                                                                                                                                        + +
                                                                                                                                                        +
                                                                                                                                                        + +

                                                                                                                                                        No results matching ""

                                                                                                                                                        + +
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        + +
                                                                                                                                                        +
                                                                                                                                                        + +
                                                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                                                        + + +
                                                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-11-0-conditions.html b/clones/llthw.common-lisp.dev/2-11-0-conditions.html new file mode 100644 index 00000000..fab957c6 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-11-0-conditions.html @@ -0,0 +1,1903 @@ + + + + + + + Conditions and Error Handling ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                        +
                                                                                                                                                        + + + + + + + + +
                                                                                                                                                        + +
                                                                                                                                                        + +
                                                                                                                                                        + + + + + + + + +
                                                                                                                                                        +
                                                                                                                                                        + +
                                                                                                                                                        +
                                                                                                                                                        + +
                                                                                                                                                        + +

                                                                                                                                                        Chapter 2.11

                                                                                                                                                        +

                                                                                                                                                        Conditions and Error Handling

                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        "The death rate is the same for us as for anybody... one person, one death, sooner or later."

                                                                                                                                                        +
                                                                                                                                                        Robert A. Heinlein, Tunnel in the Sky
                                                                                                                                                        + +
                                                                                                                                                        +

                                                                                                                                                        No matter what you do, things will eventually go wrong in any program you write. You may have overlooked a bug, pass a function an object of the wrong data type, overestimated the ability of your users to follow instructions, incorrectly guaged the needs of your users, or, most commonly, kept working when you're burned-out, and really messed up your code. It happens to everyone.

                                                                                                                                                        +

                                                                                                                                                        Thankfully, Lisp has a very mature and robust system for handling errors gracefully, so that your users can have a seamless experience.

                                                                                                                                                        +

                                                                                                                                                        In this chapter, we'll take a tour through all of Lisp's built-in tools for handling, defining, and working with Conditions.

                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.1

                                                                                                                                                        +

                                                                                                                                                        Errors vs. Conditions

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.2

                                                                                                                                                        +

                                                                                                                                                        Signaling Conditions

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.3

                                                                                                                                                        +

                                                                                                                                                        ASSERT

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.4

                                                                                                                                                        +

                                                                                                                                                        More ASSERT

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.5

                                                                                                                                                        +

                                                                                                                                                        Handling Conditions

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.6

                                                                                                                                                        +

                                                                                                                                                        HANDLER-CASE

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.7

                                                                                                                                                        +

                                                                                                                                                        More HANDLER-CASE

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.8

                                                                                                                                                        +

                                                                                                                                                        Even More HANDLER-CASE

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.9

                                                                                                                                                        +

                                                                                                                                                        HANDLER-BIND

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.10

                                                                                                                                                        +

                                                                                                                                                        More HANDLER-BIND

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.11

                                                                                                                                                        +

                                                                                                                                                        Even More HANDLER-BIND

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.12

                                                                                                                                                        +

                                                                                                                                                        Defining Conditions

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        +

                                                                                                                                                        Exercise 2.11.13

                                                                                                                                                        +

                                                                                                                                                        Defining Conditions, Again

                                                                                                                                                        +
                                                                                                                                                        
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        + + +
                                                                                                                                                        + +
                                                                                                                                                        +
                                                                                                                                                        +
                                                                                                                                                        + +

                                                                                                                                                        results matching ""

                                                                                                                                                        +
                                                                                                                                                          + +
                                                                                                                                                          +
                                                                                                                                                          + +

                                                                                                                                                          No results matching ""

                                                                                                                                                          + +
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          + +
                                                                                                                                                          +
                                                                                                                                                          + +
                                                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                                                          + + +
                                                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-12-0-2d-game.html b/clones/llthw.common-lisp.dev/2-12-0-2d-game.html new file mode 100644 index 00000000..8c86f53c --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-12-0-2d-game.html @@ -0,0 +1,1944 @@ + + + + + + + Extra Credit: Write a 2D Game ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                          +
                                                                                                                                                          + + + + + + + + +
                                                                                                                                                          + +
                                                                                                                                                          + +
                                                                                                                                                          + + + + + + + + +
                                                                                                                                                          +
                                                                                                                                                          + +
                                                                                                                                                          +
                                                                                                                                                          + +
                                                                                                                                                          + +

                                                                                                                                                          Chapter 2.12 --- Extra Credit

                                                                                                                                                          +

                                                                                                                                                          Write a 2D Game

                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          "Going to dance at my wake?"

                                                                                                                                                          +

                                                                                                                                                          "I don't dance," the lawyer answered, "but you tempt me to learn."

                                                                                                                                                          +
                                                                                                                                                          Robert A. Heinlein, I Will Fear No Evil
                                                                                                                                                          + +
                                                                                                                                                          +

                                                                                                                                                          Hopefully you've had a lot of fun writing and playing your own Text Adventures and MUD-like online games; but in today's gaming world, you may be hard-pressed to get your friends excited about working at the command line or out of a MUD console to try your new game. So now it's time to make a paradigm shift and start thinking about graphics and user interfaces.

                                                                                                                                                          +

                                                                                                                                                          We already have a game engine to work with, but it needs some major overhaul before we can write our first 2D game. We also have to determine what we mean by 2D game, since there are so many varieties to choose from---room-based graphical adventures, like the old Sierra classics; side-scrollers, like the old Nintendo games; rogue-likes; the list goes on. It would be useful if we could abstract all these different styles into our engine, so that we can use it to build all these different styles of 2D games. Luckily, we're working with Lisp, and that's exactly what it was made for: endless abstraction.

                                                                                                                                                          +

                                                                                                                                                          To support our endless whims and fancies, we will be using the lispbuilder-sdl library in our extended game engine, one of the better Lisp libraries available for working with graphics, audio, and all things gaming. We will also be generating our graphics and environments procedurally, so that we can use a minimum of assets and textures from open-source graphic libraries.

                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.1

                                                                                                                                                          +

                                                                                                                                                          An Intro to LISPBUILDER-SDL

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.2

                                                                                                                                                          +

                                                                                                                                                          The Display

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.3

                                                                                                                                                          +

                                                                                                                                                          Display Types

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.4

                                                                                                                                                          +

                                                                                                                                                          Clearing and Redrawing the Display

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.5

                                                                                                                                                          +

                                                                                                                                                          Display Buffering and Memory

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.6

                                                                                                                                                          +

                                                                                                                                                          Audio

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.7

                                                                                                                                                          +

                                                                                                                                                          More Audio

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.8

                                                                                                                                                          +

                                                                                                                                                          Even More Audio

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.9

                                                                                                                                                          +

                                                                                                                                                          Primitives

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.10

                                                                                                                                                          +

                                                                                                                                                          Graphics and Other Resources

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.11

                                                                                                                                                          +

                                                                                                                                                          Surfaces

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.12

                                                                                                                                                          +

                                                                                                                                                          Procedural Content Generation

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.13

                                                                                                                                                          +

                                                                                                                                                          Game Physics

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.14

                                                                                                                                                          +

                                                                                                                                                          The Game Loop

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.15

                                                                                                                                                          +

                                                                                                                                                          Input

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.16

                                                                                                                                                          +

                                                                                                                                                          More Input

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.17

                                                                                                                                                          +

                                                                                                                                                          Fonts

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.18

                                                                                                                                                          +

                                                                                                                                                          More Fonts

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.19

                                                                                                                                                          +

                                                                                                                                                          The 2D Game Engine

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.20

                                                                                                                                                          +

                                                                                                                                                          Abstractions of Rooms and Worlds

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          +

                                                                                                                                                          Exercise 2.12.21

                                                                                                                                                          +

                                                                                                                                                          Tidy Game Scripts

                                                                                                                                                          +
                                                                                                                                                          
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          + + +
                                                                                                                                                          + +
                                                                                                                                                          +
                                                                                                                                                          +
                                                                                                                                                          + +

                                                                                                                                                          results matching ""

                                                                                                                                                          +
                                                                                                                                                            + +
                                                                                                                                                            +
                                                                                                                                                            + +

                                                                                                                                                            No results matching ""

                                                                                                                                                            + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + +
                                                                                                                                                            +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                            + + +
                                                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-13-0-compiler.html b/clones/llthw.common-lisp.dev/2-13-0-compiler.html new file mode 100644 index 00000000..ee425c4e --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-13-0-compiler.html @@ -0,0 +1,1918 @@ + + + + + + + The Compiler ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            + +
                                                                                                                                                            + +
                                                                                                                                                            + + + + + + + + +
                                                                                                                                                            +
                                                                                                                                                            + +
                                                                                                                                                            +
                                                                                                                                                            + +
                                                                                                                                                            + +

                                                                                                                                                            Chapter 2.13

                                                                                                                                                            +

                                                                                                                                                            The Compiler

                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            "I will accept the rules that you feel necessary to your freedom. I am free, no matter what rules surround me. If I find them tolerable, I tolerate them; if I find them too obnoxious, I break them. I am free because I know that I alone am morally responsible for everything I do."

                                                                                                                                                            +
                                                                                                                                                            Robert A. Heinlein, The Moon Is a Harsh Mistress
                                                                                                                                                            + +
                                                                                                                                                            +

                                                                                                                                                            One of the great things about Lisp is that you can write a full application with clean, straightforward, simple, dynamic code that always gives you exactly what you mean---and in fact, that's what we've been doing so far; full-scale applications written this way won't be particularly performant and they'll be memory-hogs, but they will work, without you needing to worry about such things as Garbage Collection, static type declarations, memory allocation and deallocation, so on and so forth. But at this stage of development, your application isn't done. It's just a prototype.

                                                                                                                                                            +

                                                                                                                                                            Another great thing about Lisp is that you can also optimize your applications to the point of absurdity, achieving twice the performance as heavily optimized C code---such as was done with the CL-PPCRE library. That's what we'll be covering here---all the tools that the Common Lisp compiler offers that you'll need to milk your computer for every last GHz.

                                                                                                                                                            +

                                                                                                                                                            We will also be covering relevant techniques for profiling the performance of your code-base, minimizing extraneous consing, reviewing the disassembly of your compiled code, and static type declarations. And from here on out, we'll adopt all these techniques for subsequent exercises.

                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.1

                                                                                                                                                            +

                                                                                                                                                            TIME

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.2

                                                                                                                                                            +

                                                                                                                                                            Profiling with SB-PROFILE

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.3

                                                                                                                                                            +

                                                                                                                                                            Profiling with SB-SPROF

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.4

                                                                                                                                                            +

                                                                                                                                                            Consing

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.5

                                                                                                                                                            +

                                                                                                                                                            Less Consing

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.6

                                                                                                                                                            +

                                                                                                                                                            Even Less Consing

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.7

                                                                                                                                                            +

                                                                                                                                                            Static Typing

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.8

                                                                                                                                                            +

                                                                                                                                                            DECLARE

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.9

                                                                                                                                                            +

                                                                                                                                                            PROCLAIM

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.10

                                                                                                                                                            +

                                                                                                                                                            DECLAIM

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.11

                                                                                                                                                            +

                                                                                                                                                            EVAL-WHEN

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.12

                                                                                                                                                            +

                                                                                                                                                            DISASSEMBLE

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.13

                                                                                                                                                            +

                                                                                                                                                            Garbage Collection

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.14

                                                                                                                                                            +

                                                                                                                                                            More Garbage Collection

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.15

                                                                                                                                                            +

                                                                                                                                                            Even More Garbage Collection

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            +

                                                                                                                                                            Exercise 2.13.16

                                                                                                                                                            +

                                                                                                                                                            Purifying Lisp Images

                                                                                                                                                            +
                                                                                                                                                            
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + + +
                                                                                                                                                            + +
                                                                                                                                                            +
                                                                                                                                                            +
                                                                                                                                                            + +

                                                                                                                                                            results matching ""

                                                                                                                                                            +
                                                                                                                                                              + +
                                                                                                                                                              +
                                                                                                                                                              + +

                                                                                                                                                              No results matching ""

                                                                                                                                                              + +
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              + +
                                                                                                                                                              +
                                                                                                                                                              + +
                                                                                                                                                              + + + + + + + + + + + + + + +
                                                                                                                                                              + + +
                                                                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-14-0-tree-shaker.html b/clones/llthw.common-lisp.dev/2-14-0-tree-shaker.html new file mode 100644 index 00000000..0414bf35 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-14-0-tree-shaker.html @@ -0,0 +1,1912 @@ + + + + + + + Extra Credit: Write a Tree-Shaker ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                              +
                                                                                                                                                              + + + + + + + + +
                                                                                                                                                              + +
                                                                                                                                                              + +
                                                                                                                                                              + + + + + + + + +
                                                                                                                                                              +
                                                                                                                                                              + +
                                                                                                                                                              +
                                                                                                                                                              + +
                                                                                                                                                              + +

                                                                                                                                                              Chapter 2.14 --- Extra Credit

                                                                                                                                                              +

                                                                                                                                                              Write a Tree-Shaker

                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              "Whatever the answers are, here's one monkey that's going to keep on climbing, and looking around him to see what he can see, as long as the tree holds out."

                                                                                                                                                              +
                                                                                                                                                              Robert A. Heinlein, Methuselah's Children
                                                                                                                                                              + +
                                                                                                                                                              +

                                                                                                                                                              You've probably noticed in previous exercises, that when creating executable binaries of your Lisp programs to distribute or share, their size on your file system has been somewhat larger than you expected---over 80 MBs even for just a simple command-line application. If you were to deploy this same Lisp application with a commercial implementation of ANSI Common Lisp, however, you would get a much smaller application: for a simple command-line application, probably less than 1 MB. What gives, right? That's a pretty big discrepancy!

                                                                                                                                                              +

                                                                                                                                                              As it turns out, whenever you dump a Common Lisp environment to an executable binary, you're dumping everything. The entire Lisp language, every contrib package, the REPL, the debugger, all the packages you've loaded in as dependencies, and your application itself. The commercial Lisps do this too---only they don't stop there, like the open-source implementations of Common Lisp---they then "shake the tree" of your Lisp application to prune all the unused symbols from the final executable. Your final executable binary then only contains a subset of Lisp needed to execute your program, and strips out everything else not needed for run-time.

                                                                                                                                                              +

                                                                                                                                                              There are pros and cons to both approaches. Many Lisp Hackers consider shipping the full Common Lisp environment with each instance of the application to be a feature---after all, you can embed a SWANK server into every app, and work with the live instance on the target platform, debugging and testing as it continues working. You can also provide a Lisp REPL to your users and let them customize everything in your program to their liking.

                                                                                                                                                              +

                                                                                                                                                              Commercial Lisps take a more traditional approach, and provide a clear separation between developers and users. So their binaries are stripped of everything that a user, in their view, should not have access to.

                                                                                                                                                              +

                                                                                                                                                              Whether or not you care about providing your users the full power of Common Lisp as a part of the application run-time, writing a tree-shaker is an interesting exercise, and may give you a deeper understanding of Lisp's implementation and execution on the machine level. To-date, the best example of a tree-shaker for SBCL was written several years ago by Juho Snellman, but as SBCL has gone under considerable development since that time, it requires a fresh perspective---which is a perfect opportunity for learning!

                                                                                                                                                              +

                                                                                                                                                              Revision Note: A More recent tree-shaker example is available from Burton Samograd, with some relevant chat history from IRC included.

                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.1

                                                                                                                                                              +

                                                                                                                                                              Shaking Trees vs. Stripping Binaries

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.2

                                                                                                                                                              +

                                                                                                                                                              Pruning Trees

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.3

                                                                                                                                                              +

                                                                                                                                                              Unneccessary Run-Time Packages

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.4

                                                                                                                                                              +

                                                                                                                                                              Full Garbage Collection

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.5

                                                                                                                                                              +

                                                                                                                                                              Disabling the Debugger

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.6

                                                                                                                                                              +

                                                                                                                                                              Type Safety

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.7

                                                                                                                                                              +

                                                                                                                                                              A Basic Tree-Shaker

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.8

                                                                                                                                                              +

                                                                                                                                                              Code-Walking

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.9

                                                                                                                                                              +

                                                                                                                                                              More Code-Walking

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.10

                                                                                                                                                              +

                                                                                                                                                              Even More Code-Walking

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.11

                                                                                                                                                              +

                                                                                                                                                              A Smart Tree-Shaker

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.12

                                                                                                                                                              +

                                                                                                                                                              NUKE-LISP-AND-DIE

                                                                                                                                                              +

                                                                                                                                                              aka, Optimize, Collect, Shake, Save, Purify, Compress and Die

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.13

                                                                                                                                                              +

                                                                                                                                                              Packaging the Tree-Shaker

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              +

                                                                                                                                                              Exercise 2.14.14

                                                                                                                                                              +

                                                                                                                                                              Revisiting the 2D Game Engine

                                                                                                                                                              +
                                                                                                                                                              
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              + + +
                                                                                                                                                              + +
                                                                                                                                                              +
                                                                                                                                                              +
                                                                                                                                                              + +

                                                                                                                                                              results matching ""

                                                                                                                                                              +
                                                                                                                                                                + +
                                                                                                                                                                +
                                                                                                                                                                + +

                                                                                                                                                                No results matching ""

                                                                                                                                                                + +
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                + +
                                                                                                                                                                +
                                                                                                                                                                + +
                                                                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                                                                + + +
                                                                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-15-0-docs-and-inspection.html b/clones/llthw.common-lisp.dev/2-15-0-docs-and-inspection.html new file mode 100644 index 00000000..00cc2206 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-15-0-docs-and-inspection.html @@ -0,0 +1,1904 @@ + + + + + + + Documentation and Inspection ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                +
                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                + +
                                                                                                                                                                + +
                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                +
                                                                                                                                                                + +
                                                                                                                                                                +
                                                                                                                                                                + +
                                                                                                                                                                + +

                                                                                                                                                                Chapter 2.15

                                                                                                                                                                +

                                                                                                                                                                Documentation and Inspection

                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                "This non-system holds together by having no togetherness, no uniformity, never seeking perfection, no Utopias---just answers good enough to get by, with lots of looseness and room for many ways and attitudes."

                                                                                                                                                                +
                                                                                                                                                                Robert A. Heinlein, Glory Road
                                                                                                                                                                + +
                                                                                                                                                                +

                                                                                                                                                                When exploring a new library, documentation of the source code is invaluable. In some cases, the ultimate failure or success of a project can rest squarely on how well it has been documented---but lets say you write a library that has no competition, so people use it anyway because it's the only tool available. How much time and effort can you save answering questions and solving issues, by providing clear and instructive documentation, use-cases, and tutorials up-front?

                                                                                                                                                                +

                                                                                                                                                                The same goes for commenting your source-code; sometimes you might think your code is perfectly self-explanatory, but then six-months down the road---or even the next day!---you come back to your code and have no idea what you were thinking when you implemented a critical function to your system. Imagine how a newcomer to your source code might feel!

                                                                                                                                                                +

                                                                                                                                                                Another problem can be the opaqueness of objects. In any serious project, you have all these complex, structured objects running in your program---they could be from any number of libraries, each of which could be using very different conventions. If only there was some way to see inside these black boxes!

                                                                                                                                                                +

                                                                                                                                                                Oh right, this is Lisp. You can get into the REPL of any running Lisp application and inspect everything.

                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.1

                                                                                                                                                                +

                                                                                                                                                                Documentation and Comments

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.2

                                                                                                                                                                +

                                                                                                                                                                More Documentation and Comments

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.3

                                                                                                                                                                +

                                                                                                                                                                Even More Documentation and Comments

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.4

                                                                                                                                                                +

                                                                                                                                                                DOCUMENTATION

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.5

                                                                                                                                                                +

                                                                                                                                                                Unreadable Objects

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.6

                                                                                                                                                                +

                                                                                                                                                                Modifying the Lisp Printer

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.7

                                                                                                                                                                +

                                                                                                                                                                DESCRIBE

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.8

                                                                                                                                                                +

                                                                                                                                                                More DESCRIBE

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.9

                                                                                                                                                                +

                                                                                                                                                                Even More DESCRIBE

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.10

                                                                                                                                                                +

                                                                                                                                                                INSPECT

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.11

                                                                                                                                                                +

                                                                                                                                                                More INSPECT

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Exercise 2.15.12

                                                                                                                                                                +

                                                                                                                                                                Even More INSPECT

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                +

                                                                                                                                                                Extra Credit Exercise 2.15.13

                                                                                                                                                                +

                                                                                                                                                                Documentation and Inspection in Emacs+SLIME

                                                                                                                                                                +
                                                                                                                                                                
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                + + +
                                                                                                                                                                + +
                                                                                                                                                                +
                                                                                                                                                                +
                                                                                                                                                                + +

                                                                                                                                                                results matching ""

                                                                                                                                                                +
                                                                                                                                                                  + +
                                                                                                                                                                  +
                                                                                                                                                                  + +

                                                                                                                                                                  No results matching ""

                                                                                                                                                                  + +
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  + +
                                                                                                                                                                  +
                                                                                                                                                                  + +
                                                                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                                                                  + + +
                                                                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-16-0-foreign-libs.html b/clones/llthw.common-lisp.dev/2-16-0-foreign-libs.html new file mode 100644 index 00000000..0d5d9cbf --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-16-0-foreign-libs.html @@ -0,0 +1,1882 @@ + + + + + + + Extra Credit: Foreign Libraries in Lisp ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                  +
                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                  + +
                                                                                                                                                                  + +
                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                  +
                                                                                                                                                                  + +
                                                                                                                                                                  +
                                                                                                                                                                  + +
                                                                                                                                                                  + +

                                                                                                                                                                  Chapter 2.16 --- Extra Credit

                                                                                                                                                                  +

                                                                                                                                                                  Foreign Libraries in Lisp

                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  "I was indeed a total stranger in an utterly strange and confusing land... but I do not think, in retrospect, that I would have made my condition worse had I simply blurted out my predicament. I would not have been believed."

                                                                                                                                                                  +
                                                                                                                                                                  Robert A. Heinlein, Job: A Comedy of Justice
                                                                                                                                                                  + +
                                                                                                                                                                  +

                                                                                                                                                                  Like many other languages these days, Lisp allows you to call foreign code libraries, compiled or otherwise, as if they were native code. Lisp was one of the first languages to include this feature, and the term "Foreign Function Interface" was introduced specifically for this functionality in Common Lisp.

                                                                                                                                                                  +

                                                                                                                                                                  We have already seen some foreign libraries in action---such as lispbuilder-sdl in Chapter 2.12, and a few database libraries in Chapter 2.4. In this chapter we will be exploring a variety of foreign function interface libraries available in Quicklisp, so that you can get a feel for working with Lisp in a diverse ecosystem of code from many different sources---even Python libraries!

                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.1

                                                                                                                                                                  +

                                                                                                                                                                  CL-COLLIDER: an interface to SuperCollider

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.2

                                                                                                                                                                  +

                                                                                                                                                                  CL-COLLIDER: Live-Hacking Audio

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.3

                                                                                                                                                                  +

                                                                                                                                                                  CL-COLLIDER: Audio-Generating Macros

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.4

                                                                                                                                                                  +

                                                                                                                                                                  CL+SSL: an interface to OpenSSL

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.5

                                                                                                                                                                  +

                                                                                                                                                                  GSLL: an interface to the GNU Scientific Library

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.6

                                                                                                                                                                  +

                                                                                                                                                                  Burgled-Batteries: a Python--Lisp Bridge

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.7

                                                                                                                                                                  +

                                                                                                                                                                  Burgled-Batteries and SciPy

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.8

                                                                                                                                                                  +

                                                                                                                                                                  Burgled-Batteries and Python GUI Libraries

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  +

                                                                                                                                                                  Exercise 2.16.9

                                                                                                                                                                  +

                                                                                                                                                                  Burgled-Batteries: Python In Lisp

                                                                                                                                                                  +
                                                                                                                                                                  
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  + + +
                                                                                                                                                                  + +
                                                                                                                                                                  +
                                                                                                                                                                  +
                                                                                                                                                                  + +

                                                                                                                                                                  results matching ""

                                                                                                                                                                  +
                                                                                                                                                                    + +
                                                                                                                                                                    +
                                                                                                                                                                    + +

                                                                                                                                                                    No results matching ""

                                                                                                                                                                    + +
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    + +
                                                                                                                                                                    +
                                                                                                                                                                    + +
                                                                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                                                                    + + +
                                                                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-17-0-debugging-testing.html b/clones/llthw.common-lisp.dev/2-17-0-debugging-testing.html new file mode 100644 index 00000000..18773b1b --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-17-0-debugging-testing.html @@ -0,0 +1,1902 @@ + + + + + + + Debugging and Unit Testing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                    +
                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                    + +
                                                                                                                                                                    + +
                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                    +
                                                                                                                                                                    + +
                                                                                                                                                                    +
                                                                                                                                                                    + +
                                                                                                                                                                    + +

                                                                                                                                                                    Chapter 2.17

                                                                                                                                                                    +

                                                                                                                                                                    Debugging and Unit Testing

                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    "I know, as the prime lesson of my profession, that good intentions are the source of more folly than all other causes put together."

                                                                                                                                                                    +
                                                                                                                                                                    Robert A. Heinlein, Glory Road
                                                                                                                                                                    + +
                                                                                                                                                                    +

                                                                                                                                                                    No matter what you do, how hard you try, your code will eventually break. You, or someone else maintaining your code, will make a mistake, or overlook that one use-case that brings your whole program down. It happens. Software is fragile by nature, and programmers are only human. So remember this: the debugger is your friend. It's only there to help you.

                                                                                                                                                                    +

                                                                                                                                                                    You've seen the interactive debugger enough times by now to have a general idea how it works, but Lisp has a lot more tools to help you debug as you go; you've already seen how to write and handle Conditions in Chapter 2.11---but that's just a small piece of a much bigger puzzle.

                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.1

                                                                                                                                                                    +

                                                                                                                                                                    The Debugger

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.2

                                                                                                                                                                    +

                                                                                                                                                                    Control Stack

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.3

                                                                                                                                                                    +

                                                                                                                                                                    Backtrace

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.4

                                                                                                                                                                    +

                                                                                                                                                                    Restarts

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.5

                                                                                                                                                                    +

                                                                                                                                                                    Stepping

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.6

                                                                                                                                                                    +

                                                                                                                                                                    LDB, the low-level debugger

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.7

                                                                                                                                                                    +

                                                                                                                                                                    More LDB

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.8

                                                                                                                                                                    +

                                                                                                                                                                    Even More LDB

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.9

                                                                                                                                                                    +

                                                                                                                                                                    Writing Tests

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.10

                                                                                                                                                                    +

                                                                                                                                                                    Regression Testing with FiveAM

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 2.17.11

                                                                                                                                                                    +

                                                                                                                                                                    More FiveAM

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Exercise 1.17.12

                                                                                                                                                                    +

                                                                                                                                                                    Even More FiveAM

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    +

                                                                                                                                                                    Extra Credit Exercise 2.17.13

                                                                                                                                                                    +

                                                                                                                                                                    Interactive Debugging in Emacs+SLIME

                                                                                                                                                                    +
                                                                                                                                                                    
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    + + +
                                                                                                                                                                    + +
                                                                                                                                                                    +
                                                                                                                                                                    +
                                                                                                                                                                    + +

                                                                                                                                                                    results matching ""

                                                                                                                                                                    +
                                                                                                                                                                      + +
                                                                                                                                                                      +
                                                                                                                                                                      + +

                                                                                                                                                                      No results matching ""

                                                                                                                                                                      + +
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      + +
                                                                                                                                                                      +
                                                                                                                                                                      + +
                                                                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                                                                      + + +
                                                                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-18-0-ffi.html b/clones/llthw.common-lisp.dev/2-18-0-ffi.html new file mode 100644 index 00000000..ad6a6a42 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-18-0-ffi.html @@ -0,0 +1,1873 @@ + + + + + + + Extra Credit: Write a Foreign Function Interface ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                      +
                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                      + +
                                                                                                                                                                      + +
                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                      +
                                                                                                                                                                      + +
                                                                                                                                                                      +
                                                                                                                                                                      + +
                                                                                                                                                                      + +

                                                                                                                                                                      Chapter 2.18 --- Extra Credit

                                                                                                                                                                      +

                                                                                                                                                                      Write a Foreign Function Interface

                                                                                                                                                                      +
                                                                                                                                                                      +

                                                                                                                                                                      "Geniuses and supergeniuses always make their own rules... they do not accept the monkey customs of their lessers."

                                                                                                                                                                      +
                                                                                                                                                                      Robert A. Heinlein, Friday
                                                                                                                                                                      + +
                                                                                                                                                                      +

                                                                                                                                                                      Revision Note: The intro text requires minor expansion, and there should be more exercises.

                                                                                                                                                                      +

                                                                                                                                                                      Extending on Chapter 2.16, we will now write our own Foreign Function Interface for the Oculus Rift SDK using CFFI. This particular use case poses some interesting challenges that will hopefully prove more generally useful to you in your career as a Lisp Hacker.

                                                                                                                                                                      +

                                                                                                                                                                      We will also be using this library in Chapters 3.6 and 3.7; so that should be a good motivation to see this through to the end!

                                                                                                                                                                      +

                                                                                                                                                                      Exercise 2.18.1

                                                                                                                                                                      +

                                                                                                                                                                      CFFI

                                                                                                                                                                      +
                                                                                                                                                                      
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      +

                                                                                                                                                                      Exercise 2.18.2

                                                                                                                                                                      +

                                                                                                                                                                      More CFFI

                                                                                                                                                                      +
                                                                                                                                                                      
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      +

                                                                                                                                                                      Exercise 2.18.3

                                                                                                                                                                      +

                                                                                                                                                                      Even More CFFI

                                                                                                                                                                      +
                                                                                                                                                                      
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      +

                                                                                                                                                                      Exercise 2.18.4

                                                                                                                                                                      +

                                                                                                                                                                      Grovelling

                                                                                                                                                                      +
                                                                                                                                                                      
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      +

                                                                                                                                                                      Exercise 2.18.5

                                                                                                                                                                      +

                                                                                                                                                                      SWIG

                                                                                                                                                                      +
                                                                                                                                                                      
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      +

                                                                                                                                                                      Exercise 2.18.6

                                                                                                                                                                      +

                                                                                                                                                                      The Oculus Rift SDK

                                                                                                                                                                      +
                                                                                                                                                                      
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      +

                                                                                                                                                                      Exercise 2.18.7

                                                                                                                                                                      +

                                                                                                                                                                      A Basic 3D World

                                                                                                                                                                      +
                                                                                                                                                                      
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      + + +
                                                                                                                                                                      + +
                                                                                                                                                                      +
                                                                                                                                                                      +
                                                                                                                                                                      + +

                                                                                                                                                                      results matching ""

                                                                                                                                                                      +
                                                                                                                                                                        + +
                                                                                                                                                                        +
                                                                                                                                                                        + +

                                                                                                                                                                        No results matching ""

                                                                                                                                                                        + +
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        + +
                                                                                                                                                                        +
                                                                                                                                                                        + +
                                                                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                                                                        + + +
                                                                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-19-0-essential-libs.html b/clones/llthw.common-lisp.dev/2-19-0-essential-libs.html new file mode 100644 index 00000000..0965d023 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-19-0-essential-libs.html @@ -0,0 +1,1952 @@ + + + + + + + Essential Lisp Libraries ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                        +
                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                        + +
                                                                                                                                                                        + +
                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                        +
                                                                                                                                                                        + +
                                                                                                                                                                        +
                                                                                                                                                                        + +
                                                                                                                                                                        + +

                                                                                                                                                                        Chapter 2.19

                                                                                                                                                                        +

                                                                                                                                                                        Essential Lisp Libraries

                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        "He seeks order, not truth. Suppose truth defies order, will he accept it? Will you? I think not."

                                                                                                                                                                        +
                                                                                                                                                                        Robert A. Heinlein, Life-Line
                                                                                                                                                                        + +
                                                                                                                                                                        +

                                                                                                                                                                        Revision Note: This chapter's intro text needs minor expansion.

                                                                                                                                                                        +

                                                                                                                                                                        Introduce or review through exercises a number of essential lisp libraries that are included in nearly all serious projects, in some cases being considered extensions to the standard.

                                                                                                                                                                        +

                                                                                                                                                                        For starters:

                                                                                                                                                                        +
                                                                                                                                                                          +
                                                                                                                                                                        • ASDF
                                                                                                                                                                        • +
                                                                                                                                                                        • Alexandria
                                                                                                                                                                        • +
                                                                                                                                                                        • CL-PPCRE
                                                                                                                                                                        • +
                                                                                                                                                                        • CL-FAD
                                                                                                                                                                        • +
                                                                                                                                                                        • Flexi-Streams
                                                                                                                                                                        • +
                                                                                                                                                                        • Babel
                                                                                                                                                                        • +
                                                                                                                                                                        • Ironclad
                                                                                                                                                                        • +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.1

                                                                                                                                                                        +

                                                                                                                                                                        ASDF

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.2

                                                                                                                                                                        +

                                                                                                                                                                        More ASDF

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.3

                                                                                                                                                                        +

                                                                                                                                                                        Even More ASDF

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.4

                                                                                                                                                                        +

                                                                                                                                                                        Alexandria

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.5

                                                                                                                                                                        +

                                                                                                                                                                        More Alexandria

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.6

                                                                                                                                                                        +

                                                                                                                                                                        Even More Alexandria

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.7

                                                                                                                                                                        +

                                                                                                                                                                        CL-PPCRE

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.8

                                                                                                                                                                        +

                                                                                                                                                                        More CL-PPCRE

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.9

                                                                                                                                                                        +

                                                                                                                                                                        Even More CL-PPCRE

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.10

                                                                                                                                                                        +

                                                                                                                                                                        CL-FAD

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.11

                                                                                                                                                                        +

                                                                                                                                                                        More CL-FAD

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.12

                                                                                                                                                                        +

                                                                                                                                                                        Even More CL-FAD

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.13

                                                                                                                                                                        +

                                                                                                                                                                        Flexi-Streams

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.14

                                                                                                                                                                        +

                                                                                                                                                                        More Flexi-Streams

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.15

                                                                                                                                                                        +

                                                                                                                                                                        Even More Flexi-Streams

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.16

                                                                                                                                                                        +

                                                                                                                                                                        Babel

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.17

                                                                                                                                                                        +

                                                                                                                                                                        More Babel

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.18

                                                                                                                                                                        +

                                                                                                                                                                        Even More Babel

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.19

                                                                                                                                                                        +

                                                                                                                                                                        Ironclad

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.20

                                                                                                                                                                        +

                                                                                                                                                                        More Ironclad

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        +

                                                                                                                                                                        Exercise 2.19.21

                                                                                                                                                                        +

                                                                                                                                                                        Even More Ironclad

                                                                                                                                                                        +
                                                                                                                                                                        
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        + + +
                                                                                                                                                                        + +
                                                                                                                                                                        +
                                                                                                                                                                        +
                                                                                                                                                                        + +

                                                                                                                                                                        results matching ""

                                                                                                                                                                        +
                                                                                                                                                                          + +
                                                                                                                                                                          +
                                                                                                                                                                          + +

                                                                                                                                                                          No results matching ""

                                                                                                                                                                          + +
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          + +
                                                                                                                                                                          +
                                                                                                                                                                          + +
                                                                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                                                                          + + +
                                                                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-20-0-packaging-libs.html b/clones/llthw.common-lisp.dev/2-20-0-packaging-libs.html new file mode 100644 index 00000000..04ca6ed4 --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-20-0-packaging-libs.html @@ -0,0 +1,1907 @@ + + + + + + + Extra Credit: Packaging Lisp Libraries ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                          +
                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                          + +
                                                                                                                                                                          + +
                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                          +
                                                                                                                                                                          + +
                                                                                                                                                                          +
                                                                                                                                                                          + +
                                                                                                                                                                          + +

                                                                                                                                                                          Chapter 2.20 --- Extra Credit

                                                                                                                                                                          +

                                                                                                                                                                          Packaging Lisp Libraries

                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          "A 'critic' is a man who creates nothing and thereby feels qualified to judge the work of creative men. There is logic in this; he is unbiased---he hates all creative people equally."

                                                                                                                                                                          +
                                                                                                                                                                          Robert A. Heinlein, Time Enough for Love
                                                                                                                                                                          + +
                                                                                                                                                                          +

                                                                                                                                                                          Now that you've got a solid grounding in writing, optimizing, debugging and testing your Lisp software, it's time to learn all about packaging your code for the wild---namely with ASDF, to be distributed in the Quicklisp package manager. You've been using ASDF system files and Quicklisp to manage your projects since Part One, but now it's time to take a closer look at the structure of these ASDF files, and all the awesome power they can hold.

                                                                                                                                                                          +

                                                                                                                                                                          But, as the famous saying goes, with great power comes great responsibility---there's a right way of packaging your libraries, and there are certain limitations as to what sort of project qualifies for inclusion in Quicklisp. We'll be covering all this and more.

                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.1

                                                                                                                                                                          +

                                                                                                                                                                          Considerations for a Useful Library

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.2

                                                                                                                                                                          +

                                                                                                                                                                          Quicklisp Library Submission Guidelines

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.3

                                                                                                                                                                          +

                                                                                                                                                                          Required System Metadata

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.4

                                                                                                                                                                          +

                                                                                                                                                                          ASDF In More Detail

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.5

                                                                                                                                                                          +

                                                                                                                                                                          System Dependencies

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.6

                                                                                                                                                                          +

                                                                                                                                                                          More System Dependencies

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.7

                                                                                                                                                                          +

                                                                                                                                                                          Components: Files and Modules

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.8

                                                                                                                                                                          +

                                                                                                                                                                          Component Interdependency

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.9

                                                                                                                                                                          +

                                                                                                                                                                          Multiple Systems and Packages

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.10

                                                                                                                                                                          +

                                                                                                                                                                          Test Suites

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.11

                                                                                                                                                                          +

                                                                                                                                                                          More Test Suites: FiveAM

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.12

                                                                                                                                                                          +

                                                                                                                                                                          More Test Suites: Prove

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.13

                                                                                                                                                                          +

                                                                                                                                                                          Continuous Integration Testing

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          +

                                                                                                                                                                          Exercise 2.20.14

                                                                                                                                                                          +

                                                                                                                                                                          Code Coverage Testing

                                                                                                                                                                          +
                                                                                                                                                                          
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          + + +
                                                                                                                                                                          + +
                                                                                                                                                                          +
                                                                                                                                                                          +
                                                                                                                                                                          + +

                                                                                                                                                                          results matching ""

                                                                                                                                                                          +
                                                                                                                                                                            + +
                                                                                                                                                                            +
                                                                                                                                                                            + +

                                                                                                                                                                            No results matching ""

                                                                                                                                                                            + +
                                                                                                                                                                            +
                                                                                                                                                                            +
                                                                                                                                                                            + +
                                                                                                                                                                            +
                                                                                                                                                                            + +
                                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                                            + + +
                                                                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/2-21-0-review.html b/clones/llthw.common-lisp.dev/2-21-0-review.html new file mode 100644 index 00000000..cfae4e0a --- /dev/null +++ b/clones/llthw.common-lisp.dev/2-21-0-review.html @@ -0,0 +1,1852 @@ + + + + + + + Detailed Syntax Review ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                            +
                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                            + +
                                                                                                                                                                            + +
                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                            +
                                                                                                                                                                            + +
                                                                                                                                                                            +
                                                                                                                                                                            + +
                                                                                                                                                                            + +

                                                                                                                                                                            Chapter 2.21

                                                                                                                                                                            +

                                                                                                                                                                            Detailed Review of Common Lisp

                                                                                                                                                                            +
                                                                                                                                                                            +

                                                                                                                                                                            "The best things in life are beyond money; their price is agony and sweat and devotion... and the price demanded for the most precious of all things in life is life itself---ultimate cost for perfect value."

                                                                                                                                                                            +
                                                                                                                                                                            Robert A. Heinlein, Starship Troopers
                                                                                                                                                                            + +
                                                                                                                                                                            +

                                                                                                                                                                            Brutal though it may have been, you have reached the end of Part Two. There is just one final challenge before you move on to the industry-themed practical challenges of Part Three---and that's to make your peace with the Common Lisp HyperSpec, and even learn to love it. The HyperSpec is, of course, the de-facto official specification of the Common Lisp language freely available to the public, its text at least partly extracted from the original standards document, ANSI X3.226 (which is now available in a revised version as ANSI INCITS 226-1994 (R2004)). If you'd prefer to use the official ANSI standard as your choice of reference over the HyperSpec, I don't think anyone in the Lisp community would fault you.

                                                                                                                                                                            +

                                                                                                                                                                            Lisp as a language gets a lot of flak from outsiders and newcomers to the language, simply because the HyperSpec looks like it hasn't been updated since 1994. As it so happens, it was created in 1996, so design-wise it looked old and out of date even then---and the current version is actually much improved over the original release, which had a silver background, and a harsh aqua banner with a slogan reading, "the very definition of class." But given that the HyperSpec is best viewed within Emacs beside your code in a text-based browser, so you can get right at the documentation text without any interference, it doesn't much matter what the HyperSpec looks like. What matters is that, aside from the ANSI Standard itself, it is the most complete reference manual to the language available. And it's free.

                                                                                                                                                                            +

                                                                                                                                                                            What the HyperSpec is not, however, is a tutorial or implementation guide---this book, Learn Lisp the Hard Way, has been your tutorial; the last tutorial you need to start your career as a professional Lisp Hacker is how to use the CLHS, and appreciate the magnitude and detail of that document. So that's what we'll cover here:

                                                                                                                                                                            +
                                                                                                                                                                              +
                                                                                                                                                                            • The organization and structure of the CLHS
                                                                                                                                                                            • +
                                                                                                                                                                            • Navigating the Chapters, Master Index, and Glossary
                                                                                                                                                                            • +
                                                                                                                                                                            • Understanding formal definitions of Common Lisp symbols
                                                                                                                                                                            • +
                                                                                                                                                                            • Searching the CLHS on the Web
                                                                                                                                                                            • +
                                                                                                                                                                            • Accessing the CLHS with Emacs+SLIME
                                                                                                                                                                            • +
                                                                                                                                                                            +

                                                                                                                                                                            The final challenge before you move on to Part Three is this:

                                                                                                                                                                            +
                                                                                                                                                                              +
                                                                                                                                                                            • Read through all chapters of the CLHS three times, carefully, making notes for yourself as you go
                                                                                                                                                                            • +
                                                                                                                                                                            • Study and memorize all symbols in the Common Lisp language, noting their class and type, and other interesting features about them
                                                                                                                                                                            • +
                                                                                                                                                                            • Review the formal definitions of all symbols until, from memory, you can write down on paper the semantics of every symbol
                                                                                                                                                                            • +
                                                                                                                                                                            +

                                                                                                                                                                            Only once you've fully internalized the Common Lisp HyperSpec, can you proudly boast that you're a Lisp Hacker; and then you can move on to Part Three. Good luck, and see you there!

                                                                                                                                                                            + + +
                                                                                                                                                                            + +
                                                                                                                                                                            +
                                                                                                                                                                            +
                                                                                                                                                                            + +

                                                                                                                                                                            results matching ""

                                                                                                                                                                            +
                                                                                                                                                                              + +
                                                                                                                                                                              +
                                                                                                                                                                              + +

                                                                                                                                                                              No results matching ""

                                                                                                                                                                              + +
                                                                                                                                                                              +
                                                                                                                                                                              +
                                                                                                                                                                              + +
                                                                                                                                                                              +
                                                                                                                                                                              + +
                                                                                                                                                                              + + + + + + + + + + + + + + +
                                                                                                                                                                              + + +
                                                                                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-00-00-overview.html b/clones/llthw.common-lisp.dev/3-00-00-overview.html new file mode 100644 index 00000000..f4463c37 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-00-00-overview.html @@ -0,0 +1,1863 @@ + + + + + + + Lisp So(u)rcery ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                              +
                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                              + +
                                                                                                                                                                              + +
                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                              +
                                                                                                                                                                              + +
                                                                                                                                                                              +
                                                                                                                                                                              + +
                                                                                                                                                                              + +

                                                                                                                                                                              PART THREE

                                                                                                                                                                              +

                                                                                                                                                                              Lisp So(u)rcery

                                                                                                                                                                              +
                                                                                                                                                                              +

                                                                                                                                                                              "I would be disappointed if everything I saw turned out to be something Western Electric will build once Bell Labs works the bugs out. There ought to be some magic, somewhere, just for flavor."

                                                                                                                                                                              +
                                                                                                                                                                              Robert A. Heinlein, Glory Road
                                                                                                                                                                              + +
                                                                                                                                                                              +

                                                                                                                                                                              Now that you've gotten a solid grounding in the Common Lisp language and some popular Lisp libraries, it's time to really challenge yourself. While up to this point, Extra Credit exercises have been mixed in-between fundamental language exercises, this part of the book is all practical exercises. It will guide you through many of the popular use-cases you will come across as a professional Lisp developer, and by the end of it, you will be able to work some real programming magic.

                                                                                                                                                                              +

                                                                                                                                                                              This part of the book will also be less prescriptive, and leave you to rely on your knowledge and instinct to complete the outlined projects. I will guide you through system architecture, laying out a project into user stories, and finding relevant libraries which can save you time; but I'm leaving the coding to you. When you complete each chapter, you can then compare your implementation against my own reference implementation and those of your peers. But remember, no cheating! It's important that you finish the project on your own and get it to run with only the information I've given you, before looking for alternate implementations to improve your style or methodology.

                                                                                                                                                                              +

                                                                                                                                                                              Chapters

                                                                                                                                                                              +
                                                                                                                                                                                +
                                                                                                                                                                              1. Real-World Web Apps
                                                                                                                                                                              2. +
                                                                                                                                                                              3. Typesetting
                                                                                                                                                                              4. +
                                                                                                                                                                              5. Native Mobile Applications
                                                                                                                                                                              6. +
                                                                                                                                                                              7. Cross-Platform Desktop Applications
                                                                                                                                                                              8. +
                                                                                                                                                                              9. Drivers, Daemons, and System-Utilities
                                                                                                                                                                              10. +
                                                                                                                                                                              11. Reverse Engineering
                                                                                                                                                                              12. +
                                                                                                                                                                              13. Graphics Rendering
                                                                                                                                                                              14. +
                                                                                                                                                                              15. OpenGL, SDL, and 3D Game Development
                                                                                                                                                                              16. +
                                                                                                                                                                              17. Audio Generation and Manipulation
                                                                                                                                                                              18. +
                                                                                                                                                                              19. Data Aggregation and Analysis
                                                                                                                                                                              20. +
                                                                                                                                                                              21. Cryptography and Security
                                                                                                                                                                              22. +
                                                                                                                                                                              23. Financial Software and Crypto-Currencies
                                                                                                                                                                              24. +
                                                                                                                                                                              25. Scientific Computing
                                                                                                                                                                              26. +
                                                                                                                                                                              27. Computational Physics
                                                                                                                                                                              28. +
                                                                                                                                                                              29. Quantum Computing
                                                                                                                                                                              30. +
                                                                                                                                                                              31. Natural Language Processing
                                                                                                                                                                              32. +
                                                                                                                                                                              33. Artificial Intelligence
                                                                                                                                                                              34. +
                                                                                                                                                                              35. Robotics
                                                                                                                                                                              36. +
                                                                                                                                                                              37. Space-Tech
                                                                                                                                                                              38. +
                                                                                                                                                                              39. Neuroscience and Thought-Controlled Computing
                                                                                                                                                                              40. +
                                                                                                                                                                              41. A Simple LispOS
                                                                                                                                                                              42. +
                                                                                                                                                                              43. Build Your Own Lisp Machine
                                                                                                                                                                              44. +
                                                                                                                                                                              45. Government and Military Grade Systems
                                                                                                                                                                              46. +
                                                                                                                                                                              + + +
                                                                                                                                                                              + +
                                                                                                                                                                              +
                                                                                                                                                                              +
                                                                                                                                                                              + +

                                                                                                                                                                              results matching ""

                                                                                                                                                                              +
                                                                                                                                                                                + +
                                                                                                                                                                                +
                                                                                                                                                                                + +

                                                                                                                                                                                No results matching ""

                                                                                                                                                                                + +
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                + +
                                                                                                                                                                                +
                                                                                                                                                                                + +
                                                                                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                                                                                + + +
                                                                                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-01-00-web-apps.html b/clones/llthw.common-lisp.dev/3-01-00-web-apps.html new file mode 100644 index 00000000..3c2715d6 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-01-00-web-apps.html @@ -0,0 +1,1899 @@ + + + + + + + Real-world Web Apps ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                +
                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                + +
                                                                                                                                                                                + +
                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                +
                                                                                                                                                                                + +
                                                                                                                                                                                +
                                                                                                                                                                                + +
                                                                                                                                                                                + +

                                                                                                                                                                                Chapter 3.1

                                                                                                                                                                                +

                                                                                                                                                                                Real-World Web Applications

                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                "Free will is a golden thread running through the frozen matrix of fixed events."

                                                                                                                                                                                +
                                                                                                                                                                                Robert A. Heinlein, The Rolling Stones
                                                                                                                                                                                + +
                                                                                                                                                                                +

                                                                                                                                                                                There is no other problem-domain more complicated than the Web. To be a successful web developer these days, you have to wear a lot of hats---you need to be a programmer, a graphic designer, a system administrator, a DBA, a security expert, you have to know the quirks of every platform and browser, mobile or desktop, you have to keep abreast of the cutting edge. It's an endless journey, and you'll always find the need to be better than you are.

                                                                                                                                                                                +

                                                                                                                                                                                One of the biggest problems with the Web is just how many languages you need to know to create a straightforward web application. It's not just HTML, CSS, a splattering of JavaScript, and your choice of PHP, Python, or Perl anymore. Now you need to learn a web framework, the language it's written in to write the server-side logic, an arbitrary templating language to create your interfaces, and new protocols like Comet or Websockets for real-time two-way communication between the server and client.

                                                                                                                                                                                +

                                                                                                                                                                                Lisp solves all these issues, and will give you an edge over the competition. You only need to know Lisp, and you can run a web server on any platform, generate your HTML, CSS, JavaScript front-end interfaces, JSON or XML data feeds, and communicate with your clients over AJAX, Comet, REST, or Websockets. Using a sensible front-end library, you can also ensure a graceful experience for all your users on every platform. And never have to write a single line of any other language.

                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Extend upon the material covered earlier for building simple web apps; cover the feature and security requirements of web applications, REST endpoints, websockets, etc.

                                                                                                                                                                                +

                                                                                                                                                                                Review web frameworks in Lisp: Weblocks, RESTAS, Clack/Caveman, Anti-Web, REDSHIFTNET; refresher on underlying servers, Hunchentoot, Wookie, IOLib, teepeedee2, etc., database libraries, crane, postmodern, etc., and other web-related libraries, cl-who, cl-css, parenscript, etc.

                                                                                                                                                                                +

                                                                                                                                                                                Web app should be a live-updating feed, pulling from some standard data source in JSON.

                                                                                                                                                                                +

                                                                                                                                                                                Focus on 100% Lisp to generate/parse web languages.

                                                                                                                                                                                +

                                                                                                                                                                                Also, include an exercise that shows how to set up a secure load-balanced cloud lisp web application.

                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.1

                                                                                                                                                                                +

                                                                                                                                                                                Full Featured Web Apps

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.2

                                                                                                                                                                                +

                                                                                                                                                                                Clack and Caveman

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.3

                                                                                                                                                                                +

                                                                                                                                                                                Wookie

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.4

                                                                                                                                                                                +

                                                                                                                                                                                CL-ASYNC

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.5

                                                                                                                                                                                +

                                                                                                                                                                                IOLib

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.6

                                                                                                                                                                                +

                                                                                                                                                                                IOLib

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.7

                                                                                                                                                                                +

                                                                                                                                                                                Websockets

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.8

                                                                                                                                                                                +

                                                                                                                                                                                Databases and ORMs for the Web

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.9

                                                                                                                                                                                +

                                                                                                                                                                                Serializing Data to JSON

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Project 3.1.10

                                                                                                                                                                                +

                                                                                                                                                                                An All-in-One Asynchronous Web Framework

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                +

                                                                                                                                                                                Exercise 3.1.11

                                                                                                                                                                                +

                                                                                                                                                                                Deploying a Secure, Distributed Lisp Web Application in the Cloud

                                                                                                                                                                                +
                                                                                                                                                                                
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                + + +
                                                                                                                                                                                + +
                                                                                                                                                                                +
                                                                                                                                                                                +
                                                                                                                                                                                + +

                                                                                                                                                                                results matching ""

                                                                                                                                                                                +
                                                                                                                                                                                  + +
                                                                                                                                                                                  +
                                                                                                                                                                                  + +

                                                                                                                                                                                  No results matching ""

                                                                                                                                                                                  + +
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  + +
                                                                                                                                                                                  +
                                                                                                                                                                                  + +
                                                                                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                                                                                  + + +
                                                                                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-02-00-typesetting.html b/clones/llthw.common-lisp.dev/3-02-00-typesetting.html new file mode 100644 index 00000000..13cd57de --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-02-00-typesetting.html @@ -0,0 +1,1929 @@ + + + + + + + Typesetting ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                  +
                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                  + +
                                                                                                                                                                                  + +
                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                  +
                                                                                                                                                                                  + +
                                                                                                                                                                                  +
                                                                                                                                                                                  + +
                                                                                                                                                                                  + +

                                                                                                                                                                                  Chapter 3.2

                                                                                                                                                                                  +

                                                                                                                                                                                  Typesetting

                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  "You don't pay back, you pay forward."

                                                                                                                                                                                  +
                                                                                                                                                                                  Robert A. Heinlein, as quoted by Jerry Pournelle in Starswarm
                                                                                                                                                                                  + +
                                                                                                                                                                                  +

                                                                                                                                                                                  The Web and Plain Text aren't the only document formats you can target with Common Lisp. You can generate code for any other programming language, including the TeX Typesetting System, it's variants and extensions LaTeX, ConTeXt, and XeTeX, such as with the CL-Docutils library; or you can typeset your documents as PDF natively from within Lisp using the CL-Typesetting and CL-PDF libraries.

                                                                                                                                                                                  +

                                                                                                                                                                                  In this chapter we will explore single-source documents with multiple output formats; structured text formats; native CL-Typesetting syntax; book design; fonts & typography; in-line graphics; typesetting math; self-publishing your documents and books; and collect everything together in a library that will let you focus entirely on your writing while simultaneously publishing professional documents to every platform and medium.

                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.1

                                                                                                                                                                                  +

                                                                                                                                                                                  CL-Typesetting Syntax

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.2

                                                                                                                                                                                  +

                                                                                                                                                                                  Markdown vs. reStructuredText

                                                                                                                                                                                  +

                                                                                                                                                                                  (and thus, CL-Typesetting vs. CL-Docutils)

                                                                                                                                                                                  +

                                                                                                                                                                                  Note: we will prefer CL-Typesetting integrated with 3bmd for a Lispier solution; but CL-Docutils is useful for outputting LaTeX.

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.3

                                                                                                                                                                                  +

                                                                                                                                                                                  Integrating 3bmd with CL-Typesetting

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.4

                                                                                                                                                                                  +

                                                                                                                                                                                  Target Templates

                                                                                                                                                                                  +

                                                                                                                                                                                  Highlight unique considerations for:

                                                                                                                                                                                  +
                                                                                                                                                                                    +
                                                                                                                                                                                  • LaTeX
                                                                                                                                                                                  • +
                                                                                                                                                                                  • PDF/Print
                                                                                                                                                                                  • +
                                                                                                                                                                                  • Ebook
                                                                                                                                                                                  • +
                                                                                                                                                                                  • Web
                                                                                                                                                                                  • +
                                                                                                                                                                                  • Screen Readers
                                                                                                                                                                                  • +
                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.5

                                                                                                                                                                                  +

                                                                                                                                                                                  Book Design

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.6

                                                                                                                                                                                  +

                                                                                                                                                                                  Fonts & Typography

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.7

                                                                                                                                                                                  +

                                                                                                                                                                                  Document Structure

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.8

                                                                                                                                                                                  +

                                                                                                                                                                                  White-space and Black-space

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.9

                                                                                                                                                                                  +

                                                                                                                                                                                  Headers, Footers, and Margins

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.10

                                                                                                                                                                                  +

                                                                                                                                                                                  Footnotes, Citations, Bibliographies

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.11

                                                                                                                                                                                  +

                                                                                                                                                                                  Contents and Indices

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.12

                                                                                                                                                                                  +

                                                                                                                                                                                  In-Line Graphics and Plots

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.13

                                                                                                                                                                                  +

                                                                                                                                                                                  Typesetting Mathematical Notation

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Exercise 3.2.14

                                                                                                                                                                                  +

                                                                                                                                                                                  Self-Publishing Services

                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  +

                                                                                                                                                                                  Project 3.2.15

                                                                                                                                                                                  +

                                                                                                                                                                                  CL-BookKit: A Single-Source Publishing Library for Typesetting in Common Lisp

                                                                                                                                                                                  +

                                                                                                                                                                                  Output to:

                                                                                                                                                                                  +
                                                                                                                                                                                    +
                                                                                                                                                                                  • PDF/Print
                                                                                                                                                                                  • +
                                                                                                                                                                                  • Ebook
                                                                                                                                                                                  • +
                                                                                                                                                                                  • Web
                                                                                                                                                                                  • +
                                                                                                                                                                                  • Plain-Text
                                                                                                                                                                                  • +
                                                                                                                                                                                  +
                                                                                                                                                                                  
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  + + +
                                                                                                                                                                                  + +
                                                                                                                                                                                  +
                                                                                                                                                                                  +
                                                                                                                                                                                  + +

                                                                                                                                                                                  results matching ""

                                                                                                                                                                                  +
                                                                                                                                                                                    + +
                                                                                                                                                                                    +
                                                                                                                                                                                    + +

                                                                                                                                                                                    No results matching ""

                                                                                                                                                                                    + +
                                                                                                                                                                                    +
                                                                                                                                                                                    +
                                                                                                                                                                                    + +
                                                                                                                                                                                    +
                                                                                                                                                                                    + +
                                                                                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                                                                                    + + +
                                                                                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-03-00-mobile.html b/clones/llthw.common-lisp.dev/3-03-00-mobile.html new file mode 100644 index 00000000..d58b81b1 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-03-00-mobile.html @@ -0,0 +1,1860 @@ + + + + + + + Native Mobile Applications ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                    +
                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                    + +
                                                                                                                                                                                    + +
                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                    +
                                                                                                                                                                                    + +
                                                                                                                                                                                    +
                                                                                                                                                                                    + +
                                                                                                                                                                                    + +

                                                                                                                                                                                    Chapter 3.3

                                                                                                                                                                                    +

                                                                                                                                                                                    Native Mobile Applications

                                                                                                                                                                                    +
                                                                                                                                                                                    +

                                                                                                                                                                                    "Progress doesn't come from early risers---progress is made by lazy men looking for easier ways to do things."

                                                                                                                                                                                    +
                                                                                                                                                                                    Robert A. Heinlein, Time Enough For Love
                                                                                                                                                                                    + +
                                                                                                                                                                                    +

                                                                                                                                                                                    Mobile devices are ubiquitous---there are nearly 7 Billion mobile devices in use around the world according to the ITU, which is almost as many people as there are on the planet; thus, the importance of developing native applications to target mobile devices cannot be overstated.

                                                                                                                                                                                    +

                                                                                                                                                                                    But each mobile platform is bogged down by its own proprietary environment, toolchain, and methodology. Maintaining separate codebases is expensive and time-consuming, and not feasible for many organizations---leaving many to develop cumbersome, neutered mobile web applications instead. If only there was some way to target all platforms natively, with one code-base. Oh wait, this is a book on Lisp, so of course there is!

                                                                                                                                                                                    +

                                                                                                                                                                                    The most popular library for native mobile development in Common Lisp is MOCL---it currently supports Android, iOS, and OS X native apps, and support for the Apple Watch is also expected soon. LispWorks has also begun to offer support for Android, and has a demo app available on Google Play. But there are also open-source alternatives: SBCL runs natively on Android and ARM processors, Clozure CL can target iOS, ECL compiles to C code which can run on either iOS or on Android with the NDK, and there is the new implementation of Common Lisp, Clasp, which targets LLVM to interoperate with C++. In other words, you have choices.

                                                                                                                                                                                    +

                                                                                                                                                                                    That being said, mobile development is primarily a commercial endeavour, so in this chapter we will emphasize the commercial solutions to native mobile Common Lisp development, with MOCL and LispWorks.

                                                                                                                                                                                    +

                                                                                                                                                                                    TO-DO: Profile CLASP, ECL, SBCL, and CCL native app development.

                                                                                                                                                                                    +

                                                                                                                                                                                    Exercise 3.3.1

                                                                                                                                                                                    +

                                                                                                                                                                                    Getting Started with MOCL

                                                                                                                                                                                    +
                                                                                                                                                                                    
                                                                                                                                                                                    +
                                                                                                                                                                                    +
                                                                                                                                                                                    +

                                                                                                                                                                                    Exercise 3.3.2

                                                                                                                                                                                    +

                                                                                                                                                                                    iOS Development with MOCL

                                                                                                                                                                                    +
                                                                                                                                                                                    
                                                                                                                                                                                    +
                                                                                                                                                                                    +
                                                                                                                                                                                    +

                                                                                                                                                                                    Exercise 3.3.3

                                                                                                                                                                                    +

                                                                                                                                                                                    Android Development with MOCL

                                                                                                                                                                                    +
                                                                                                                                                                                    
                                                                                                                                                                                    +
                                                                                                                                                                                    +
                                                                                                                                                                                    +

                                                                                                                                                                                    Project 3.3.4

                                                                                                                                                                                    +

                                                                                                                                                                                    Cross-Platform Mobile App, for iOS and Android

                                                                                                                                                                                    +
                                                                                                                                                                                    
                                                                                                                                                                                    +
                                                                                                                                                                                    +
                                                                                                                                                                                    + + +
                                                                                                                                                                                    + +
                                                                                                                                                                                    +
                                                                                                                                                                                    +
                                                                                                                                                                                    + +

                                                                                                                                                                                    results matching ""

                                                                                                                                                                                    +
                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      + +

                                                                                                                                                                                      No results matching ""

                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      + +
                                                                                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                                                                                      + + +
                                                                                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-04-00-gui.html b/clones/llthw.common-lisp.dev/3-04-00-gui.html new file mode 100644 index 00000000..b1f45746 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-04-00-gui.html @@ -0,0 +1,1880 @@ + + + + + + + Cross-platform Desktop Applications ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                      +
                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                      + +
                                                                                                                                                                                      + +
                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                      +
                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      + +
                                                                                                                                                                                      + +

                                                                                                                                                                                      Chapter 3.4

                                                                                                                                                                                      +

                                                                                                                                                                                      Cross-Platform Desktop Applications

                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      "A skillful Artist in shapes and appearances does no more than necessary to create His effect."

                                                                                                                                                                                      +
                                                                                                                                                                                      Robert A. Heinlein, Job: A Comedy of Justice
                                                                                                                                                                                      + +
                                                                                                                                                                                      +

                                                                                                                                                                                      Assuming your target user-base is not comprised entirely of Lisp Hackers, your users will normally not be interested in receiving a source-code distribution or a command-line utility; they will expect a nice, clean installation package, an attractive and iconographically-appropriate icon, and a graphical user interface that is both familiar and novel. This means a few different things---first, that your application's UI looks like other applications; it works like other applications; it fits into the Operating System like all other applications; but it tells its own story to users, like the best applications. GUI design is not just a matter of calling widgets to simplify a command-line interface with toggle buttons and text areas, after all---you have to consider the User Experience.

                                                                                                                                                                                      +

                                                                                                                                                                                      Typically, on large commercial software projects, there will be a UX developer either on staff or contract; so you don't have to know the ins-and-outs of UX as a software developer---but it is useful to know the language of UX, and why UX is so important. Then, you will be able to make the most of the GUI tools available in Common Lisp.

                                                                                                                                                                                      +

                                                                                                                                                                                      In Common Lisp, there are a lot of choices to provide desktop graphical user interfaces; but GUI applications are still a lot of work, and need to be carefully designed to support cross-platform deployment. Unfortunately, there is no one-size-fits-all solution to this problem, but there are options which make the task manageable.

                                                                                                                                                                                      +

                                                                                                                                                                                      For commercial, cross-platform desktop applications, the cleanest, simplest solution is the CAPI library included in all versions of LispWorks. For 90% of your GUI-application projects, you will need the features and workflow that LispWorks provides; for the rest, an open-source alternative might be preferable, even though they all fall short of the CAPI feature-set. In order to distribute binaries of your desktop app, you will need the professional version of LispWorks or above for each platform you wish to target---but you can write and test your applications with the free personal edition.

                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Discuss Smoke/QT bindings, LTK, McCLIM, SDL + Dormouse, LispWorks CAPI, etc.

                                                                                                                                                                                      +

                                                                                                                                                                                      LTK for developing rapid cross-platform guis.

                                                                                                                                                                                      +

                                                                                                                                                                                      Develop a cross-platform LTK app for OS X, Windows, and Linux, package it for each OS appropriately.

                                                                                                                                                                                      +

                                                                                                                                                                                      Note: consider a wrapper around Atom-Shell, for writing rapid web technology based cross-platform applications.

                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Exercise 3.4.1

                                                                                                                                                                                      +

                                                                                                                                                                                      QTools and CommonQT

                                                                                                                                                                                      +
                                                                                                                                                                                      
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Exercise 3.4.2

                                                                                                                                                                                      +

                                                                                                                                                                                      McCLIM

                                                                                                                                                                                      +
                                                                                                                                                                                      
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Exercise 3.4.3

                                                                                                                                                                                      +

                                                                                                                                                                                      SDL and Dormouse

                                                                                                                                                                                      +
                                                                                                                                                                                      
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Exercise 3.4.4

                                                                                                                                                                                      +

                                                                                                                                                                                      LTK

                                                                                                                                                                                      +
                                                                                                                                                                                      
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Exercise 3.4.5

                                                                                                                                                                                      +

                                                                                                                                                                                      LispWorks: CAPI

                                                                                                                                                                                      +
                                                                                                                                                                                      
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Exercise 3.4.6

                                                                                                                                                                                      +

                                                                                                                                                                                      Atom-Shell: GUI Apps built on Web Technologies

                                                                                                                                                                                      +
                                                                                                                                                                                      
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      +

                                                                                                                                                                                      Project 3.4.7

                                                                                                                                                                                      +

                                                                                                                                                                                      A Cross-Platform Native GUI App

                                                                                                                                                                                      +
                                                                                                                                                                                      
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      + + +
                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      + +

                                                                                                                                                                                      results matching ""

                                                                                                                                                                                      +
                                                                                                                                                                                        + +
                                                                                                                                                                                        +
                                                                                                                                                                                        + +

                                                                                                                                                                                        No results matching ""

                                                                                                                                                                                        + +
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        + +
                                                                                                                                                                                        +
                                                                                                                                                                                        + +
                                                                                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                                                                                        + + +
                                                                                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-05-00-system-utils.html b/clones/llthw.common-lisp.dev/3-05-00-system-utils.html new file mode 100644 index 00000000..67059650 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-05-00-system-utils.html @@ -0,0 +1,1878 @@ + + + + + + + Drivers, Daemons, and System-Utilities ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                        +
                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                        + +
                                                                                                                                                                                        + +
                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                        +
                                                                                                                                                                                        + +
                                                                                                                                                                                        +
                                                                                                                                                                                        + +
                                                                                                                                                                                        + +

                                                                                                                                                                                        Chapter 3.5

                                                                                                                                                                                        +

                                                                                                                                                                                        Drivers, Daemons, and System-Utilities

                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        "Anyone who considers protocol unimportant has never dealt with a cat."

                                                                                                                                                                                        +
                                                                                                                                                                                        Robert A. Heinlein, The Cat Who Walks Through Walls
                                                                                                                                                                                        + +
                                                                                                                                                                                        +

                                                                                                                                                                                        Not every application you write actually needs a GUI. There's a wide class of drivers, daemons, and system-utilities which make more sense to distribute as command-line utilities. Generally, when designing an application, you ask yourself who or what the user is; if the intended user is a sysadmin, or another application, a daemon is a really useful type of system-utility that runs in the background and provides low-level interfaces to system-critical functionality. Conversely, if your application only needs to do one thing at a time and exit, then a simple command-line utility will do. Drivers are a bit different, as the intention behind them is to provide an API to hardware that the computer otherwise does not know how to use; they often don't need to run as their own process, and can be embedded in the applications that need them, or linked to through Lisp's FFI.

                                                                                                                                                                                        +

                                                                                                                                                                                        Drivers, much like any other library, are aptly suited for distribution through Quicklisp, whereas your full applications (daemons, command-line utilities, gui, mobile, and web apps) are best distributed through traditional means. Naturally, to write a driver you need to be intimately familiar with the low-level protocol for the hardware device---this means working directly with binary streams, byte-vectors, and sockets, to recreate the protocol specification for the device in question, and provide your users with a high-level API to the device that can be used in their Lisp applications.

                                                                                                                                                                                        +

                                                                                                                                                                                        There are a number of libraries already available in Quicklisp to make the writing of drivers, daemons, and system-utilities much simpler; many of which have already been touched upon in previous chapters. In the following exercises we will be taking a deeper look at CLON (the Command-Line Options Nuker), SB-DAEMON, Nibbles; how to implement low-level protocols using sockets and streams; and the design of useful command-line interfaces and APIs.

                                                                                                                                                                                        +

                                                                                                                                                                                        Exercise 3.5.1

                                                                                                                                                                                        +

                                                                                                                                                                                        Nibbles

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        Exercise 3.5.2

                                                                                                                                                                                        +

                                                                                                                                                                                        SB-DAEMON

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        Exercise 3.5.3

                                                                                                                                                                                        +

                                                                                                                                                                                        CLON, Revisited

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        Exercise 3.5.4

                                                                                                                                                                                        +

                                                                                                                                                                                        Useful Command-Line Interfaces

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        Exercise 3.5.5

                                                                                                                                                                                        +

                                                                                                                                                                                        Low-Level Protocols

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        Project 3.5.6

                                                                                                                                                                                        +

                                                                                                                                                                                        A Hardware Driver

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        Project 3.5.7

                                                                                                                                                                                        +

                                                                                                                                                                                        A Daemonized Service

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        +

                                                                                                                                                                                        Project 3.5.8

                                                                                                                                                                                        +

                                                                                                                                                                                        A Suite of Command-Line Utilities

                                                                                                                                                                                        +
                                                                                                                                                                                        
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        + + +
                                                                                                                                                                                        + +
                                                                                                                                                                                        +
                                                                                                                                                                                        +
                                                                                                                                                                                        + +

                                                                                                                                                                                        results matching ""

                                                                                                                                                                                        +
                                                                                                                                                                                          + +
                                                                                                                                                                                          +
                                                                                                                                                                                          + +

                                                                                                                                                                                          No results matching ""

                                                                                                                                                                                          + +
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          + +
                                                                                                                                                                                          +
                                                                                                                                                                                          + +
                                                                                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                                                                                          + + +
                                                                                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-06-00-reverse-engineering.html b/clones/llthw.common-lisp.dev/3-06-00-reverse-engineering.html new file mode 100644 index 00000000..1be1a0f9 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-06-00-reverse-engineering.html @@ -0,0 +1,1893 @@ + + + + + + + Reverse Engineering ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                          +
                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                          + +
                                                                                                                                                                                          + +
                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                          +
                                                                                                                                                                                          + +
                                                                                                                                                                                          +
                                                                                                                                                                                          + +
                                                                                                                                                                                          + +

                                                                                                                                                                                          Chapter 3.6

                                                                                                                                                                                          +

                                                                                                                                                                                          Reverse Engineering

                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          "Aside from a cold appreciation of my own genius I felt that I was a modest man."

                                                                                                                                                                                          +
                                                                                                                                                                                          Robert A. Heinlein, Double Star
                                                                                                                                                                                          + +
                                                                                                                                                                                          +

                                                                                                                                                                                          Disclaimer: Reverse engineering commercially licensed software may subject you to criminal prosecution. The material in this chapter is presented for informational purposes only, to aid in the authorized porting of software to the Common Lisp language, and the recovery of lost source code by the owners of the software; its use for criminal activities, including but not limited to, intellectual property theft, and circumvention of software authorization and digital-rights management protocols, in violation of the license agreements of commercial software and other digital assets is strictly prohibited.

                                                                                                                                                                                          +

                                                                                                                                                                                          Reverse Engineering is an art, more than a science---that being said, it is also a highly skilled area that requires a deep understanding of all aspects of computer science. While this chapter will cover the essential techniques to reverse engineer software using the Common Lisp language, it does not attempt to teach the methodology or theory behind reverse engineering. For a complete, general introduction to the subject, please see the Resources section for texts related to this area.

                                                                                                                                                                                          +

                                                                                                                                                                                          In this chapter we will explore the structure of binary applications as output by various compilers, the features available across the most popular reverse engineering tools, and what Lisp offers that other tools don't. We will then tackle the specific reverse engineering tasks to progressively migrate a closed-source application to Lisp by parsing objdump files, generating header files (for software compiled from C/C++), parsing common patterns in Assembly Language to create low-level Lisp code, and then wrapping up everything together to generate high-level Lisp code that can be used to maintain and compile a new version of the reverse engineered software.

                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.1

                                                                                                                                                                                          +

                                                                                                                                                                                          OBJDUMP: Dumping Binaries as Assembly

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.2

                                                                                                                                                                                          +

                                                                                                                                                                                          Operating System Kernels

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.3

                                                                                                                                                                                          +

                                                                                                                                                                                          x86 Assembly

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.4

                                                                                                                                                                                          +

                                                                                                                                                                                          x86-64 Assembly

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.5

                                                                                                                                                                                          +

                                                                                                                                                                                          Stripped Binaries

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.6

                                                                                                                                                                                          +

                                                                                                                                                                                          (Re)Generating Header Files

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.7

                                                                                                                                                                                          +

                                                                                                                                                                                          Obfuscation and Deobfuscation

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.8

                                                                                                                                                                                          +

                                                                                                                                                                                          Finding Compiler Patterns

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.9

                                                                                                                                                                                          +

                                                                                                                                                                                          Transforming Assembly to Low-Level Lisp

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Exercise 3.6.10

                                                                                                                                                                                          +

                                                                                                                                                                                          High-Level Transformations

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          +

                                                                                                                                                                                          Project 3.6.11

                                                                                                                                                                                          +

                                                                                                                                                                                          A Reverse Engineering Toolkit

                                                                                                                                                                                          +
                                                                                                                                                                                          
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          + + +
                                                                                                                                                                                          + +
                                                                                                                                                                                          +
                                                                                                                                                                                          +
                                                                                                                                                                                          + +

                                                                                                                                                                                          results matching ""

                                                                                                                                                                                          +
                                                                                                                                                                                            + +
                                                                                                                                                                                            +
                                                                                                                                                                                            + +

                                                                                                                                                                                            No results matching ""

                                                                                                                                                                                            + +
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            + +
                                                                                                                                                                                            +
                                                                                                                                                                                            + +
                                                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                                                            + + +
                                                                                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-07-00-graphics.html b/clones/llthw.common-lisp.dev/3-07-00-graphics.html new file mode 100644 index 00000000..d90f3c13 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-07-00-graphics.html @@ -0,0 +1,1893 @@ + + + + + + + Graphics Rendering ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                            +
                                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                                            + +
                                                                                                                                                                                            + +
                                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                                            +
                                                                                                                                                                                            + +
                                                                                                                                                                                            +
                                                                                                                                                                                            + +
                                                                                                                                                                                            + +

                                                                                                                                                                                            Chapter 3.7

                                                                                                                                                                                            +

                                                                                                                                                                                            Graphics Rendering

                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            "If you happen to be one of the fretful minority who can do creative work, never force an idea... Be patient and you'll give birth to it when the time is ripe. Learn to wait."

                                                                                                                                                                                            +
                                                                                                                                                                                            Robert A. Heinlein, Time Enough for Love
                                                                                                                                                                                            + +
                                                                                                                                                                                            +

                                                                                                                                                                                            Graphics rendering and generation is a fairly popular topic in Lisp, and as such there are a number of libraries already available to assist the developer, from vector art to procedurally generated 3D worlds. Naturally, there are also libraries available for manipulating bitmap image formats, and converting between vector and bitmap images, so that you can process your images in a number of ways, such as with photo filters.

                                                                                                                                                                                            +

                                                                                                                                                                                            A natural extension to this topic is the visualization of data---you could simply plot your data on a graph, but sometimes you want something more dynamic and engaging. Lisp is a very useful ally in this task.

                                                                                                                                                                                            +

                                                                                                                                                                                            In this chapter we will explore various methods for generating both vector and bitmap image files; plotting complex data; and creating a simple paint application with a GUI.

                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.1

                                                                                                                                                                                            +

                                                                                                                                                                                            Vector Graphics with VECTO

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.2

                                                                                                                                                                                            +

                                                                                                                                                                                            More VECTO

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.3

                                                                                                                                                                                            +

                                                                                                                                                                                            Even More VECTO

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.4

                                                                                                                                                                                            +

                                                                                                                                                                                            Raster Graphics with CL-PNG

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.5

                                                                                                                                                                                            +

                                                                                                                                                                                            More CL-PNG

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.6

                                                                                                                                                                                            +

                                                                                                                                                                                            Even More CL-PNG

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.7

                                                                                                                                                                                            +

                                                                                                                                                                                            Plotting Data with VECTO

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.8

                                                                                                                                                                                            +

                                                                                                                                                                                            Plotting Data with CL-PLplot

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Exercise 3.7.9

                                                                                                                                                                                            +

                                                                                                                                                                                            Plotting Data for the Web

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Project 3.7.10

                                                                                                                                                                                            +

                                                                                                                                                                                            A Web-Based Data Plotting Service

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            +

                                                                                                                                                                                            Project 3.7.11

                                                                                                                                                                                            +

                                                                                                                                                                                            A Simple Paint Application with VECTO and Qtools

                                                                                                                                                                                            +
                                                                                                                                                                                            
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            + + +
                                                                                                                                                                                            + +
                                                                                                                                                                                            +
                                                                                                                                                                                            +
                                                                                                                                                                                            + +

                                                                                                                                                                                            results matching ""

                                                                                                                                                                                            +
                                                                                                                                                                                              + +
                                                                                                                                                                                              +
                                                                                                                                                                                              + +

                                                                                                                                                                                              No results matching ""

                                                                                                                                                                                              + +
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              + +
                                                                                                                                                                                              +
                                                                                                                                                                                              + +
                                                                                                                                                                                              + + + + + + + + + + + + + + +
                                                                                                                                                                                              + + +
                                                                                                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-08-00-gaming.html b/clones/llthw.common-lisp.dev/3-08-00-gaming.html new file mode 100644 index 00000000..ede677e4 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-08-00-gaming.html @@ -0,0 +1,1885 @@ + + + + + + + OpenGL, SDL, and 3D Game Development ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                              +
                                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                                              + +
                                                                                                                                                                                              + +
                                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                                              +
                                                                                                                                                                                              + +
                                                                                                                                                                                              +
                                                                                                                                                                                              + +
                                                                                                                                                                                              + +

                                                                                                                                                                                              Chapter 3.8

                                                                                                                                                                                              +

                                                                                                                                                                                              OpenGL, SDL, and 3D Game Development

                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              "For modern man one of the most troubling aspects of eternity lies in getting used to the slippery quality of time."

                                                                                                                                                                                              +
                                                                                                                                                                                              Robert A. Heinlein, Job: A Comedy of Justice
                                                                                                                                                                                              + +
                                                                                                                                                                                              +

                                                                                                                                                                                              Revision Note: Chapter 2.18 already includes an FFI library for the Oculus Rift, so this chapter can focus on integration into a Lisp game engine.

                                                                                                                                                                                              +

                                                                                                                                                                                              Game development is a highly competitive industry; there are a lot of development platforms and technology-stacks available for the would-be game developer, and all of them have their own particular strengths and advantages. If you want an out of the box solution, and are working with 3D artists to create your assets, you will get everything you need with popular frameworks such as the Unreal Engine, or Unity3D; but creating a commercial platformer is not the only reason developers get into game development. Sometimes, you just want to create something for yourself and your friends---and you want the satisfaction of knowing you did it your own way.

                                                                                                                                                                                              +

                                                                                                                                                                                              Game development in Lisp has many options, and offers the unique strength that you can program everything---even the graphics and audio. You don't need to work with a team of asset creators and audio engineers, you can do everything yourself with pure Lisp code. Naturally, game development on any platform is still a lot of work---but building a 3D platformer in 100% Lisp source code requires no more effort than a game built in Unity3D, and as a programmer, you may find the pure source code approach more intuitive. That being said, Lisp doesn't stop you from working with a 3D artist to create your assets; you can adopt the approach that works best for you.

                                                                                                                                                                                              +

                                                                                                                                                                                              To create the immersive worlds of today's platformer games, you will have to start thinking in terms of spatial geometry and perspective. The goal is not to programmatically recreate the material world from the atomic level up---the goal is to create the effect of the material world with adequate simulations, using physics and animation to create your scenes. Game development is very math-heavy, but if you paid close attention in the preceding material from Part Two of this book, you'll have all the tools you need.

                                                                                                                                                                                              +

                                                                                                                                                                                              In this chapter, we will be modelling a basic 3+1n Spacetime, to get you thinking in terms of the environments you will be building for your games, and transforming objects within them over time; reviewing the available libraries in Quicklisp for 3D game development; and creating a couple simple games---first, programmatically with procedurally generated environments and assets, and second, using assets created with the open-source 3D artwork platform, Blender. As an extra credit exercise, we will also be writing a bridge to the Oculus Rift VR headset, so that you can create fully immersive virtual reality games.

                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.1

                                                                                                                                                                                              +

                                                                                                                                                                                              Blackthorn 3D: OpenGL, SDL and Lisp

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.2

                                                                                                                                                                                              +

                                                                                                                                                                                              More Blackthorn 3D

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.3

                                                                                                                                                                                              +

                                                                                                                                                                                              Even More Blackthorn 3D

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.4

                                                                                                                                                                                              +

                                                                                                                                                                                              Physics Modelling in Lisp

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.5

                                                                                                                                                                                              +

                                                                                                                                                                                              Importing 3D Assets

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.6

                                                                                                                                                                                              +

                                                                                                                                                                                              Procedurally Generated 3D Environments

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.7

                                                                                                                                                                                              +

                                                                                                                                                                                              More Procedural Generation

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Exercise 3.8.8

                                                                                                                                                                                              +

                                                                                                                                                                                              Integrating Oculus Rift

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              +

                                                                                                                                                                                              Project 3.8.9

                                                                                                                                                                                              +

                                                                                                                                                                                              Build a 3D Platform Game

                                                                                                                                                                                              +
                                                                                                                                                                                              
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              + + +
                                                                                                                                                                                              + +
                                                                                                                                                                                              +
                                                                                                                                                                                              +
                                                                                                                                                                                              + +

                                                                                                                                                                                              results matching ""

                                                                                                                                                                                              +
                                                                                                                                                                                                + +
                                                                                                                                                                                                +
                                                                                                                                                                                                + +

                                                                                                                                                                                                No results matching ""

                                                                                                                                                                                                + +
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                + +
                                                                                                                                                                                                +
                                                                                                                                                                                                + +
                                                                                                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                                                                                                + + +
                                                                                                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-09-00-audio.html b/clones/llthw.common-lisp.dev/3-09-00-audio.html new file mode 100644 index 00000000..4f5064f1 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-09-00-audio.html @@ -0,0 +1,1889 @@ + + + + + + + Audio Generation and Manipulation ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                +
                                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                                + +
                                                                                                                                                                                                + +
                                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                                +
                                                                                                                                                                                                + +
                                                                                                                                                                                                +
                                                                                                                                                                                                + +
                                                                                                                                                                                                + +

                                                                                                                                                                                                Chapter 3.9

                                                                                                                                                                                                +

                                                                                                                                                                                                Audio Generation and Manipulation

                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                "You're not listening."
                                                                                                                                                                                                +"What were you doing talking," she answered reasonably, "when I wasn't listening?"

                                                                                                                                                                                                +
                                                                                                                                                                                                Robert A. Heinlein, Have Space Suit---Will Travel
                                                                                                                                                                                                + +
                                                                                                                                                                                                +

                                                                                                                                                                                                There is something strangely satisfying about creating music---and it doesn't much matter whether anyone else wants to hear it, because the real point of it is to express yourself, without filters, without judgement, without fear. Now, there are a lot of ways to make music---you can pick up an instrument, bang your fingers on your desk the the rhythm of your heart, or hum a private tune to yourself; it doesn't much matter, because at the end of the day it's all about how you best express yourself. Obviously, if you've made it this far in the book, you're now a programmer; so what better way to express yourself than through the language that you have poured your blood, sweat, and tears into learning?

                                                                                                                                                                                                +

                                                                                                                                                                                                There are a lot of solutions available in the Lisp world for working with audio; you can handle MIDI to control your hardware or software synthesizers, modify WAV files, even live-hack in Common Lisp to create music on the fly with custom instruments and audio samples. There are no limits---it's just you and your computer, making noise with code; and as it turns out, it is one powerful medium.

                                                                                                                                                                                                +

                                                                                                                                                                                                In this chapter, we will explore the variety of audio generation and manipulation libraries available for Lisp, with a particular emphasis on CL-Collider for algorithmic audio generation and live hacking. If you have not set up Emacs Live yet, now will be a good time to do so, as it was specifically designed with live hacking in mind. We will also revisit our 3D platformer game from the previous chapter, to embed a soundtrack and custom sound-effects, all generated with Lisp source code.

                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.1

                                                                                                                                                                                                +

                                                                                                                                                                                                CL-Collider and SuperCollider

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.2

                                                                                                                                                                                                +

                                                                                                                                                                                                Notes and Chords

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.3

                                                                                                                                                                                                +

                                                                                                                                                                                                Instruments

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.4

                                                                                                                                                                                                +

                                                                                                                                                                                                Filters

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.5

                                                                                                                                                                                                +

                                                                                                                                                                                                Controlling MIDI Devices

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.6

                                                                                                                                                                                                +

                                                                                                                                                                                                MIDI Input

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.7

                                                                                                                                                                                                +

                                                                                                                                                                                                Bouncing Audio to Disk

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.8

                                                                                                                                                                                                +

                                                                                                                                                                                                Mixing and Mastering Audio

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Exercise 3.9.9

                                                                                                                                                                                                +

                                                                                                                                                                                                Live Hacking CL-Collider in Emacs Live

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                +

                                                                                                                                                                                                Project 3.9.10

                                                                                                                                                                                                +

                                                                                                                                                                                                Extending your 3D Game Engine with programmatic audio

                                                                                                                                                                                                +
                                                                                                                                                                                                
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                + + +
                                                                                                                                                                                                + +
                                                                                                                                                                                                +
                                                                                                                                                                                                +
                                                                                                                                                                                                + +

                                                                                                                                                                                                results matching ""

                                                                                                                                                                                                +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + +

                                                                                                                                                                                                  No results matching ""

                                                                                                                                                                                                  + +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                                                                                                  + + +
                                                                                                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-10-00-data.html b/clones/llthw.common-lisp.dev/3-10-00-data.html new file mode 100644 index 00000000..32f05eb5 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-10-00-data.html @@ -0,0 +1,1874 @@ + + + + + + + Data Aggregation and Analysis ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  + +

                                                                                                                                                                                                  Chapter 3.10

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Data Aggregation and Analysis

                                                                                                                                                                                                  +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  "Mass psychology is not simply a summation of individual psychologies; that is a prime theorem of social psychodynamics---not just my opinion; no exception has ever been found to this theorem."

                                                                                                                                                                                                  +
                                                                                                                                                                                                  Robert A. Heinlein, Methuselah's Children
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  These days, you hear the buzz-word "Big Data" being thrown around everywhere, as if it's something new and exciting. It isn't, really; it is just the natural extension of data aggregation and analysis techniques that have existed for decades, applied to the surprising amount of personal information that is shared with the world on the internet through social media, blogging platforms, and community platforms. Now, what can be inferred from this amount of data is what the buzz is really all about---and where a lot of companies are making all their money.

                                                                                                                                                                                                  +

                                                                                                                                                                                                  At its core, Big Data is simple. It starts with simple techniques for parsing the data available on the internet, from HTML, XML, JSON, and so forth; using concepts from the semantic web, it allows developers to infer more meaning about this data than would otherwise be possible; and then it aggregates large volumes of this data so that global trends and individual preferences can be exploited for profit. And using techniques from artificial intelligence for designing knowledge-based systems, this simple set of techniques can be transformed into a multi-billion dollar enterprise.

                                                                                                                                                                                                  +

                                                                                                                                                                                                  These types of tasks are Lisp's core strength. Symbolic computation is aptly suited for representing knowledge-based systems and artificial intelligence problems, and can give new-comers to the business of Big Data a significant edge against their monolithic, corporate competitors.

                                                                                                                                                                                                  +

                                                                                                                                                                                                  In this chapter we will look at the challenges of scraping websites, xml and json feeds; parsing the data intelligently; storing and indexing large quantities of data; analyzing and graphing such data in meaningful ways; and writing AI agents that can automate this process for you. We will also look at considerations of privacy, and your responsibility in handling, using, and protecting personal information appropriately.

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Exercise 3.10.1

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Lisp-Based HTTP Clients

                                                                                                                                                                                                  +
                                                                                                                                                                                                  
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  Exercise 3.10.2

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Scraping the Web

                                                                                                                                                                                                  +
                                                                                                                                                                                                  
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  Exercise 3.10.3

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Parsing XML and HTML

                                                                                                                                                                                                  +
                                                                                                                                                                                                  
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  Exercise 3.10.4

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Parsing JSON

                                                                                                                                                                                                  +
                                                                                                                                                                                                  
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  Exercise 3.10.5

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Data Aggregation

                                                                                                                                                                                                  +
                                                                                                                                                                                                  
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  Exercise 3.10.6

                                                                                                                                                                                                  +

                                                                                                                                                                                                  Targeted Data Mining

                                                                                                                                                                                                  +
                                                                                                                                                                                                  
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +

                                                                                                                                                                                                  Project 3.10.7

                                                                                                                                                                                                  +

                                                                                                                                                                                                  An Extensible Knowledge Engine

                                                                                                                                                                                                  +
                                                                                                                                                                                                  
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + + +
                                                                                                                                                                                                  + +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  +
                                                                                                                                                                                                  + +

                                                                                                                                                                                                  results matching ""

                                                                                                                                                                                                  +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + +

                                                                                                                                                                                                    No results matching ""

                                                                                                                                                                                                    + +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                                                                                                    + + +
                                                                                                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-11-00-cryptosec.html b/clones/llthw.common-lisp.dev/3-11-00-cryptosec.html new file mode 100644 index 00000000..3e31cac1 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-11-00-cryptosec.html @@ -0,0 +1,1884 @@ + + + + + + + Cryptography and Security ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    + +

                                                                                                                                                                                                    Chapter 3.11

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Cryptography and Security

                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    "An armed society is a polite society."

                                                                                                                                                                                                    +
                                                                                                                                                                                                    Robert A. Heinlein, Beyond This Horizon
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Revision Note: Update chapter intro text to support more in-depth cryptography discussion.

                                                                                                                                                                                                    +

                                                                                                                                                                                                    The tools available in the ANSI Common Lisp standard for handling binary data and advanced mathematics, among other more-or-less hidden features of Common Lisp compilers, make it an ideal environment for implementing robust cryptographic utilities and secure software. Naturally, cryptography is a highly specialized subject, and requires deep exploration to grok fully. No general purpose programming language is a magic bullet that allows a layperson to write cryptographic software without extensive training; but if you are interested in cryptographic security as a specialization, this chapter will---hopefully---at least point you in the right direction.

                                                                                                                                                                                                    +

                                                                                                                                                                                                    In this chapter we will review again the mathematics of cryptography, alongside the theory that makes it work and the code we have already written; we will take a deeper exploration of random and pseudo-random number generation; write a one-time pad cipher using CL-ISAAC, suitable for gaming; explore the use-cases of all the tools available to a developer using the Ironclad library; and try our hand at extending Ironclad to support more advanced cryptographic protocols.

                                                                                                                                                                                                    +

                                                                                                                                                                                                    For a list of further readings on cryptography, please consult the Resources section of this site.

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.1

                                                                                                                                                                                                    +

                                                                                                                                                                                                    The Math of Modern Cryptography

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.2

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Post-Quantum Cryptography

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.3

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Cryptographically Strong (Pseudo)-Random Number Generators

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.4

                                                                                                                                                                                                    +

                                                                                                                                                                                                    A One-Time Pad using CL-ISAAC

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.5

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Ironclad: Authentication

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.6

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Ironclad: Hashing

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.7

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Ironclad: Encryption

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Exercise 3.11.8

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Secure Coding Principles

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +

                                                                                                                                                                                                    Project 3.11.9

                                                                                                                                                                                                    +

                                                                                                                                                                                                    Extending Ironclad: Elliptical Curve Cryptography

                                                                                                                                                                                                    +
                                                                                                                                                                                                    
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + + +
                                                                                                                                                                                                    + +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    +
                                                                                                                                                                                                    + +

                                                                                                                                                                                                    results matching ""

                                                                                                                                                                                                    +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + +

                                                                                                                                                                                                      No results matching ""

                                                                                                                                                                                                      + +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                                                                                                      + + +
                                                                                                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-12-00-fintech.html b/clones/llthw.common-lisp.dev/3-12-00-fintech.html new file mode 100644 index 00000000..68c9386d --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-12-00-fintech.html @@ -0,0 +1,1913 @@ + + + + + + + Financial Software and Crypto-Currencies ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      + +

                                                                                                                                                                                                      Chapter 3.12

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Financial Software and Crypto-Currencies

                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      "'Value' has no meaning other than in relationship to living beings... This very personal relationship, 'value', has two factors... first, what he can do with a thing, its use to him... and second, what he must do to get it, its cost to him."

                                                                                                                                                                                                      +
                                                                                                                                                                                                      Robert A. Heinlein, Starship Troopers
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Out of all the commercial ventures available to a budding entrepreneur, the most dangerous undertaking is handling other people's money. Not just for the obvious reasons, such as becoming a target for theft, exploitation, and blackmail---but the liability alone, the stifling regulatory systems, and compliance requirements make the financial industry a deeply uncomfortable place for newcomers. With this in mind, you can wonder at the audacity of the Bitcoin and crypto-currency community, that has spearheaded a new digital economy without taking such factors into consideration; and then realize why so many Bitcoin companies are failing. The biggest problem may be self-evident to certain people, but is not often discussed amongst members of commercial crypto-currency start-ups---Bitcoin was specifically designed to sabotage the financial industry through total decentralization, not to be used as a tool to build banks and other money service businesses for cheap. With that point in mind, this chapter will adopt the attitude of personal, decentralized banking, where you take the control and security of your money into your own hands---however, many of the necessary skills needed to design a personal Bitcoin wallet are transferable to the financial industry as a whole. And, as it so happens, Common Lisp is often used in financial industry software, so if this is your area of interest, you'll have no trouble fitting in.

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Naturally, security is of utmost concern; so if you have not already read it, worked through the exercises, and done the extra readings from the Resources section, you should go back and read Chapter 3.10 -- Cryptography and Security first. In any banking system, the only factor more important than compliance with your local financial regulatory body is the security of that system. Other factors that you will have to consider, even for a personal wallet, are accounting ledgers, transaction histories, and encrypting your wallet. Money service businesses also have to maintain strict Know-Your-Customer and Anti-Money-Laundering policies.

                                                                                                                                                                                                      +

                                                                                                                                                                                                      So in this chapter, we'll take an overview of the strongest encryption protocols available in Common Lisp, design a personal wallet that utilizes Bitcoin to store and transfer value, interface with the Bitcoin blockchain from Common Lisp, and review some of the more interesting Bitcoin Improvement Proposals (BIPs) to add valuable features to your personal wallet. We will also point you to some important resources for learning how to do a basic security profile of your application, to harden your wallet against potential loss through theft or other malicious activity.

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.1

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Working with Crypto-Currencies in Common Lisp

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.2

                                                                                                                                                                                                      +

                                                                                                                                                                                                      JSON-RPC Interfaces

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.3

                                                                                                                                                                                                      +

                                                                                                                                                                                                      ECDSA, SHA256, and Ripemd160

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.4

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Base-58 and Base-64 Representations

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.5

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Transactions

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.6

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Addresses

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.7

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Op-Codes

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.8

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Scripts

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.9

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Unspent-Outs

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.10

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Wallets

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.11

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Writing an Encrypted Wallet

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Two methods:

                                                                                                                                                                                                      +
                                                                                                                                                                                                        +
                                                                                                                                                                                                      • Encrypt database fields individually
                                                                                                                                                                                                      • +
                                                                                                                                                                                                      • Encrypt Wallet Instance Object
                                                                                                                                                                                                      • +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.12

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Providing a RESTful API to the Blockchain

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Exercise 3.12.13

                                                                                                                                                                                                      +

                                                                                                                                                                                                      Hierarchical--Deterministic Keychains

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +

                                                                                                                                                                                                      Project 3.12.14

                                                                                                                                                                                                      +

                                                                                                                                                                                                      A Personal Bitcoin Wallet Web-App

                                                                                                                                                                                                      +
                                                                                                                                                                                                      
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + + +
                                                                                                                                                                                                      + +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      +
                                                                                                                                                                                                      + +

                                                                                                                                                                                                      results matching ""

                                                                                                                                                                                                      +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + +

                                                                                                                                                                                                        No results matching ""

                                                                                                                                                                                                        + +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                                                                                                        + + +
                                                                                                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-13-00-scientific-computing.html b/clones/llthw.common-lisp.dev/3-13-00-scientific-computing.html new file mode 100644 index 00000000..17a8810c --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-13-00-scientific-computing.html @@ -0,0 +1,1878 @@ + + + + + + + Scientific Computing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        + +

                                                                                                                                                                                                        Chapter 3.13

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Scientific Computing

                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        "In this complex world, science, the scientific method, and the consequences of the scientific method are central to everything the human race is doing and to wherever we are going."

                                                                                                                                                                                                        +
                                                                                                                                                                                                        Robert A. Heinlein, The Pragmatics of Patriotism
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Scientific computing, also known as Computational Science, is now considered a third mode of science in addition to the traditional two modes of observation/experimentation and theory, and is thus an essential basic skill for researchers of every scientific field. Typically, computational scientists favour R, Mathematica, MATLAB, Python's SciPy and PDL libraries, C, or Fortran to implement highly optimized numerical simulations; but Common Lisp has significant advantages over all these technologies for implementing robust, optimized, distributed algorithms for modelling scientific problems, running simulations, and further optimizing scenarios.

                                                                                                                                                                                                        +

                                                                                                                                                                                                        At the most basic level, computational science requires featureful and fast algebra and plotting libraries; but advanced use-cases and computationally expensive simulations require massive concurrency, and resource intensive floating-point calculations. Using LParallel, CL-GPU, GSLL, CL-PLPlot, and the optimization techniques you've already learned, you can beat the performance of other platforms and technologies, and take advantage of all of Common Lisp's other intrinsic features, such as interactive programming at the REPL, for rapid prototyping of solutions to many of the most important problems in computational science.

                                                                                                                                                                                                        +

                                                                                                                                                                                                        In this chapter we will review the Lisp syntax of the math necessary to model problems in computational science, translate a selection of problems in computational science from pseudo-code to Common Lisp, work heavily from the REPL to model systems interactively in real-time, graph and plot our results, and run exhaustive tests and benchmarks against other platforms as part of the optimization process, to prove to yourself and others that Common Lisp is the ideal platform for Scientific Computing.

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Exercise 3.13.1

                                                                                                                                                                                                        +

                                                                                                                                                                                                        The Math of Scientific Computing

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Exercise 3.13.2

                                                                                                                                                                                                        +

                                                                                                                                                                                                        GSLL

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Exercise 3.13.3

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Leveraging Massive Concurrency

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Exercise 3.13.4

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Floating-Point Calculations using CL-GPU

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Exercise 3.13.5

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Plotting Your Results

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Exercise 3.13.6

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Performance Testing and Optimization

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Exercise 3.13.7

                                                                                                                                                                                                        +

                                                                                                                                                                                                        Proofing Results

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +

                                                                                                                                                                                                        Project 3.13.8

                                                                                                                                                                                                        +

                                                                                                                                                                                                        A Scientific Computing Application

                                                                                                                                                                                                        +
                                                                                                                                                                                                        
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + + +
                                                                                                                                                                                                        + +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        +
                                                                                                                                                                                                        + +

                                                                                                                                                                                                        results matching ""

                                                                                                                                                                                                        +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + +

                                                                                                                                                                                                          No results matching ""

                                                                                                                                                                                                          + +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                                                                                                          + + +
                                                                                                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-14-00-computational-physics.html b/clones/llthw.common-lisp.dev/3-14-00-computational-physics.html new file mode 100644 index 00000000..1b047147 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-14-00-computational-physics.html @@ -0,0 +1,1889 @@ + + + + + + + Computational Physics ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          + +

                                                                                                                                                                                                          Chapter 3.14

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Computational Physics

                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          "Behind every mystery lies another mystery. Infinite recession. But you don't need to know final answers---if there be such---and neither do I."

                                                                                                                                                                                                          +
                                                                                                                                                                                                          Robert A. Heinlein, Job: A Comedy of Justice
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          While Computational Science is generally useful for all scientific disciplines, as it allows scientists to refine and improve established theories and models to better match the observed data, computational science is of fundamental importance to Physicists, as it allows them to model underlying systems which cannot yet be observed; thus, the highly specialized branch of computational science dealing primarily with theoretical physics has its own name, Computational Physics, and is often treated as its own field---though obviously it inherits most of its techniques and tools from its parent.

                                                                                                                                                                                                          +

                                                                                                                                                                                                          As a third modality of science, the results of computational simulations of these underlying physical systems can be used in lieu of observation and experiment to aid in the validation of various theories; and naturally, to aid in the modelling of experiments so that the more exotic phenomenon in theoretical physics can be observed, if the theories correctly predict the behaviour and nature of these systems.

                                                                                                                                                                                                          +

                                                                                                                                                                                                          While modelling problems in M-Theory, Quantum Field Theory, or other novel approaches at harmonizing General Relativity with Quantum Mechanics are far beyond the scope of this book, it will be interesting to model some of the more approachable problems in physics and astrophysics to create 3D simulations using OpenGL; and write a general physics engine that is lightweight enough to be used anywhere, but accurate enough to simulate all the common physics problems that a student might face in an undergraduate Physics program.

                                                                                                                                                                                                          +

                                                                                                                                                                                                          In this chapter, we will revisit the methodology from Chapters 3.12 on Scientific Computing, and 3.7 on 3D Game Development, to progressively build 3D OpenGL simulations of n-body problems, gravitational fields, relativistic systems that warp spacetime, and models of sub-atomic particle physics; and as a final exercise, we will explore Newtonian Mechanics as an emergent system of Quantum Mechanics.

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.1

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Common Problems in Computational Physics

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.2

                                                                                                                                                                                                          +

                                                                                                                                                                                                          The Ising Model

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.3

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Simulating Physics with OpenGL

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.4

                                                                                                                                                                                                          +

                                                                                                                                                                                                          An n-body Problem

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.5

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Gravitational Fields

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.6

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Relativistic Velocities

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.7

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Visualizing a Warped Space-Time

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.8

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Modelling the sub-atomic world

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Exercise 3.14.9

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Newtonian Mechanics as Emergent from Quantum Mechanics

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +

                                                                                                                                                                                                          Project 3.14.10

                                                                                                                                                                                                          +

                                                                                                                                                                                                          Extending the Computational Science Application for Physics Simulation

                                                                                                                                                                                                          +
                                                                                                                                                                                                          
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + + +
                                                                                                                                                                                                          + +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          +
                                                                                                                                                                                                          + +

                                                                                                                                                                                                          results matching ""

                                                                                                                                                                                                          +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + +

                                                                                                                                                                                                            No results matching ""

                                                                                                                                                                                                            + +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                                                                            + + +
                                                                                                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-15-00-quantum-computing.html b/clones/llthw.common-lisp.dev/3-15-00-quantum-computing.html new file mode 100644 index 00000000..c50e7592 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-15-00-quantum-computing.html @@ -0,0 +1,1918 @@ + + + + + + + Quantum Computing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            + +

                                                                                                                                                                                                            Chapter 3.15

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Quantum Computing

                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            "Who taught me that the world is not only stranger than we imagine but stranger than we can imagine? Who has already taken me into two universes that are not this one... and brought me safely home?"

                                                                                                                                                                                                            +
                                                                                                                                                                                                            Robert A. Heinlein, The Number of the Beast
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Quantum Computing is built on functional programming. Since the release of Selinger's seminal paper on the Quantum Lambda Calculus in 2007, the progress within the field shifted suddenly from puttering along like the earliest steam-engines, to a rocket blasting off into space; and along with it, the circuit model of quantum computation, that reformulates the gate model in terms of the actual quantum circuits that would be needed to build these gates, has allowed for concise expression and simulation of quantum hardware in a classical computer program.

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Meanwhile, a team in Vancouver was working on another model of quantum computation, that utilized quantum annealing on a chimera graph of superconducting flux qubits to solve energy problems; this work resulted in the first commercial adiabatic quantum computer, the D-Wave One, purpose-built for solving computationally expensive optimization problems efficiently. And its operating system was written entirely in Common Lisp, compiled with SBCL. We are now on the eve of the release of the D-Wave Three, built on the Washington adiabatic processor---giving quantum hackers a full 2,048 physical qubits to play with. With recent announcements from Google, and a handfull of VC-funded startups all announcing their upcoming quantum hardware, it is an exciting time in quantum computing---particularly for Lisp Hackers.

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Naturally, there are limitations to what can be simulated on a classical computer; on a quad-core processor with hyperthreading, the most you can simulate in realtime is a 4-qubit system---anything more than this has to be time-lagged to compensate for the inherent limitations of classical computing. As the number of qubits grows, the number of simultaneous operations computable in a quantum system grows exponentially---and very quickly you get to a hard wall, where a quantum algorithm is no longer computable on classical hardware within the estimated lifespan of the universe. This problem can be mitigated by simply adding more classical cores, such as is done when building supercomputer labs, but this is extremely inefficient and expensive. When running quantum algorithms, you need to be able to exploit the quantum phenomena directly, to get meaningful and timely results.

                                                                                                                                                                                                            +

                                                                                                                                                                                                            That being said, time on D-Wave hardware is not exactly available to the general public; and the institutions which have made time available on the D-Wave One and Two to researchers and specialists are completely booked up. At present, the average Lisp Hacker with an interest in quantum computer programming has no means to test any quantum algorithms they may write---and this is a problem. Quantum Computing is the future of computing as a whole, so it needs to be accessible to everyone with an interest in it.

                                                                                                                                                                                                            +

                                                                                                                                                                                                            With that aim in mind, in this chapter we will review the basic theory of quantum computing, including important phenomena such as superposition of states, entanglement, teleportation, and various models of quantum computing such as the Gate Model, the Circuit Model, the Adiabatic Model, and Quantum Turing Machines; the programming paradigms needed and used, such as quantum energy programming and the quantum lambda calculus; and write basic simulators in Common Lisp for the different models of quantum computers that are either being built or already commercially available, forcefully time-lagged to simulate superpositioning, and time-limited to the maximum number of qubits that can be handled by your system within a customizeable unit of classical computer time in seconds.

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Additional material for specialization in Quantum Computer Science will be listed under the Resources section of this site.

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.1

                                                                                                                                                                                                            +

                                                                                                                                                                                                            The Qubit

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.2

                                                                                                                                                                                                            +

                                                                                                                                                                                                            State Preparation

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.3

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Measurement

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.4

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Probability and Superposition

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.5

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Entanglement

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.6

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Quantum Registers

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.7

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Quantum Gates

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.8

                                                                                                                                                                                                            +

                                                                                                                                                                                                            The Hadamard Gate

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.9

                                                                                                                                                                                                            +

                                                                                                                                                                                                            The CNOT Gate

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.10

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Single-Qubit T-Gates

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.11

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Additional Quantum Gates

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.12

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Quantum Memory

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Storing Unmeasured Quantum States

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.13

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Universal Quantum Computers

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Quantum Turing Completeness

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Exercise 3.15.14

                                                                                                                                                                                                            +

                                                                                                                                                                                                            Outputting Circuit Diagrams with LaTeX

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +

                                                                                                                                                                                                            Project 3.15.15

                                                                                                                                                                                                            +

                                                                                                                                                                                                            A Quantum Computer Simulator

                                                                                                                                                                                                            +
                                                                                                                                                                                                            
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + + +
                                                                                                                                                                                                            + +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            +
                                                                                                                                                                                                            + +

                                                                                                                                                                                                            results matching ""

                                                                                                                                                                                                            +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + +

                                                                                                                                                                                                              No results matching ""

                                                                                                                                                                                                              + +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              + + + + + + + + + + + + + + +
                                                                                                                                                                                                              + + +
                                                                                                                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-16-00-nlp.html b/clones/llthw.common-lisp.dev/3-16-00-nlp.html new file mode 100644 index 00000000..8ce03592 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-16-00-nlp.html @@ -0,0 +1,1882 @@ + + + + + + + Natural Language Processing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              + +

                                                                                                                                                                                                              Chapter 3.16

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Natural Language Processing

                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              "Language itself shapes a man's basic ideas."

                                                                                                                                                                                                              +
                                                                                                                                                                                                              Robert A. Heinlein, Stranger in a Strange Land
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Creating a programming language and writing a compiler for it is one thing; analyzing human speech is quite another. Computer languages rely on precision, rigorous formal definitions, unambiguous code that compiles down to exact machine instructions; natural human languages rely on allusions, metaphors, nuances, idioms, and unspoken body language---writing is therefore an art-form, and not a science, as it takes a very special sort of person to convey the vast wealth of human interactions in the limited medium of the written word, allowing all readers to experience their emotions and perceptions. But all programmers are expected to convey the degree of precision that a computer expects.

                                                                                                                                                                                                              +

                                                                                                                                                                                                              In this chapter, we will review the current state of NLP as a field of research and the libraries available in Common Lisp for writing NLP software; we will explore the challenges of speech-recognition and leverage existing tools and APIs for transforming speech to text; and we will write a general purpose library for creating meaningful abstract syntax trees from English, to attempt to write Lisp software using natural, conversational language.

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.1

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Speech Recognition

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.2

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Handling Audio Input

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.3

                                                                                                                                                                                                              +

                                                                                                                                                                                                              HTTP Interfaces with Drakma

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.4

                                                                                                                                                                                                              +

                                                                                                                                                                                                              An Interface to the Dragon Mobile SDK

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.5

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Parsing Speech-to-Text with CL-LangUtils

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.6

                                                                                                                                                                                                              +

                                                                                                                                                                                                              More CL-LangUtils

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.7

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Even More CL-LangUtils

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Exercise 3.16.8

                                                                                                                                                                                                              +

                                                                                                                                                                                                              Advanced NLP with CL-NLP and CL-NLTK

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +

                                                                                                                                                                                                              Project 3.16.9

                                                                                                                                                                                                              +

                                                                                                                                                                                                              A Conversational Speech-to-Software Tool

                                                                                                                                                                                                              +
                                                                                                                                                                                                              
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + + +
                                                                                                                                                                                                              + +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              +
                                                                                                                                                                                                              + +

                                                                                                                                                                                                              results matching ""

                                                                                                                                                                                                              +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + +

                                                                                                                                                                                                                No results matching ""

                                                                                                                                                                                                                + +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                                                                                                                + + +
                                                                                                                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-17-00-ai.html b/clones/llthw.common-lisp.dev/3-17-00-ai.html new file mode 100644 index 00000000..210dbc39 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-17-00-ai.html @@ -0,0 +1,1917 @@ + + + + + + + Artificial Intelligence ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                + +

                                                                                                                                                                                                                Chapter 3.17

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Artificial Intelligence

                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                "They kept hooking hardware into him---decision-action boxes to let him boss other computers, bank on bank of additional memories, more banks of associational neural nets, another tubful of twelve-digit random numbers, a greatly augmented temporary memory. Human brain has around ten-to-the-tenth neurons. By third year Mike had better than one and a half times that number of neuristors. And woke up."

                                                                                                                                                                                                                +
                                                                                                                                                                                                                Robert A. Heinlein, The Moon Is a Harsh Mistress
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Revision Note: Trim down intro text to focus on AI techniques in Lisp.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                There is a strong historical association of the LISP-family of programming languages with Artificial Intelligence research; this is mostly accidental, as some notable early Lisp Hackers happened to also be AI researchers, and in particular, John McCarthy---the creator of the original LISP language---also managed to earn himself the title, "the Father of Modern AI". And of course, we can't forget that the ANSI Committee working on the Common Lisp standard itself was sponsored by DARPA primarily for military-grade artificial intelligence software.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                These days, however, there are many good choices for so-called "AI Languages"---and Common Lisp, the general-purpose, high-level, multi-paradigm, programmable programming language is just as strong a choice for AI as for any other problem domain.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                It may benefit the reader to know more about the different kinds of AI software that one can write. Many people still hear the term "AI" and get scared---visions of hostile, AI-driven robots bent on the annihilation of humanity from a variety of Science Fiction stories spring to mind; combined with Elon Musk's recent outburst about AI-researchers "summoning the devil" by creating "soulless" beings. But AI-research is nowhere near the sufficient level of sophistication to allow for emergent machine intelligence. The reality of all AI software-agents written to date is that they are no more than highly complex, underwhelming impersonations of intelligent behaviour---and because their behaviour is entirely programmed, the emergence of genuine machine intelligence within them is not even possible.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                If you are one of those people that is afraid of the future, where we are either ruled or exterminated by our robot creations, you don't need to be; the more behaviour you program into an AI agent, the less likely it is to develop sentience. In order to create a Strong, or General AI agent that supports the potential for emergent machine intelligence, you would have to recreate the exact conditions in which intelligence emerges naturally---and that is to say, we would not be creating a hostile, demonic, or soulless computational entity; by recreating the exact conditions in which intelligence already emerges naturally, we would simply be creating an artificial human being. But therein also lies the challenge; there is still so much that we do not understand about the human brain, that creating an artificial one is not yet even a feasible undertaking. And furthermore, there is still the question of just how much instinctual knowledge humans are born with, compared to some other species of animal life; and what instinct actually means, when you consider a computational model of consciousness.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                In short, the threat of hostile AI is not worth worrying about; as usual, the only threat is with the people who wield AI techniques for the exploitation of others.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                In this chapter, we will review a selection of current models of AI research and development, building on what you already learned in chapters 3.14 on Quantum Computing, and 3.15 on Natural Language Processing in order to create a Learning Agent version of the old Eliza program, that will appear to become smarter the more you use it; and then we'll revisit your game built for Chapter 3.7 and extended in Chapter 3.8, to add more sophisticated NPCs and Enemies that rely on Quantum AI.

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.1

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Artificial Intelligence Today

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.2

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Heuristics

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.3

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Decisions

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.4

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Pathfinding

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.5

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Learning and Neural Networks

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.6

                                                                                                                                                                                                                +

                                                                                                                                                                                                                The AI Agent's World

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.7

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Knowledge and Information

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Project 3.17.8

                                                                                                                                                                                                                +

                                                                                                                                                                                                                A Learning Eliza

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.9

                                                                                                                                                                                                                +

                                                                                                                                                                                                                An Intro to Quantum AI

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.10

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Quantum Learning Algorithms

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.11

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Quantum Pathfinding

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.12

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Quantum Optimization and Heuristics

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Project 3.17.13

                                                                                                                                                                                                                +

                                                                                                                                                                                                                Upgrading Your Game Engine With Quantum AI

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Exercise 3.17.14

                                                                                                                                                                                                                +

                                                                                                                                                                                                                The Turing Test

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +

                                                                                                                                                                                                                Project 3.17.15

                                                                                                                                                                                                                +

                                                                                                                                                                                                                A Quantum, Learning Eliza

                                                                                                                                                                                                                +
                                                                                                                                                                                                                
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + + +
                                                                                                                                                                                                                + +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                +
                                                                                                                                                                                                                + +

                                                                                                                                                                                                                results matching ""

                                                                                                                                                                                                                +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                  No results matching ""

                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                                                                                                                  + + +
                                                                                                                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-18-00-robotics.html b/clones/llthw.common-lisp.dev/3-18-00-robotics.html new file mode 100644 index 00000000..bad87558 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-18-00-robotics.html @@ -0,0 +1,1918 @@ + + + + + + + Robotics ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                  Chapter 3.18

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Robotics

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  "Engineering is the art of the practical and depends more on the total state of the art than it does on the individual engineer."

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  Robert A. Heinlein, The Door Into Summer
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Note: the exercises in this chapter will require specialized hardware components to complete, and due to the prohibitive cost and lack of availability for some readers, it should be considered optional.

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  To many people in the tech community, robotics is the ultimate expression of human innovation and ingenuity; and in many ways, the progress of the field is also a direct reflection of how well we understand ourselves as a species, as roboticists work towards an idealized simulacrum of the human form captured in engineering. Humanoid robots are also, of course, a cornerstone of the Technological Singularity; and having this technology will redefine what it means to be human. It combines so many disparate areas of research into a single, autonomous physical agent---at the very least, robotics is a technological marvel, but some day, once our computers rival the raw power of the human brain, and we are able to harness portable power supplies of sufficient output, they could also become new homes for our True Selves---our Minds.

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  At present, however, robotics is not nearly as advanced as we need it to be to achieve those goals---or advanced enough to give us any reason to fear robotics and the cynical science fiction trope of a robotic uprising. Certain companies have been making great strides in the field, such as Boston Dynamics (recently acquired by Google); and we can be certain that for all the progress that has been made, that is public knowledge, there are likely even more impressive and terrifying classified military projects---but any ventures into that topic would be pure speculation.

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  What is of more interest is the vast selection of components that are already available to hobby roboticists, a very different situation from only two decades ago, when you would have to build nearly every component from scratch, even down to designing, assembling, and sautering your own logic control board. Now you can buy all these components, logic boards, servos, sensors, and more, to design, build, and program your own robots in a fraction of the time it used to take. This allows you to put more time and energy into programming the AI of your robot, up to the computational limits of the platform.

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Programming in general is a highly satisfying career choice, as there is nothing quite like the feeling of building something that people need and want to use every day; but taking the next step, programming a robot, and watching it move around on its own, learning and adapting, is orders of magnitude greater. A certain part of you can't help but feel like Dr. Frankenstein, laughing maniacally as you bring life to the inanimate---but that feeling is overwhelmed by an even greater wonder at the marvels of science and engineering, that awakens your inner child.

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  In this chapter, we will review the field of robotics, AI-controlled automatons, and learning algorithms; suppliers for components and robot kits; write a library to allow us to program a kit robot in Common Lisp; extend this library with an architecture to support intent-based motion; and finally, integrate a basic AI that will allow your kit robot to walk around, explore, and make its own decisions based on the environment you put it in.

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.1

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  The Basic Principles of Robotics

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.2

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Programmable Kit Robots

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  The Bioloid Premium Robot Kit is probably the most cost-effective solution that offers a full complement of programmable kit robot features.

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  http://www.robotshop.com/

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.3

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Handling Controllers, Servos, and Sensors

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.4

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  The Control Board

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.5

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Dispatching to Servos

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.6

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Sensors: Gyroscope

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.7

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Sensors: Infrared

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.8

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Sensors: Distance Measurement

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.9

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  USB Interfaces

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Project 3.18.10

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  A Library for the BIOLOID Premium Robot Kit

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.11

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Robot AI

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.12

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Motion Teaching and Learning

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.13

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Intent-Based Motion

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Exercise 3.18.14

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Decision-Making, for Robots

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  Project 3.18.15

                                                                                                                                                                                                                  +

                                                                                                                                                                                                                  An Independent, Learning Automaton

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + + +
                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  +
                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                  results matching ""

                                                                                                                                                                                                                  +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + +

                                                                                                                                                                                                                    No results matching ""

                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                                                                                                                    + + +
                                                                                                                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-19-00-space-tech.html b/clones/llthw.common-lisp.dev/3-19-00-space-tech.html new file mode 100644 index 00000000..d489b1d6 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-19-00-space-tech.html @@ -0,0 +1,1905 @@ + + + + + + + Space Tech ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    + +

                                                                                                                                                                                                                    Chapter 3.19

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Space-Tech

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    "People don't really want change, any change at all... But we progress, as we must---if we are to go out to the stars."

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    Robert A. Heinlein, Double Star
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    All software has bugs in it---it's just a part of life in a technologically-driven society---but not all bugs are actual mistakes, per se. Sometimes they can be no more than an application of the wrong algorithm to a given problem, which provides an apparently correct answer, say, 99% of the time, but then produces something completely wrong in that last 1% of the cases. Here, on Earth, bugs in software can cause significant problems as it is, which is why so much time and effort is spent on QA and software updates; but imagine how much trouble a bug could be in a Probe, Satellite, or Space-Craft, where a technical support and development team can't directly access the hardware, and in dealing with the vast distances of space, have so much lag between any event, the notification of it, and the hardware getting the updated code.

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Traditional software development lifecycles and technologies are inherently at a disadvantage in Space Tech, an industry where you can't afford to make any mistakes. One of the most important features needed in any space-based platform is the ability to immediately get inside the running application, identify a bug and fix it while the application is running. Lisp was designed to do this. And certainly, NASA validated this point quite strongly with Deep Space 1 and the Remote Agent Experiment (RAX).

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Now, imagine the relative convenience of a space-craft where all the systems are programmed in Lisp, and are thus live hackable; astronauts are already highly trained, highly intelligent and resourceful individuals who can cope with the stresses of life in space---and it would not be much of a stretch to add programming in Lisp to their list of necessary skills. If they had the option to control all systems from a REPL, extend, test, and fix mission critical software interactively, on an as-needed basis, they would be significantly better equipped to handle any of the many issues that can arise in space, in a much more timely fashion than mission control on Earth can respond. Those precious seconds of lag in communication between Earth and a space-craft can mean the difference between mission failure and success.

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Space Tech is a complex field of interrelated, specialized disciplines---and inevitably, after a cursory introduction to the field as a whole in an undergraduate program, students are expected to focus on one of the many specializations, such as astrophysics, propulsion, aerospace engineering, communications, etc. But it is advantageous to have a big picture, wide-view of the field before choosing a specialization.

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    In this chapter, we will explore a very high-level overview of a selection of the topics in the field of Space Tech, namely astrophysics, microgravity, properties of vacuums and near-vacuums, propulsion, aerospace engineering, and communication; design idealized model satellites and probes, integrating a basic AI that can be overridden by a controller on Earth; and implement an environment to simulate space-like conditions for testing these models. And lastly, we will extend this text-based simulator to a 3D simulation, where you can see your model space-craft in action.

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.1

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Simulating Physics and Astrophysics

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.2

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Microgravity

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.3

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Vacuums and Near-Vacuums

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.4

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Orbits

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.5

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Simulating Space-Tech

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.6

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Basic Principles of Aerospace Engineering

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.7

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Propulsion

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.8

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Communication

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.9

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    A Controller AI

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.10

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Unmanned Spacecraft

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.11

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Simulating Life-Support for Manned Spacecraft

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Exercise 3.19.12

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Live Hacking Mission-Critical Systems

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    Project 3.19.13

                                                                                                                                                                                                                    +

                                                                                                                                                                                                                    A 3D Space Simulator

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + + +
                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    +
                                                                                                                                                                                                                    + +

                                                                                                                                                                                                                    results matching ""

                                                                                                                                                                                                                    +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + +

                                                                                                                                                                                                                      No results matching ""

                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                                                                                                                      + + +
                                                                                                                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-20-00-neurotech.html b/clones/llthw.common-lisp.dev/3-20-00-neurotech.html new file mode 100644 index 00000000..7aeb82e4 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-20-00-neurotech.html @@ -0,0 +1,1907 @@ + + + + + + + Neuroscience and Thought-Controlled Computing ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      + +

                                                                                                                                                                                                                      Chapter 3.20

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Neuroscience and Thought-Controlled Computing

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      "Now that he knew himself to be self he was free to grok ever closer to his brothers, merge without let. Self's integrity was and is and ever had been."

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      Robert A. Heinlein, Stranger in a Strange Land
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Note: the exercises in this chapter will require specialized hardware components to complete, and due to the prohibitive cost and lack of availability for some readers, it should be considered optional.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Affordable Brain--Computer Interfaces are a relatively new thing. They are not new in terms of actual technological innovation, being based on EEG systems that have existed for decades, but the application of specialized medical and scientific equipment to the average computer user as a potential replacement for the old-fashioned keyboard and mouse is quite novel. Naturally, BCIs have been advertised primarily as accessibility devices and the next big thing for gaming, but their impact is far more significant than that.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      The real significance of BCIs is that they enable an individual user to become consciously aware of their own brainwaves, and then manipulate them arbitrarily for computational purposes. Depending on the sophistication of the BCI, this may simply amount to a more interactive meditative experience that allows you to track your progress towards inner peace---but some models available on the market give a very complete picture of the brain's activity to the user, and with multiple sensors, can at least in theory be manipulated like a brainwave-powered stenographic keyboard.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      The one issue with available Brain--Computer Interfaces is the lack of software to make full use of the hardware. Developer kits are available for every platform on the market, but surprisingly few developers have jumped on such an intriguing technology---given how many programmers suffer from carpal-tunnel syndrome, and other repetitive stress injuries, one would think that BCIs would be embraced more rapidly, as a more efficient and less physically damaging means to write software. Example BCI-based replacements for the keyboard and mouse interfaces already exist, however they suffer in terms of usability---once trained in the art of conscious brainwave manipulation, a number of more intuitive methodolgies exist for controlling a computer. And we will cover them here.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      In this chapter, we will review the basic concepts of Neuroscience and the various BCIs available on the market, their specifications and SDKs; we will parse the resulting brainwave data in Lisp, and attempt to structure Neural-net models to get a better understanding of what our brains are doing; and write several brainwave controlled utility applications specifically designed for improving your Lisp workflow, including a brief introduction to Emacs Lisp that will enable us to map BCI input to Emacs keyboard commands.

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.1

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      An Introduction to Neuroscience

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Note: illustrate concepts of neuroscience with a model neural net that produces externally visible brainwaves as a software interface.

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.2

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      An Introduction to Thought-Controlled Computing

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Note: extend the previous exercise to demonstrate use of the visible brainwave interface.

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.3

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Commercial Brain--Computer Interfaces

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.4

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Muse and OSC

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.5

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Emotiv EPOC SDK

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.6

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Analyzing Brainwave Data in Lisp

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.7

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Mapping Mnemonic Brainwave Patterns

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.8

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Training Your Brain to Activate BCI Sensors

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.9

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Training Your Brain's Resting State

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Project 3.20.10

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Interactive Meditation and Self-Awareness

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.11

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Mapping Brainwave Data to Text Input

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Exercise 3.20.12

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Mapping Brainwave Data to Mouse Input

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      Project 3.20.13

                                                                                                                                                                                                                      +

                                                                                                                                                                                                                      An Emacs Extension for Thought-Controlled Computing

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + + +
                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      +
                                                                                                                                                                                                                      + +

                                                                                                                                                                                                                      results matching ""

                                                                                                                                                                                                                      +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + +

                                                                                                                                                                                                                        No results matching ""

                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                                                                                                                        + + +
                                                                                                                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-21-00-lispos.html b/clones/llthw.common-lisp.dev/3-21-00-lispos.html new file mode 100644 index 00000000..4671e5bd --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-21-00-lispos.html @@ -0,0 +1,1890 @@ + + + + + + + A Simple LispOS ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        + +

                                                                                                                                                                                                                        Chapter 3.21

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        A Simple LispOS

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        "The difference between science and the fuzzy subjects is that science requires reasoning, while those other subjects merely require scholarship."

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        Robert A. Heinlein, Time Enough for Love
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Revision Note: rewrite this chapter as a case-study on Mezzano.

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Note: the exercises in this chapter may require an additional computer to complete, and due to the prohibitive cost and lack of availability for some readers, it should be considered optional.

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        The elegance, power, and expressiveness of Lisp often encourages students of the language to wish for a more complete, live hackable, Lisp-based environment that extends beyond the Emacs+SLIME development environment; they usually start with either a Lisp-based window manager, such as StumpWM, or replacing their command-line shell with the Lisp REPL, and then quickly come to the conclusion, "why can't the whole operating system be written in Lisp?" Well, it's not quite so easy as that... but it is still very much in the realm of possibility.

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        If you already run a Linux-based Operating System, you can start by just replacing pieces of your distro one-by-one with Lisp-based equivalents; but it is probably much safer if you use a spare computer, or a virtual machine, so that if anything goes wrong you won't lose any personal data.

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        In this chapter, we will review the basic organization of operating systems, and what software they typically need to contain; take a brief tour of the available open-source Common Lisp software for building an Operating System; and assemble a basic Lisp-based operating system which can be run on a virtual machine or installed on a spare computer for testing.

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.1

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        The Scope of Operating Systems

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.2

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        The Kernel

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.3

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        The Shell

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.4

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        I/O

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.5

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        File Systems

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.6

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Memory Management

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.7

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Processes and Threads

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.8

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Sandboxing

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Exercise 3.21.9

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Window Managers and Graphical User Interfaces

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        Project 3.21.10

                                                                                                                                                                                                                        +

                                                                                                                                                                                                                        A Basic LispOS for Virtual Machines

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + + +
                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        +
                                                                                                                                                                                                                        + +

                                                                                                                                                                                                                        results matching ""

                                                                                                                                                                                                                        +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + +

                                                                                                                                                                                                                          No results matching ""

                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                                                                                                                          + + +
                                                                                                                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-22-00-lisp-machine.html b/clones/llthw.common-lisp.dev/3-22-00-lisp-machine.html new file mode 100644 index 00000000..95731fb2 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-22-00-lisp-machine.html @@ -0,0 +1,1911 @@ + + + + + + + Build Your Own Lisp Machine ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          + +

                                                                                                                                                                                                                          Chapter 3.22

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Build Your Own Lisp Machine

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          "Revolution is an art that I pursue rather than a goal I expect to achieve. Nor is this a source of dismay; a lost cause can be as spiritually satisfying as a victory."

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          Robert A. Heinlein, The Moon Is a Harsh Mistress
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Note: the exercises in this chapter will require specialized hardware components to complete, and due to the prohibitive cost and lack of availability for some readers, it should be considered optional.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Few topics capture the imagination of budding Lisp Hackers more than the legendary Lisp Machines of the 70s and 80s---the first personal workstations in a world of time-shared, multi-user mainframes, with a fully integrated and interactive hardware and software environment, that seemed to offer unrivaled competitive-edge for the team that could afford them. Unfortunately, with the rise of IBM-Compatible Personal Computers, available at a fraction of the cost, the highly specialized and costly Lisp Machines were the first casualties of the AI Winter. But the dream of the Lisp Machine has never died.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Back in the 80s, there were a significant number of competing architectures, the various Lisp Machine chipsets being only a small number of them; but over the past 30 years, there has been a significant push by Intel to be the dominant architecture through a process of generalization---by developing a processor architecture that was more generally useful to multiple platforms and purposes, instead of being specialized, they were able to cater to more users and rapidly seize control of the largest market share---even going so far as to partner with Apple, to unify the underlying, previously competing architectures of Macintosh and IBM-Compatible PCs.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          But over the past decade, there has been a shift back towards specialized hardware, heavily prompted by the Internet-of-Things movement and the surprising success of mobile devices and smartphones. These days, reprogrammable hardware is available for little more than a full professional workstation, and once a chipset design has been tested extensively on an FPGA-based board, it can be ported to an ASIC design for microfabrication by a host of companies with competitive rates. These days, pretty much anyone can design, test, and implement a custom computer architecture, and get their design built and shipped to their front door as a big wafer. In one sense, it's a little silly, since this plethora of home-built architectures means more and more platforms exist, for which there is no compatible software or compilers---but combined with a sensible use of an existing standard instruction set, it does make for a powerful toolchain for the home inventor.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          As we have already covered in previous chapters, it's common knowledge that Lisp can be defined in Lisp---so it stands to reason to also implement the architecture of a Lisp Machine in Lisp, that can be output to the synthesizable Verilog code that will be written to the FPGA or used to fabricate an ASIC. And by implementing the core constructs of the language as the machine language of a Lisp Machine, you eliminate one of the most troublesome aspects of compiler design and optimization.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          This chapter will contain a review of available FPGA-based boards and ASIC manufacturers; a brief primer on synthesizable Verilog, and a DSL for producing Verilog/VHDL from Common Lisp source-code; and a schema for a 64-bit Lisp Machine. As an extra credit exercise, we will modify an existing Common Lisp implementation to run directly on this Lisp Machine and use it as the basis for a LispOS for your new Lisp Machine.

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.1

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Hardware Prototyping and Fabrication

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.2

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Field Programmable Gate Arrays

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.3

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Application-Specific Integrated Circuits

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.4

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Prototyping CPUs

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.5

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Synthesizable Verilog

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.6

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          More Synthesizable Verilog

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.7

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Even More Synthesizable Verilog

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.8

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Generating Verilog/VHDL from Common Lisp

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Project 3.22.9

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          A DSL for Verilog/VHDL

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.10

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Hardware Support for Common Lisp's Special Forms

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.11

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          The Lisp Machine's Memory Model

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Exercise 3.22.12

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          A 64-Bit Lisp Machine Architecture

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Project 3.22.13

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Common Lisp for the Lisp Machine

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Project 3.22.14

                                                                                                                                                                                                                          +

                                                                                                                                                                                                                          Porting the LispOS to the Lisp Machine Architecture

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + + +
                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          +
                                                                                                                                                                                                                          + +

                                                                                                                                                                                                                          results matching ""

                                                                                                                                                                                                                          +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + +

                                                                                                                                                                                                                            No results matching ""

                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                                                                                            + + +
                                                                                                                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/3-23-00-gov-mil.html b/clones/llthw.common-lisp.dev/3-23-00-gov-mil.html new file mode 100644 index 00000000..2bc338d9 --- /dev/null +++ b/clones/llthw.common-lisp.dev/3-23-00-gov-mil.html @@ -0,0 +1,1940 @@ + + + + + + + Government and Military Grade Systems ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            + + + + + + + + +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            + +

                                                                                                                                                                                                                            Chapter 3.23

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Government and Military Grade Systems

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            "The difference [between the soldier and the civilian] lies in the field of civic virtue. A soldier accepts personal responsibility for the safety of the body politic of which he is a member, defending it, if need be, with his life. The civilian does not."

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            Robert A. Heinlein, Starship Troopers
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            The technological needs of Government and Military organizations are, by necessity, far greater than the needs of civilians and businesses. Governments are charged with the protection and care of their populace, and by extension, the security of information about them that could be harmful if leaked to the public or stolen by criminals. Likewise, the Military is charged with the defense of the Nation, and everything it does is by necessity classified. But a government is only as strong as the technology it uses and the people who are wielding this technology. If an enemy nation, operative, or malicious hacker is able to compromise military communications, you can imagine how devastating this can be for national security---but such a breach of security is just as damaging to the individual, if their medical, income tax, or other personal information held by the government is leaked or stolen.

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Security is not a final destination, however, it's a process; and a complicated one at that. In military operations, every action and piece of information is time-sensitive, so efficiency and flexibility are just as fundamental needs as adaptability and situational awareness. You can see then, after everything that you've learned so far, how important a dynamic, interactive general purpose programming language like Common Lisp is to the success of military operations, and to the secure and efficient operation of government in general. But a number of other topics we've covered also have direct application to military service, civilian military contracts, and the operation of government in the 21st century.

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            The next generation of Military and Government contractors have a lot more work to do than just getting the jobs assigned to them done on time and in-budget; they also need to understand that the industry as a whole is full of bloat---inefficiencies, redundancies, and carelessness---and that this bloat is literally costing lives and putting civilians in harms way. This bloat is as much an enemy of the state as a hostile dictatorship armed with weapons of mass destruction---and the best weapon to fight this bloat is a technology stack that is designed to eliminate bloat. On average, an experienced Lisp Hacker can achieve what normally requires a team of 6 senior developers, in a fraction of the time; this has a lot to do with the type of programmers that have been attracted to Lisp, but it also has a lot to do with the interactive, iterative development process where code is progressively tested and optimized as it's written. This essential feature of Lisp is a great advantage to military contractors, cyber-warfare soldiers, and TECHINT intelligence operatives.

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            In this chapter, we will review the basic requirements of Government and Military Grade systems, in so far as these requirements are declassified; use our Lisp Verilog DSL and FPGA skills to create live-hackable battlefield hardware; and revisit the topic of cryptography, authentication, and authorization for handling extremely sensitive Need-To-Know classified information, in such a way that if it is leaked or intercepted, the person responsible can be held fully accountable with minimal delay.

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.1

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Battlefield Hardware

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.2

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Drone Kits

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.3

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Fail-Safes for Drones

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Project 3.23.4

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            A Live-Hackable Drone

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.5

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            The Techniques of Cyber-Warfare

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.6

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Deductive Reasoning

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.7

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Intelligence

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.8

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Automation and Abstraction

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.9

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Pre-Computation

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.10

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Obfuscation

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.11

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Cryptography, Revisited

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.12

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Hardware-Assisted Cryptography

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Project 3.23.13

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            A Hardware Module for Hashing, Encryption, and Decryption

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.14

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Hierarchical--Deterministic Keychains

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.15

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Device-Locked Master Keys

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.16

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Users and Keys

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.17

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Accountability

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.18

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Data Permutation

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            (i.e., selectively mutating information to embed detectable signatures in decrypted classified data)

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.19

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Role-Based Redaction

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Exercise 3.23.20

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Self-Destructing Hardware

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            Project 3.23.21

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            A Hardware-Assisted Intelligence Subnet with Strong Accountability

                                                                                                                                                                                                                            +

                                                                                                                                                                                                                            (Not actually military-grade, but useful to illustrate TECHINT principles)

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + + +
                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            +
                                                                                                                                                                                                                            + +

                                                                                                                                                                                                                            results matching ""

                                                                                                                                                                                                                            +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              + +

                                                                                                                                                                                                                              No results matching ""

                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              + + + + + + + + + + +
                                                                                                                                                                                                                              + + +
                                                                                                                                                                                                                              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/CHANGELOG.html b/clones/llthw.common-lisp.dev/CHANGELOG.html new file mode 100644 index 00000000..e6e1ac83 --- /dev/null +++ b/clones/llthw.common-lisp.dev/CHANGELOG.html @@ -0,0 +1,1851 @@ + + + + + + + CHANGELOG ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              + + + + + + + + +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              + +

                                                                                                                                                                                                                              CHANGELOG

                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              2022-08-24

                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                              • Add book.json to manually define GitBook configuration; let's see if that helps with some outstanding oddities
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              • Add GitBook plugins:
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                • "hints"
                                                                                                                                                                                                                                • +
                                                                                                                                                                                                                                • "folding-chapters"
                                                                                                                                                                                                                                • +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              2022-08-23

                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                              • Add CHANGELOG and TODO chapters
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              • Deprecate and remove old "Draft Progress at a Glance" section from title page
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              +

                                                                                                                                                                                                                              2022-08-22

                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                              • Re-launched Learn Lisp The Hard Way on common-lisp.net
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              • Cleaned-up markdown source files for GitBook on GitLab Pages
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              • Removed purposely absurd "BigInt" examples from all exercises of Chapter 1.6, +Numbers and Math, because GitBook couldn't parse them without crashing
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              • Removed Extra Credit Exercise 1.1.9, Setting Up and Learning Emacs Live
                                                                                                                                                                                                                              • +
                                                                                                                                                                                                                              + + +
                                                                                                                                                                                                                              + +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              +
                                                                                                                                                                                                                              + +

                                                                                                                                                                                                                              results matching ""

                                                                                                                                                                                                                              +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                + +

                                                                                                                                                                                                                                No results matching ""

                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                + + +
                                                                                                                                                                                                                                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/TODO.html b/clones/llthw.common-lisp.dev/TODO.html new file mode 100644 index 00000000..1455f8a5 --- /dev/null +++ b/clones/llthw.common-lisp.dev/TODO.html @@ -0,0 +1,1840 @@ + + + + + + + TODO ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                + + + + + + + + +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                + +

                                                                                                                                                                                                                                TODO

                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                • [ ] Chapter 1.3, "Extra Credit: Getting Input From Users"
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                  • [ ] Finish code examples
                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                  • [ ] Split code examples into separate "In the REPL" and "What You Should See" sections
                                                                                                                                                                                                                                  • +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                • +
                                                                                                                                                                                                                                • [ ] Rewrite code examples and simplify discourse for Chapter 1.4, "Lists and List Operations"
                                                                                                                                                                                                                                • +
                                                                                                                                                                                                                                • [ ] Rewrite code examples and simplify discourse for Chapter 1.5, "Extra Credit: Look-up Lists and Trees"
                                                                                                                                                                                                                                • +
                                                                                                                                                                                                                                • [ ] Write code examples for Chapter 1.7, "Extra Credit: Arrays and Vectors"
                                                                                                                                                                                                                                • +
                                                                                                                                                                                                                                • [ ] Write code examples for Chapter 1.8, "Variables, Parameters, and Constants"
                                                                                                                                                                                                                                • +
                                                                                                                                                                                                                                + + +
                                                                                                                                                                                                                                + +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                + +

                                                                                                                                                                                                                                results matching ""

                                                                                                                                                                                                                                +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                  No results matching ""

                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                  + + +
                                                                                                                                                                                                                                  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/acknowledgements.html b/clones/llthw.common-lisp.dev/acknowledgements.html new file mode 100644 index 00000000..091ed9af --- /dev/null +++ b/clones/llthw.common-lisp.dev/acknowledgements.html @@ -0,0 +1,1838 @@ + + + + + + + Acknowledgements ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  + + + + + + + + +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                  Preface pt. V

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  Acknowledgements

                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  "Age is not an accomplishment, and youth is not a sin."

                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  Robert A. Heinlein, Methuselah's Children
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  First, I would like to thank John McCarthy (1927--2011), the creator of LISP and father of modern AI. His insights into axiomatizing computation led to the ultimate expression of the symmetry between the human mind and the universe through the art of programming.

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  To the generations of Lisp Hackers before me, for keeping the language alive even through the dark years of the AI Winter, and for their excellent contributions to open-source software. And to all those who've lent a hand proofreading the first and second drafts of this work, for their time and feedback.

                                                                                                                                                                                                                                  +

                                                                                                                                                                                                                                  And lastly, to Zed A. Shaw for creating and releasing to open-source the LxTHW package for writing your own Learn Code The Hard Way book, so that I could finally bring my ideas into being for a better Lisp book; he has already gone a long way on his own to improve programming education as a whole, and to make programming more accessible to people all over the world.

                                                                                                                                                                                                                                  + + +
                                                                                                                                                                                                                                  + +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                  + +

                                                                                                                                                                                                                                  results matching ""

                                                                                                                                                                                                                                  +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    + +

                                                                                                                                                                                                                                    No results matching ""

                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                    + + +
                                                                                                                                                                                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.eot? b/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.eot? new file mode 100644 index 0000000000000000000000000000000000000000..c7b00d2ba8896fd29de846b19f89fcf0d56ad152 GIT binary patch literal 76518 zcmZ^JRZtvU(B;hF?rsAN?(R0YJHg%EL-4`f-QC?GxVuBJBzSNO0TKw=Z@2d0uiDz~ z>N?%0@9pZhTXpN4G6MmC{{r-%!vp@O0Rbuhwcr6N8vm31-}!&^|1owS^ws~H{tqAo z$N}5{t^jX<6yPJk2H^Ey%R&Bp#T5O1phx10RX7B{Qt8t9Pl**$n*kadIQ|f;xC*hEUn@g zl*^#1p2$%G{Blbw#9Q*e6@DYa223V18Ij|2&2%cPTvx@iNioUoZ)_KE6Q5=~WJfZ6 z@6#n=xTLp0OA@il+i|so^fL%AHC3|sOKFq@_?XQai){2qkS}rMNBrJi`>xR3*k)Ld4_O*y=YyU9%ULX8Mt|3PGQJ(= zu5_-C{h(64@}ws=y4%mO#^-0|S)8jKTS}tyTCRrQ#rm0C*{&43?>G$we1bThm2RqW zr0DH!n;Ru#`mDbNA2wM$;x!?!a`4fw?Fo~yus67&r1abr>%F0xMWMH?N|{wiNZ+FY zi_q&l)sRzB{O=MeHnz?|4E!7NzLgZx?>wKfMy~TrDUE27f?^!K0pcyz zKgVg~jz3oin*6AlFIecSs@o*bYRurv(wa@E+g$K~!LjVYF|>8*mz38zvT0|~_Z9-@ zFpwD~_2L(!Y&LKA6%F~|!5SJ(mBsg47{V^nyZ*x17OEqVyB;cG?Qs2f_ZtmwuJ*$; zrV4&09S>ZcsCt|3)l&E7&8T&q9=-bJiHDK3=i=dX9doW52uEMp^BA|^$Stu z_bobQ9n=z83Z~xpsct18Hw06@v%p4TXJGmaJEDy&(-v74j^{YHE3)iSLyj)+MAzaq zSB+BK=7$bIV5~T@od+AQJY2H9n&J;sL(S53?(5d<&xHEKF#(AEjDF0n9Jl27)uNRn z=Zqk(EM~|62JY~o@N;`C!oum~!C=AiA|~s%&&Ik>G**GymPqvB`PYqZ;u*QIa+@iL!)+*8P-7K zBA6oelJuQCvn?-o2%~luo8?Xb+G!NZ!7(~d1g2ttZM_#V^1$i{p!Qb*N$?!^+u*hF zV7O^eAoMadrY~~UdHTy?%pjJPqalWC^&_g56Y~m9&?E}nU5>dTmN*NFuSg;4cIJNE z2^EiW?@vNZ#r%d;BJ`>nq>m?N?9aCRC>Eh zlV6Ugn6XebS>cYT-zx{MC|>X&wjrrzRb@<5rN9sBgK3+zcK*f~#(jWcq}V82ZaN6! z3x!(uoZC?rX`+`TZExW@B_Jd`o0*~rUKsn%1&5+DXP_)=VVN6Rw_<%|IIeJXU{K?4 zkvpJ6ee4r5g*02SaFM0f$+GrDNoKlJ$fXCjeyCd_b;&|GDk?G#%7IhpGA~XrsRNoT zSn_IST!)8|RdNz{EK?$GHsh7BU%UL{N}W5${L)#YgMB{m(WaRfq+Ozk=>6yo6i(u{ zf(b&PyZaNLrRm8d?nLwm4RCW`F=y{wXwBU<1oh#53u%tXKBrZtC;g$CQwJ|3=?DCD zerFLv5RFMpC{V>kQ+TCYW{$YVXPdLvhk1i?2BH7*5zlBC=Eg2pWli#0yzi%PDl04! zX&Dv67bLYow-X+mpm<KPeKlSsQEOh60QCqd>_Y|7@=xfK+ngw^ zD9o5yHpH4sx!(oAf3Z~ut%84X+V41Y!;?fEQq#q#+CzZ?=oBqWXmCht%;@0qn-pXU z6&ZLq5MdGq=bNj3NOl3&${$YR2TE&Oh0hG0G2EOV^jo8A(1&RttcnDJzR-h1D#R0}zqpfOicY zzq2MeIM+kW>E-B>q$uKRN2tGiHnK}WNo6&OL>_t; zV1rZISSu}XgE-OkNg2_I@hb}1C?6<}M=_hc-{W8hM8NN;GYL+>#KK0dwCHrBex*Uqk)i)Dqd zU#lhxdi%Txp@ah5XeFm?k7_Yodp z-!k}ec>%eSm}S5O#=xIi$W$Rq_rR|K6>k|OA9X3z72fKks33U6BPZizFb_rTqPa<4 z;wu%~I7|kQWi{Idir_c6&L3<@%aS;uJbxr9td_oX+ztx@{eMop15cA&f zZiD^v=IYY`&qlv@6!HQpzSQKsQBb<*bcP;=jaHWhB2F^2tHq%Km@FhCs z{w($Y`FD&xEyPe52lc_;IpIF-4O|#a2C?nfX+bMIXiumj=O%J`M;E)dMDr)&@>{8C z3)nyTY?5I}>~fhpzYH!hfU7Dx2qW9CttqrJKu+NeWg8bK1ldYw%># z7D=t1FVzX${`^Rx_Q-`n#>5qB3-9K1!*Xpt%P!%+rm=Mzdi@Jv-Mdm(4nCkDi1#eo>L7qH7Xc{4y>=Zeb+Acl}PCs zP|AstTnUNT8LcRAh$XiY&;YtB)*~5^(DOj|p#-~{ESml1S>;0Ihcen0Y@f$jkYvz2 zlW{_1tCm4;RV=Sq@*X zmZs7>+b|O^;)AHk%5D8>7yOUqk}r&jH`_jC_&4rN32Uik1G+>)%Ej{3OW%M*irgZsH)L#PyqEESx$?Bw z(TuNjVL(pLO3PO3^)xyaV&7$hStYhzf%C&8Z|?JwE{VP%s5F$D11$(l8@ST;pbV_A!S5i<$-LImWb|qUoY( zgN-4291V9tZkzizQhq=oU!hNIw6!x{8rpt=AC4u-pxG>Xjeqc9#7@E!m<4@k`?Xc3L zGW*|?jHH~P{52A-aV(Q#{5es%%#G>8C-I`9`^(zDzJgCtLZ*03KIvH6jYvVe~m9=u?k})-Q$0N@CYmQMic;bnk2iJ>Vm8OKV6M&st{n4thcQ|8w z7ghMeK(fX}mM?x8ly1=nqrOKo4P7{=2?9!(bUPhZ*cvf1)bY705uSXn9{deye9Jvelcco2b>1-ZJ}k zFmR^35d_{lz01HTCO8%h4`fhpf)ySyi8hqDTcE(`V1*98k+0cyKPG&K99MoPzY8H%gq4+vdug@>y;9pP%`0(vW5A;I|G%#vZOyK?F z*(Px`vSR3C5JU%x4YH49uOow^77PJrF!ST?xHI~)rAc748p=xY%*3S*Qe3gKQg@pK z49qeg8DkFigyGW>y@|>zttBjSBN$SjknA5 z{#6t?XWP<2GvG6%gog<3*CmZL3)K(*_U>y|O^fpiv&bA|&5RY{7dxl^*^+goJg2=$S8q^swAAT(IoKD~`el<+KI_b*qBp>Acw-d+=MRc4pnDWkV_ zE<-7i*`{-C#UsdI++oxdg-81&2=U7rtwb-4H(MnnJFYlY>jaoE&5kQC`6+!hPo3Y= zbuYPeeaqMB&TtQ&zTJL@@s|{*iX`!P3ws)`oD8McaxEUl1P{3{P07T?i$-JOq)JIq zgRQ`>ilyi5qi{KImy=g-y`U>FT$K`LUty3n>wG0d8N(dMSlmUn^@~JG65S6ak|v%X z>G(IGs&}$r%!vWT1Fm@Eha|%nDG3II4qI;L3SHk4It}(`fHB3W@{Sx7Sz$$dK@)6~ zEMrYY=)_JoWHFc&Jy?*ozRL{n7UPAF_`8^_cxG5<(O0-YRVl5KkW}e?m3H!uh08E4 zcuqC?kiQ;5F5;Uerw;!g2G^M+XHOwy8XWG2d~gLlX^queZie2A3fFhiW7Jlz$8JSG zZRy9o7nLFKFwK`I7JA_bG3~WM_|p1alZ)@~b;MwEwv72`+N5ZECd|CyvsQNlYuxb%h{b6L)Yd4j zJr90~RK>_YG^dJlW#khv(r~oQlosf#7ncRUWMR-q=P~X_f_i#ftf&oHchD~dt_g2A z%SjtjfmS3Prw1h?V=Cl(OvJnPtL6{wwiNU}Qf(Vpe;`IjHGyRu^~q>>+p0uU2lw$x zzX{EKe%A>2&+cpPB+z2=wR_UL_kp=Ktw&-BlZ(aDP&&}Rk9}#xnfy``eTj|gL?Rz; zq5Rvq?aipr>Vy{d#RXNkh3YsJ+s}1u62e(X+T!j+fEOV-9x?NQ(Bk{uiNF@>*)Y@8 zK5|n2^0F4<(YBlU((CA|SGy|XtPpi{lvjSEv=Alv4>(f+IrX7c@bO2+5m;?P0&{fX zxMlz*4#ik)>qCBM1YKaeT#(BXZ9Hf^y#EuDS{@-PIFz=<>Z4a zaIz;#wAF~((i*{OJl~6H8L-h5knI+m*+y3Y)%XfVBDmPk^kz}>xpPodw4Vy%M+srn zfa$)D7(JGeS`AZy<*vyv5lX1n@N`g>rDmI+t#5>9;vOmnHoYtg7Yv}5p7P2yCcRW| zzlUBs$qrUX{3nw|v~_f`>(SgZ`Qa4+Tx1c*l+IzVLbwvDr;P1?$^^UUn!-^}@8Xnm z%fd~=#ZUe-g`*?%S`N1GieL}Lb3o(#AsixR+*z4YGbFTgCQQT#pN*A}NAQIru4^_Q zfGfqz&^(HDzlOh9nRMIRoK5pphXL(PjR^nzg-K|CT`_RkoAZ+(ni{!)1(8u4%#Ssa zc8wPx(53`h2TV}su1f_>Xz;<;0JgxwSB_oVqd;c2Dhi)MZS6Xd44JM+PmT7)IS6ju zrIlm;LReLX))zEtCvMC)>Sk4~wk0I`<4^kT@r8PsP{OfG?uC<28Hf$2oSF$cn$F+o zG1)UiCyfq0t*RJBr7TA_ry@;aEmIS=;e)hq8My+vN-x70gEOKQIsIlGhsWQBCQ^h) zW^)Cxr9?04EB4#0R0d^BS)IEzHm03mqmV4k(Y&49K$a)lfPC7}=$Pb{vS!aGJUz8u{xMruX(ZtQ$Vupj8u)z@a(< zp2!MSE5l0Ph1{$p_A^p{yDwt=0Nu%Y} zF5A7rB?;Mo@{eMwB!WE>5v-n-LtHT*sF}nfV1vaYt2(D26~VK_9Aos3VD(LL+qC( zi;TPVQDWu#gBs})2zSe}9{sPpWd8|~1u=Jd*KFN%4FR`%Whxfr#}0H@%bbCFGAM^X*lh$E+~aZQ zXaUMlg<>2!by_7y1^eYlKdJos+F357hHF;RLdIlp@q3ddq;(KnP;bE{U5|d;1@D=w zV>w)+K=!izn^)|>yBED~ z5=r>LT7R54^@n!+@L61Y(Pw%uI-+@hw1~cV^8&2|fKr~4B(av!>$7 zrC(%zIs2pNRwxiKNbtMy$> zWtRM|L$1SJq!e6jiW^Rw%*s1-A{;-ulF{wX!>~nrl)Gi7bim2+gGp_F6|cOET9-MC zIR7|-f0wiM>m?Oe^MJ*h^Gy_KK5cFLI_lfek(OL?t(NJUzeC$3`DCWWB6oxc?t)4SW$=c1L-XR?gKjR6Z z%?e3HKEkP$k8_FS8)D)1M++Ye?E;^@B2atFY;JXYNvE_jX|4nLe+4`QlIoU#r7-ZN z9w%ORF!TdEE32>(PP*9f!4+1ypjF8X34VRdCG>HWCXSZ+4n3H)>6&dLmDWrcEa$2m$ z<{P|tfdhbDou2!+3#eDom0vm@rRTzdaNf?nr%1`}2fuAx?vw1XxNjyCVu`X4lfCPO zQw{A&4#6$$$uk_U2))K_Xp5H)Ynj;M%OG+#5wovXa41ut|FriC zZ5?nF#JuH|{ni@Rb1?Wt0L4ckFaEV!VW!ox)2vWV@m0ortHgG<(|&aztcf*qm+?!L z)zAGm9oxG%PF6M%JF9lvlniIsGlaGwZ)XwlR?d=41aBnzLpe1FoItFRR;`$mDLx}A zXs(tnZMYsu$8goUuhiJ6uK@{%@GO~1CH!K6;^W6x_<&#;VzU=8n&L{Tu=AvTmmg1Y z%U|1*!pwm5>I!81otTNe4X4)T`r@h)MLmIfania|o4YiMP_|=}*4 zm_pWIwxkEH#`m|aw5Oj2cV-uB#SJ`daQMf&=~kRF@3xsN+UR(DDz5Yk8lDcaoW=`$ z;qNA4Vl#=JGw=*2{Zi7KlpC7JONZ1XD_bq&cHo~j$03Xtp1(JuD@k*#UgfxYMp_f1 zHeEc9Kcgq&|B5(vDZy+(Etf2hJ>k|_^m5d}rVF#m0M#V`Q9`v_-A*{>_qn*375dUg z20xPEwUamwFwVaNtLQZ3gYac3D)sy^c<-eomp&)JqaRT_aA6r=N2r6`KOM+GMJ=uR zJJSx}{}`IzagvLgClXz7Op`%JxJVWdnAdVtZ1L!MfIpFd5$mbn)VtpZ2Dq#c};nB58w+tL1@BkvVm+h71i)f_rIG$a3$o)nd2gZCgqZg~DGttbCOjwn?T1fRRA~iA+N6zr-;& z7UpcL;{pJJf)iyuS*g7~6!ti&x@hgZ#xgHB8ZB0#Wgu+Hz!hHcArgMW)f)z%?s16( zJeG`Z`(w!uZJjB~*T>P26oGK0$6Ra+4CRgGJkwbG9@u7+)h--#OMaS^94%|>j;>R~ zT%qfgW0)@wi&e~`^<*MZCoDx~+mYuARSCYEm>;`|buUuX)z=r)Q}WwRB&Vel;HOqY zt?1$U*XyTspA5UDMs;VDIKkBMCB~1`(9)wALGvaW59!Wb3>nh!}Np-waLby1tarvXP0A|3ysMqsnTY z7IT-5SgV|NZN3<9`r9|e9fK*l^~72~4KML@f2-=7XWD<6>M0GD5j6}OvWt#l46g@+ zBn=-(Fs@xS?n)J$Xr>RwZ_#oKk$->E5KPBlHq*q3&L}J6YBw6pbza1XN073{97~#q zTReDJZ>6J@;i^yfR}+Lp_`&iT@`z?ozx07)PYkFJXy~x!aMN}S`gwL~_GHQp#>HGX zc~A1Bx|bR2FLSL3hpVg$;3TbFS7q&}#y9$O_!03nh!J87!{4e)7zFtHXwl@hB7Ltnv=C{#bIp5A)l^z}mW$@fR7r0bAlUmCVRMlibs5x5Fq4U26 zSFZIg+>*5IGz!0zBUOpKJ^_PQ{#c44>MBlmvZ+1}#mCe>UnZt2iU;`b4=Ks`%8=u9 z$TmiTS2eHRY>QENc*e&d zSDHMkA*D}>uf!<*^B@wSh{4gG$_){w<$pQR|-hgLw&6qP`8Ot%3y;b<*UB2J;84$BC@z( z0JW2)PBTCCKjX|mU582DgEFE<$JPnr*zT}0k1YqgH^4CNNRbg-kp)`adn6aOvc~Tn zZ**XdG-;klXk22VA)~sxk zl~ViCm}zxxbQj#Q`nC&yi@#^Z4_kTje7HHX#Z9r)ohqOEbpwy|I29~GU6A64V_oa- zLeTsWwy=D=%p;5cn~o;lcCmBai2-3vZ%ow2_$y+$xZE9a9NyBP=T&sy)Ht&2m;fC*D$x5eeA zk|-3we#iLoM>`ak;r{MPxn_C^#s}X4GPjq<$1sEism9i!lz}3?-rmuB8BWatzqo_u zwojq@6^6W+?#sB(9A-t6S&x7YT$vmtWaS;So$z-~JKO2G?-jkjqh>t+a_WEt+UFN2 zX@i+V!X=T>N6gbBpMIqWgnj>PP)q5?JS)9!FEc|KN!IE{ij84)nbj-Fp?IQ>I3o*tsg#=d zduJ2{dC>k_+kw1CyPEmT_g$u?`dcCuf3qeu{4TTVg=R*}j9DycOo`bl2sfcvQuTPx z?po`60aA%Z<-w~g69NG@P}incHlH&rU9IM^nT~4%9$7g^@?rS!(MqgRJAhv=01gvcsK9^v8!{G&A@>6m%IkksPO8n*BL%HvD+ z#1N7N*nuKngpyM}cTkz$mIui*s@j$rcOKW;h8LAWl|eNQQ+A}^V=lrg45+OX9s2t8 zAYKBQRcHvp{l_zqn{q94ZJm+Q9>$`T9V9WCTy`4=i*k~7emc>orp&GxoJ`xJ@4OpD z*Rn@(dYy_9^u3@7bxh7W)JC(!q&=JLC9+=wxj+;eROQ*+{T{CIb;eL{Yt^8Zu`zc< z6ptq)CN(2r-zo;gjze{^RT84YICcamlGLO+%Gl7MtQj`-vwL7&?an*?+sn~_ zt`vD-=Lpc(ZfZb7+HU?4^Om-*0Q>zK1gOU&R;H*WI9<0)Hmhh?85x07-0Ho$td7vV z(N&g`doL6KXLkkXfHP59hvX-7jiW1H`QI3|tb3JWmwKYdXIJ_(}J1UBkge6&iZ6@DsuDW^%3T)knHF{CVE z%`NIrU76*s&S;^Ux)-wRNNKGyW0@S~o%L&f=^6HwcK7Zq?`uX^n3EUiTSg#O631ZK zhePX`V<*B=tqBB-E2jueWZP5*2ZYJqU~6 zBthp-#yiU7$bn-vlO{XhsQf+=_^5EWB&PL>(qQ{5(}N~^_l1F9M0crNEp74zU!CK* z5+0OcMd~LgQO6}Z{I{s$OauK+_pEI+*`E%*Qhn)cU&#&3uVg2pro5A_Js>f_SFWf| zcNd_qX(H_|;#0s#1?X5;oeHPuVm^XdAWkDlU6o`E4+fXA(tI=sV*EvvJr^BUTjg;L zRc>*Ov4>gW1(e#kqZJaVa=D$r3@~-;gkt_7CDSb-BI5{CVU1xd=d>b)(K?zRSwgi; z`Ov)Xqi6P9&?ZzD^ZS5DaAU6Ejbx1W#ue3tB)PPgx}pxCWbnu{7TB zT5)79g_Sw+<3?74^>ArZ=-u%^Ox&LRnZA_Wv>%$&R=L83HBq0j6kvSW#Y`0dvfYAc zwucJsR2@!xnRV+ksY}=3*80R548sDS$t9ZDG;8|8%B_QsRz7bpV@d6C#Pe>TJ17NV zPS3X<+Dsc$rV!d}7La2q#0e-;nkB=jzDzIWm*iXVnd2wUjl266^DEuOIvAzaYfAwS zMT;_^d3Wa)Pky!*tkS+&(k!z>7*v2O5{HaDz>TOYWc__NV^L^s&?A|2sO6nge%=ZY z0|*A1n5qp&3XBKw*I0a1{O6+qroT(KmtZX$cGrM3Cg$8Q|BoVSrxnyM{uJ1TS$$|R;P07KaK|`q;h~KgahRhdM`*O!*o`&YmZ&TQ zqx;X%9TI=&7eKZ$4H7tc@D6&*;=-7Vy_b6lfPYR&;r=jkYmHTbNnt8oB5s9!;m~48 z$T{?_x9Q>K5M&bdQD-N^4`e&2_iG-nl?uBCnu2-7t7;W(f&r*Faq}WFqxK}fGayft z)2xxKu59kD-q$3x{4Id}%C@T?h4XV#XZE-RCr=F1}H^Y)jtRPPxHA0Uo&r+>O z0g7T-m&;kfeyy1b(v1=qefXt98L}400}2#KTYOa9QP!$zVVa@l5Y3dB@kZoAmfX;R zV>upE4WL$a_v6;N{@Q_c2W1j3eW!$A88^N)*fdVT@zQkh3 zD*h+>;mydfvTvZwH$P2qyUz32NAK$g^se~NX6Bn};&&J>)-!r#zd!ES@T-VVcuNTs z#3gC0WlM5X0whJV-AePkU&L%;{d8M7f7)W0Ay~S2(YrCc*DcM5v;mz_CebG?Xs89k zw05F#M-qY;kE59naU7lOpeuO=QLnK{-i<-p@Ay#T@|5$}Fj$R~H?NH10z49&!d6^B z7n)z_l=cXO)^NZr8Dw;KfXn!?50wcGz&ra9b@*Wu5y+`MMSa;Q)WzaIzhKO+lgsA< ztmylLs$4O^cLMW=H_M;8?{_5F@j7rXnqGDvw!>?tPW}heo1^k*f(ZXkR-y z&s+%>H#vA}82FR_f(62_G4ts@x96YP>D3#@P#f~cVJ~wNclR8P|^=TnxtH0 z!SXNPWDbP}(x}4cl|*h>{AkXKosER(+hLI#U!h1gw-EpNa#Cs03vcWxb6)|ux6snx z?6YA;_4JOl@3*v+FocRkjV?s`#Gq{Lt)Am#mh`=sS>v82BBS)aD=Pp z56y9Gct{k#+V=4#Ai|?q1q~N!V(!DfRu2XB3#SdAvc@ILjAo9ZvL44{LX`_S{@}91 zfLN7!wAQV06aYK5yr|AwF1hQ8*Ewn1{%4(E%WPGXFcIMpF`Z8vXejimaC6#84x0ML*)wNq|d{d@v1!m zby#$pb&l6P)aA0emeBo4ba?37pl?(#?p1N&$x@}a$)IVs@2S(xN+5tI-GG8^&y&&n z&A+pD{IhPB&D{;zMrD{lhNURjPETasrX4R1uGuLkEib=3f#TY9&6! ze2&2$z}3R(a8k&G6q^`8kSig0ykqA9hf^5A)l7B5PH;+|14qC6xgA6)^odb+ z!cfr{LF%gp?8;5^x?{MkYt0&vvASrI^3q}VHY7l`GoV_y#EF83~NB0Ubl)E6~1Q=JFOq0Z6T44Kw#3WLy5tGrJ*^95D?mxR(m zE0S>-2bJ0m-;E(Wn5@XSWW!OlRRWDCRcLhp1%O$TK<9~AWI4mt>f^K$i8Mmm>e&-{ zE=KIM7Jz!v>+P#6pfhH~uEF9u)Qb`C_Z6W#$yrOb z??i}Sau93jat+Q&t}qG42(E7Aes*_2m#Z7i#}&C(4Pd4G(7vGts2nLsO-cK05Z@pC zEfQs7vPJeA(b|qp_uq{$D8QCtCHB!Y=~=D46fj)#H5Z^gh*DREuh2?`K+vw+R>}C$ zR%n>vs4tlj)fF;u+q2R6IKG(`&tV5&(~*NG%!iXnPdh6ACF@j{+M~gq0^vTifT`DzkCqV)_^*;_t z?%X=Gw?Q~DzH^#b`oxYO=scL@~qpi;O&x;(<7Sj z_1rYs5pajTzTPm~H$)6JQxH5^NRQWJA;k&&xH03VVec6yQgAMZly zFbO9!{1N&0s`b>i!5KWMewhlKV}y|>tMMcbvWb(=HnL1Z(po8oTFR#YKc9{)O=9NY zD1awJo$R7)(V-0=pp!o&o`%NU4wGJx=ltqD?$!2{&Du^P69~sB)Jk=M&=N|3Oi*c! zY`Ot%&<(AGrt5X*p|&NiGTw$O-uG-Z&BD*c7!vO1?-c_7C1-ePl&M^NZ z@sV%Dh(*wq1~%oo%N|$$&$;`_rnx_Pu0Q&7GkswF1nI~y>t#ElK(6*9#$uK>sej#e z<`2ZEq^EAM&sdme`&eIKG2d+o2>ulmh#=la54V{Ho+GpZO9 zaAzHB%$GQuL;t#}c3v)y8h(F-P?ezCBiW#90Ou^qX_yY*u8HiYdx47YA~HkP9NOB+JY2 ztxPT;X?H>ES(<}W0z3Xp=1|T(b;$`f9{fb?bpVf`q8S?;`D3jgk9cQ?-~G#k_>ad0 zpaR9ya?fYn05QYxp_78F^0)M)k+9wMYdzg+x=fJe_~J2pEz75!`W!*iTY7&~^ODkB zSr`xUC;-j2#MtCVK5d3`(%M@u^2iRkvJ$Z!3eq3D99duVFa!VKM4 zTtt=2VgVw8tiWbn9u{zx=3$P<6mxLF8zWLpDsy|F&xIs$s=&&=(%sD1gsB3mPwW@? z0W<{G-)JN;CjPK6df$c(Sno(3zZ8g9i}vLm4ud~Gpvqr&eim_#c+S8wt-QW8+a#F> zE&OC*u%p6Gsj=$Q=*uT3E;`ZCQGL?LNPHJ+G}k5M@?k8^>XZH_=rT4(CdTLIGhNLQ z`~-J{`z=&^-b5=(vC}&jk5p8o?SLAj%@@4)#HJNNLQk=Lch<&^g@FC%PDAa6JP|J^ zSZMpiOprq3QzV+Nx(K88S5XNIS?oK40@+?U*t zzI?Bk#)1L50E!au_7e16j8_urA2D4l`QOGA#^hP-YMSlKH6RJY3o91sPXDkB;vm(v zTG~b~JW^K5r4U7qd{iTKBS-~fn5kcl_zZpbdHA>h$RPM zhAGVabHg-B!$YQbocLrTH1fzsPpgbh&J#}cVkrmM>PiCf&0`32@81ZEV{z705cex9 zo8y#4k#|Rh%$^?I(qt~3#xpY z`ga*dx}*Qe=m0eTrFx!M*~5bE1b!2cDV5MEvukT}Kukems{D+PZZ1$lqBL{qoQg{v zSdoWv+CjVvCTUjtN)`q(b@W1h)6EKzTep)p+Jsz1?v;PPNn0a!Cz|jd$e}8GPfQ`v z!deRYNY{)rR_U@y_cuXj8w>?YZv>h~hx1p*m@XbVW3&v=+4kM0@{^DGESiWsG}?#a zj+!6QJoxL2G70jbu(DNe=(;V8*r5iVSEm`Vmo|>yhpEL?_})!wX;4do?(->kenzh| zEglV5Vg9fgOSn#X@Dj#m-iOJ!))PzWU?X5(N-s2-T$*wl=2m=>ViWiw(fzYb^jy&# zRP*+blhO{`KD~w!(Bk^jyy3ziqZr8wZCWN($i?z_)3&hV6E6HC76k;S?AKK2)? zC^`K=9B-KOdI~i-a`&uJi<`uWx_G~Xi5}{8{9ybvoWz=fgq9no*8Ffqb9`)SL}u*I zVHBft;EZjVy$=KocSUB+SSuoK9eH;G6ZHbV+v{DLD>ksJ+oDEv%^GTl^%!?m&7#%$v&m{2N~mV3zVocl-e zV$E)08eyW|u{O@|LNL4Pedz3z;q|e8$opdQJ>bM850y4<3a4$@UU;i@Z^2okY9_X9 zInWaI#=Ds1KXsqr*t{U&L&)}d(Ganur`4Et)Gk^}a@5fe?SEHtRIR|K@S`?(3dR;G zQ85L%VQXlZGd3PeRfD^rql`8>*#k8tMD?7JIFlR5&;G=RQvE5bB`R~AQ&zey&)M8N zEmm^+TeHNfcGz}HDa}l81`7#$k8*O&WVdxLJXe|@VX(6D^?z@B?u;uJ(olj{z7>su zC#}J{XiIxi)Ox>Qq_!s&`LXCxOJJT0UX{!{smJz^cpN~UvmoD*uOL9MJ&X>=S@LO4 zF}!``sYN>GQOKYinj)}6efP7(#vq?rzR$0z(tvmmivrvTCX*)a50Puil%3zZx9 zC}pf?tOP5ly5v^a`zReScF^$gfDS>Vh|snQuCA4q$_But2oqTIdM9uYK(A=}%kIqA zWU6Ym^qE!W#saA+-t2HcC>Z%ILxNZ?of8*M(756UfpyxbWXKf_xmr`}@Q!ues=l3i zd`2dIZf*su00o8FDgyHR3i_#~yam8aa+NGS-_g|%*;QsEbH^vRD!% z8azp}Uq^dJIqoBJP!RN8;(y^m{qks;&CwDzBpzX~DvzYDP~1Oh76FOElR5{Rrb!3w-4fvF@7eof?Fh#GzcMlmaC^$4%N3nv%yb*Qre+m zOpR57XcKI+1X9nd=poXR_~gI}VA7pWp=PGAuhu0X$y59FM|{~NUQYzm=*GF?!fnp2 z)((Y}BQ#t}Mtf(E2%7>oXDMDMFHpLfX22S99VnI|a5XwQ_aN}Je)*kZPo64HYEmrG z8u3Yp&HG1$G*gi|{SXY|Nvp>tj>h5*JexR(ezb^gl$FISb|d>ZNkR&xFi)}Nm;;71 z;Gmf1O%R{V;{Rc4Qb*#b->^1(NgTwg(}FhHFlHL?*S!l;XZK~<=x9CK?kCV58c@H|y(ETCdqd9|^8 z1u7`r7(XTk`dPjJ2G)Ug6;-F1{b+vym)!KCR6yX(G5J%!ouIwIFqzVV*S9h2!0a>0;YjB?@cm!8IXljZR!dmD2>tN<@_GK`1>0Z_Q;vNx4u}=)CBN ziwPa99Dh<=X;EOYJ!Hf|TV!XGVFSYz&fzIB(J%*&ihBz*7J32D!+iPn$st7oSYakZ zEO5d;MuUf7sgad}f&i*^2jjWVvLHSH4BIzb|b0A3fI07mknVqp&{Ax0Z&&JY&E#eg&ErHdwv zw>B(=v+Uy9Vco6p)c{gO280b~lyn=KI5k0`%M>1JO>uuuzhyVoy9Q-G+`ptjp>h zo44w;?o6>{>g87d0KaU9htDJdlXSI=ql_e5u-#E`y}U{Y@nzMmFov+-!qy=PBi*~_ znq!TaZ~u6VKmj$~mY3aP`UuT~_JEfWCZba;;EVv;-BYi=%G9O{U6u;pA;~@GLO3UP zgo>XDyFd=*Z;)kvCP&hf36EFSE^e)O8Pk!OUzl*Lx8q^o`_ufSMG;rAfHJP{7*H%} zv_t~gAOM_70j?r9>BaQPPp8Hn)2x$82DKGSe@6Lwj8t7@<5__U66x>?N}IpQWTHIQ z`cF&b>xtF0J2*MjML45y^-WQ)!31em$JWst0kS>&*smKjE9{jdr;I2ZP!3k_;LFtQGLQx}6bWvynfH6MW#_8+lh z1rrb}PhtBCCvbcS#Km0|4$Yh3iZOdzlg;714m5YeQC9p*wlGXjd?*z1T?4UJ!Tc19 zb{W(8&?&X?6kPhof$EA8-NI!~H*hlY7%eipd53rjJ$;7px-5AOmzNcVOgbDEL)+p7 z!x(0*t|Ee>4@N+SR&BxX_G++9QVv8B5e`-s7AOD|Ee5sgBE%-1r7Vo2Qp&(4H$J<- zFF&E>-P4#&+jM{|0FS{4a!jD*ZjP128{+qHvoJ1ZL*y3};TacT)BZ)TsSelUdF4N< z?F)(+%(bq8ajUARy9&)QFbQ#C;ax=@tIEMf*9}6^VQNakjPbcsA z=%~tnDTyuWJk-;v`4J$Ru*|kBI@zoTWG%eVf4#j|l-~n1P$QsSL;$8A!9S%=!`9H} za0x5~2cgdTg9$r5AsStY7$y80DT-dWEgaF-%_mp6C$eCazB$%4D^`17Dy5hVv=d=aDRFjsnBzTD*sju)@q~_|wDb@)WxsaENW1K4>-w zJ}KoiwT13~^-$|Xq{0U~qoGvhC-Y{5Gs*zp(}ZX)NGBG}>dU%*(S|M-3P3F!9fyG_ z*z)9WG#e4i>9Or1{=|WSC4|qyXZMp;cCIT->1WBV=0DG|7PHTAb5jAeYH?bytEr-Z zat#7~;Xw#LH7GvL0|p3AFqX_Bz)pPwq@BjGX5jtGfWRO!V)=PRZG0Ye#} zUKE|PqCwaV2hYnccj*E^itgl5@Y1EWxGr)oL-iWhAclQFic#`DA@qeyc8R$dS$>c^ zq-x=D-j|HioIsBZMqFV!EclL?*<`5~ZDE=6F$zhx{5s;*c0@EaMBpN(ie;p1h#IIW z*SnSo0kVxC0?Sy)RPh!83B?BT(N}aC2#XC-sQx2MLPSY7Ye0&5jZU(gfiHMVmse9eny}OWE|_ss`HBl+m3WYr zgNf-bi)Zw8+Y&8s0d?7ao717BRtpn#y2BS7B-DdJbG8m5!toU}12^UvAP~Y4C@oBt z_VKw-4cI_nE)RK}Zan<9HK)en$NeugoFm$U4`-4B1ya|*xMd>6J87B|5d@+7`LESV z^sk_GpIYwFB3}gn1!EwRuFBoF7*7HSD^h`BvFw6TxX@rO66y?DWUtl(oK6U_#(fv* z<}ZntO77Prb--aU{TE1kK@!}ulUcyF3u@6{cheLxLa%MsfsF8e2Ucj~OJ=?n%ThT( z@WneCLW~cHAwy>~_U)jeR6`SBqX0xMC!8b+k>%m9xbQ-PK1Di5@(V(B9{FUdkdgBU zR6ww0h*M~bKq8C**wwK8QvL2L->5Q=BO4((Ig*SGqL51*^7&6hJfEaeFh|&$$$*bB zn#J28P-jL65un5eHG|Ml>GTChl-6hrPS*=AY)dfdkb=S{L6I%;2p`RFN-ZbymsW~n zpg4pZ2zwbmgz_{S7Cuu738@d`qHYkW62j9$^l>6AViD%Sw*T$O!qb~@GRw5v!z(^4~ zDO+V>5DQY3ZE(c(d_TTcfGVZwOHI{fbS(ou7UOymr_hcK>~3$hqA zsJlPVTAVE+lzT?|$^tW>T*fQPg6DXPJ_C$^%{3HSHRT&@4V?lyizRW*bS}qLA!zwo zb=>kits?_nscSE9;;`<=Gv(>uRE26gV7|L+69YEbcUnxP9`XU`-c#Q zy}>AzqxiGcwAC61DO)7YRgxJsy~C$M5PO73!il3ZkPaxY`$^n+V>;qxg>{vTc~lj} zU{rCL6!&94Vc5zkvf`4z`A;M>VE7HA;zWo(*7=*K?t9_lm|lR9N04|fIxsq+T{IN| zf&MLru8%{Ch%C|87E1`O_n>XtipEGZ8H(~24)8*gmD_3O{wf>7DdLqm)$(Lu_2~vF zYHvBColR*ebHraLdAz-*bZS@l$#lkLMWEg1pJ2K^weak6X2;+rlDkIEvsOj*` ztPGBiwg^tv2(%6iTp`=;pQX{iqKu+^0i` zl{ za_YycuGTRZAz?+i3obzpw2O3ATAI#)eLfBH^$W5pzhYC4gkA_qnI;~^fe{ife|57; zYzKn7nz()A$(=HV!Xhm}u;7q63P8d9qeaEywQSv#Ie1Iq zk|Or<2`8;U#0x|vYZ+n48YbdRYb=@$L_?POJFFrpC^{ebT+YK#5}>zva-F6vbTCqU z3u5p#4k)$M%qb==Q~*NK7{G4sFkE2{-P>?jbh0ENcQ>RV>O_K&OCCTI0<2_VPK}Jh zS`r74775h?Bg9V<6^X(Fb|k@|qhJ`MB1S3{E?XfrnVW%}C++Xf;mh)&(B<51J|G(u zM3B(E6j+@*|2BxxERh(i?3_glJ~R2tc%*He2*r8&2SM3*Yd{K<5+Nv8wbbXrD{}PG^a|s5;iDU(;+#tQ&&&Ej+7j_~{ zpab$i28w|oY=yd!{K{?RM&)sESTUv+MBNS=5(QB65LN3-!Q&NuqCj?2TQC&tv(j80 z+%kYd$ovu(s4$5p?vnva4StrRQ3l7sML2`t7Z@=DaiEC~1wxw-*dI=EN6q#@NmD3Z zaThw^U20ho?SLzwCpT}1ZxDde%oZnTS!4@3>ca}0U2zNKqh&LLT0lrx)-Q)XUY9xlM%4alfrTq9*-7VEvfT+ zQQ^WwH&Flh7R7IPcMK~3Ubc|3Tz>O*1}#iAwQEcF+K>I2|Srnufix`i;$h= z278e4xamMjL`qFLB}M{Myqi|ZnvYBrn0Y2=wY&)pihxe*hL!=s%LQgQ2ne>KQ0oVd z0Gg-ZqjMzU`cs9F>LW5w{Km2!6gmbV4oaO0n{4JVI8*0bjd=nBem_f3jvRXclU>k7 z4pY({B@+*jmu)SP_Nn6}ofJ|Zf7~KrEaFklgcT&DEHsMpGfQ15d?D;w7iqYngT85I z{5eEq)X*%?!?T62FLphO%ZNZa&Rc1mR6GBQdxT3{6Jv9Mv-VQ>)XzjX~S2@JT8;#0jz2yDszST58KF5u+FhS97` z7ma&gJyXC$29ei}lQaHkVsW~D@Z6^4Vvg`dbFdR{w zaUR@M$C7w0T!+f4@{H$!pvZ`nMf%Niyxs?P5^iEW0BBYA8)gTIaPlZ8WsuE`N$*KH zFoeFF^6m|yHszEC>acYgZULelP%qn}K)kolyJ^4~Ll@E#?$td66J(mpdx0XwBP|tE>8I`D1{ArPL$il`H7v6fQn>uulX0AP!Ih9Y=*tAE*k1{ zCGhzv*%pKExmPAvle^ggwl)apq5&F~?U^308=hL);s3-74Is|y3I>6+E*nxHJ}cB4 zSJLpI&ue-h`mt$yoo!kg0A-v@c0(D9+!gu|2t|zFZF}PcVZKZNd>Av%uO~Y;h__)l zAc+a|{ys!i~p#5)`C_;Vp({i>(aS zbV@0)UfEv)R)DR&V00)%mOS#dRb@d}TY``Y9fI2;Qnd{!@yIO|w3Qg`EauL};)SEp zEg4qjVK04QbJ#Qk*c2?0x30v;W65clhOu7rsbm94Yi_+1VDK~(1vFgieL(b=tPE`5 zxaMOeAY$m6F}!%L8-Wp`8A;UcfRiB)qAs;dwdQDQZ`7hXF4ATCi7|j06lyY8ti}4~ zso(Js72tm6=3K_*d@`t} za{`FT;rZ}Fzw&ardlq&lkfQiACE}Rb%CUneo)Ew$i^n_wfC)XxR+R0NVBIPD0HV^8 zpqg-xgM`EyWA8x*qdu$_j1|Rz>>OEAlp8*aE#?c*2?$LOQ35htvM%x6v~Cj?Ia`=S z827upiUD#9Fe*-fZ4D)SSf1WzH_{$`v>Sz_*vsdNqw z^Qen9qhv&mU-s?p!nJCMCpQEOFM`0r#6Nr%2Ttav$@VMCZOE3Vu4}P37J+-mBL-+c;G8|42x>NL3`Y@M9hV9hD$y=X2~N!7u=N-Qe9&ejSO3kJl$t;mp~Kt zGHBgyP?1-qOmR5XBSxZuW^@Wd2oz`OK91B-R8 zkxcBe1{s@}035)UU^v{N8bfuT#Vjoa$r1`1KG*la9GkXRy3?vzBPqrbXz42CXWTs<##xGy6XdzUMzlenhIWCP=ZfU3x3kI4Ir zVriKO%Lj!jB&uC7qypuBDRfkVW=5Ht+?|1swi$Ify+~#R?Mg`mWy=0E z24+m-47sWxo1uC>57?Z4eOLfpw}LVfbUXkk6+4J&!57o%fd{;-WP+y-ON^yV!T~vw z9t$w<=uQJX3bqI))jnifF;J#uSt7$S%SeYjH6$eRndvsNp)$f^)9BtUWw4=;Nwaw9 zdrp35%RvCaZj`)3Pr##Xw%TbU3<(yWm=T1esa=isE^)k+Ig(f#K3m}4azEnWgp{o? zpDhicM>^D&GSR?-a6~+G-0Co3E;yn3o6d~@AYYGtc z@KG9NspyGX%WZHKHxbuAFWdlNyGEtbXV=b)0 z#r(@F&Pu1uD;fED#{$tI+D;&4(Sl*6_+HzU>F$b#-0Iqu&DS<$J()e7Owy#okQNpI z&|qKGk*iYm1`f_h1fik5I#5wE*F;(_2oKL{8ibgR5FZ~b9|_QbVu}$I^7b$nwm=5I zWB9YTcrT=gIzu(qh6onU3y8JZM{ZV*p~CX|01XY53= zb1yVdB)3+?FGTqem7QQbK(NG@#E_0a=NOb9Igx`{~Xe8N_BW(-RdZsOwG?8SWVW)5ioDaBGGhj8} zGeWvScYqEnt;*a1Drzn8vM;n&<%ufrg`W${UD$3UoiO+(f-0Ce?F@xzYiLNdm!UXT zhPvp7VnqP{igU{^7nj}9HZdtainm+f0e~gMlavNlvy!yE$b@Uj_M}tur5I?)P@OGb zZ7;QS6ep)#@Gnwx5RMGijzxdbLxah~p!`I+hAz7&t1bsH zH!{kw>6yDdLa z)WNxw)?mzm4T3ffui_Ng#Ttjh4--dqa@0q%9N}kG3d_ry9V%7YnD9g-EGBFeTE%kzu1PNKRh;5!J-Y*e>c@Bhbp|PdG{36+lFdLUHqbLIC4!qU z>d^OgH^F7GwYpq9EDk{+E{-7w$tC^6`}0{1ur@y9#@u;QH|6c1M;djPaCj0UA+5l$ zgU~usjSW*kTOJ*T+fx#^c=H1B6v?I7U$AP{nR!U17|&-PNJuVN3(@X2YQz)ohwYxt zAQHf9D82q=lIR!sWkw)pV5(Q9tr*)9f86Qv}Qfa#B^7m8ltY%M&s zu-}`6Ms)(M^%yX~Zgs_AqzN0oM9kB1i1%n)dAxaUI)$oR616uqxKp>G#DfBx`N2sI z2Vjw9dd*;f1GXrNg{D|%A^s=+SfGt&JNKQ66`zA9SIU#fOpshIrZ(2aV2HHiFo8fZ zbm3n?I0kF+kMb`S3wWwRCYJMH+GK@3xv($h@7Zx86XHpO5-o_8i5!3|)u+fA3`BCd z8feA!AR6Vc9j;j9XJEi8nCR>z+9%gG!^_cO{YKLqHCN|s?vor-tm5GG0$e4t(r8*u_CFKhweh}19V24;x??DQaM1UBL{Gk}jWGGn1;?NL z6`ThLooCqdGU^{WT)piy!&v2|)XD*%ie3N&1F2aZ&h|pRP2gUXV+RB@AcZ53`JYN1 z4+Akpwo3CqJx&31AZ3EP&xRSD_-}v<^f*CPIE^*?@JYMKus|dL5E}i{Y5LDziHKR7 zU?5L~&>=((g__SXBc)SmzB0f<5jNlD+rDd#xlFq=z?|q^bvk3Mu%Lwd_&)7KTrxVq zS{^NxNmdqAifA?x$8S<2e5p!|^_abY$KJ*Mj##+kiu^gu(GhJG`f~@0ErzZj^1;Oj zY@U9sxu$?;--I}h_!MY^x6Xucab^nu==L;SLV}lz#Kl;EF^`H5CT0sH6&PO?*fBH^ zZVXXTku5%LdG1k&jFEEE3az+|x<6q$uZ*sLnxM_k>EXg6<_Lio+SCr3@;lKlrK zf~)JKw3s92!`aA=O&WxF}CvMA~mU{UTF4*T3zr@%@j?FWVf{vQd|gR$TuCDf>o zbf^y!jF`Mo9;3MoE>4|EBY>H#7gy9pzv5UG&L*aEL9FhzEfN&6z zq-q|!5Udh=9PExVuqo}vXqnL8W<6-sLrxG3@{1G@ig6s!Yh>#d9TEhQ+QfjsNq`va zZd^3Lg%*JrRE@7{N>$;IX#O!19?iA@MNFY;%NVcd84>(R>p`_qxVve;xAp#0-G2|@%nMr`(JAbof zx4%(oZ3855zl9w%$|2WodQm%67&Zg~V{`b?U^1tJCxrbvl)I!lM1q_!woy{Pq$?W9 zgxe>O=Q1*j$Mx$F>}R_3U02QIB)5?be2xViCwQmFHSVBdp?}+7p`>p}i$Rz*WV~^9 z{>nxBAp8;yu*|$VyfKaN5zb?8YX~=IZ z-4%9~acKW`ft&SYhX4wj*epuwKGEXgmCyeLfe`*>-TgkX?CcB{V7is-|C*s_z(8j_8&>s*>Qb`KsAxw)43(q7$nAWWztby(uG?d4&+W%#=SkTb`=$?F- zM(E)Nm9l-?BP^7l-7+SQ3YbhH{=v|wNOtoK94Z_6Sw$pMxBoXo35l>%IS7*oOn*Nt zG`LMKEQ&0S2O;>M**Xb)FYJW*7ibcpOHd)x;hFHk^R~`+8&ObOqA=^kSgfn+t}GjV zrNkCOmhga0(&qbPo%*AjG}K?Jh*}6MlA6)IGvHBZ%TVC+2nz@Z7iA|0<@rQFaMvxS z?pKy9fd%FO)(aTsOgl5g@IJS0SKlC=4z7Yxt$tDODjWAt8$rKH+?Cm?pe*K$Lh3Zu zveYdTaf7i<@^3e4Zp>tIvPnsKJ4rgR0#$uO<;T;c=)a zZc_ZYJs?8!h%u9sXyN7SH$qn9p|+Oxk@Qjq#FVf5pjNO&W_FYlCdK+Q0=W(R|DD2o z*g{|CKG07|`zD_Fi&)S=#(?ksXRbDum><{&+?FfL2x z_#@qjGlkrZjE4iYNO-UY@PfDQ3e!Wg1PqPOknyGa>jjM-yz> zVmL35PlSOUl!)M@L7uI9zkJ_7*M%%hrZMID?OmX7FE80dJ<)tfnfPL0sV(hwV(_s3 z=k4cidnlv5X;^(fN0j3tL>1mX9Lwa=~z$%BrPPwKc*=#GBLzGSOo4MDI~yI?XQ&&4Clvqm6za%WjF|%;3-jB!X=O% zwrBGAgVSj;eiRcOz#zD+K)4y4b&PeHkhkb6c{ijAal#KeP%v8_k6u$PLRLweXk>9G zy9Zdf*3t~lDFtqS_6R`f*hj5(Tq154uBv_SXch>tMko?g4ho&ON|d;zc3RVB;~=Q) z4q5R`JV4h5rQzmpz7CA;CDu75G~l-&EBdUlKaki9x&?Y$_kUa%W^?gKZPk;35c8fK=Qnc!rKL9LPQAX%>WxG$+U=6%Ja< zVTdd{_ypl<~iodFM`+>#TVP`@tif|MHx^p z+!0*zKu)b9dV-4gu|hwW1>a1VySJy@C37LiNoYXpWm5bx3|fm_y2FN@Di zKYV~n|2qbx8ab*VgDQaG=qzGpE(4hG6Q8M|c#_e0stYJ%MMBeBw^^xcGM})U;!sZY zXk~b2-y8WE_h*iw0>W6luRl*FH4X5O+}qz3J7VvS;F~%#0zhVPD|98u1zBG~c#!tS zfR+XNj8UKPTcU>l#aUpXLih#Z*QB9QFzRkTidwp=ol=t^Zf=WpsyF(7XHa$ zLzP^u?Vykq8a8Z!$L+AYtzkSiQ>bVMEAL@8v!H0j%Eo~&t}PQ))f&%1U?f-?+7>x3 zt_)ZlC3{)4FZVC-J79rh2_K*fLt{vW)~FW{n=O#2Iduwd9b}~PaEpi29N{?T)B%`6 z46>^YsPR0JUshrLB6MLE!X}Qhk~edz6uIdEw>vMWK`5YS8;vLZEXFuW{Tg0;PRg=R z0-sQP^QqXHpsWDZRdanUC3`W%1ZbreFqkBRK^|gW*n6KuE%nw-bIpwmZ9}zA^VNJa zLSQp;4IV8){Vgw;wcm_+Siy$k4?o<)}A0ggcC?A z{CK6Zoq33EaLtOFD$s>x3>weGiXcPI9Aqmzf$*h!xSUsP3Md+|4hbAQC&)2q5h@IX z;TZUJSEft}RZXKTU}uR!M1tfrfWXW2(y2a%xJ^XbP!{96qL&{SsC0eC|nwtb%ZkUzs|6lynd>89PrB#BqDu? z1}{Q#EAP$*1ZE3Ro&uCWpWFUTJ@Mw6nai2Sm*p<1D{KYP8Nm6Nggld;J3b*J1X1AN z|4+g2_c9p|{2alWsKJt&j7S*r>7*=GZw87^NFs67N>Nd`g|dX9qtA|8MeX{cu4N&Hg;{7sA?B;1Ydbtg>~vkil*0i_OvUq%AGMQc-_ zK_X;{o09>V7W&9p%gqDoqsn(sbhRLlaqD4JGoUom!lSk$Og6Z`)#fD%M^Pm;h*FDP zDrrO!y4bbQNU=MEz(_n@j(A*Mut6ZXjrX}@GpeRh0FMtm-CTruC{o+s7ZL~h4UJbF zG;@5PyT+!>i_b2%Dii^~hI@Wb}!y=DL4de&- z@JkAl)i4?n9T-c-$g1Z|dC7XU`c4-l4q&-bn*YO>j!(Pcm_B4UXy}c7(yl#Qa=>x1YIFE zLl0RL*u)}i%yjjMSXLHfpT!3y=Ab5CxFdw5)(tKY0f~U#xIh6$EffKCajU&rIa^g(U^0VgJs?Z~$4vEX3Bu?& zvdLsGRg^u|N7dj5UN%P_hJXUi(u^}T^$e|eN z;6ud2oE!{&r|a*F3Ji2mpZaQ z!GI@i3WT9SbZQ!1t6g%}zTB@|^WV{Mc56#QHXMBSZ#msxfnnU?CV~j47v2+DK`)n0 z(d|C=g3azCSLE5Rnt2&ySyqXcK*Tm1hZRKVdZrer@g(?Kp~+MknWB^xM4X~W6N7|) z)6L}ftVbRPS##4mZ^wrtGp7Q*4iaKhVW+E5v&%to9>0<1k|MQ+U@!4b?`iW~4UEyd zJ%aD5NHX0NLItNM`iNb@P*CQ~2&#uEPCHqsxPA|cGF8c(-6Hlh;Fq9i0hkIYxqocW zoD{CvWK+&ewFv&iX^M~mO7f?#4AP(P0E6x!D1#UqIM#!xlWVs7*W=vRtwvp%kJJM8 zkI(Szj(A76L$qUO?t3&`o%Zc1fNe`520gp8qCU*_)21N@i5)l*Hz?|AqoC!zmEA1? z1Ly=e@O+5BNyduzNRj$Pkukq<&x5Ojd-BII@JTZG?2xblooet`ga_QJHWVY^nxHTn zD@`tqF8AgoI*YXbeiWorUts_T5la>>7Zqq*!V|1Qju&J=5Mvg*3R>gDk|07rg5o?Y z&@Pj8)UR|CQmt%7;mT}?QMumNj}@Cd2!BQ{TWx~g^N*_NILR9gzF-g&jNtk?gOO%K z1)|AAi!7IZ=&VUGRcH8Fv5MS3GtS~KKZeW`|FUT z`_%9Rc>OTc6e0lZ8Zfx1S8t3+c>4wCQkJp}Z`ws_2nd1_0)#sn1{4RH2v6}+Uj-?{ zc9{eU&6v|ku$U~wjc`l^(zk5AvY2Ge0ZpIm6-DJ3s)Y;w--!IN!G*aQe@~-Ho0>A% zYS=1Eibv&~U+|#a>wM~o=^V(^msntciqw_Rh%r7i6y&Rb1=LMr^!ZLRl_wajU@jhA z5*FcDg9W~c&`batC|Lkn0#E|47y=SFjF+1dE(L0}+GcZ(6$}DFS4SLTu%ZaF8}Jc> zoO5I*!^JH9^I0-H+hTc?k>t4RTS=ln8GwR0v7rp`P+g@PggksQY6^*kR=cpsrb()- z$ZzOnw?huSN9k-7nI2l6#S`j?+Hs6WKz!GQKIQ|z$qM!)9*!&(FUJGIaI5Z2-9Yo_6 zF+YZxBnkvTTJ4Q#$a%h4-9q#^iR5sP1(3F8@R|6Nx)I<8#&ias%NvQ5 zB?@AKZV3qrNh%RSfH))h3yZ6<9`~YwX>cpC02pqCzU4g%p#W8QCCaB!%0DyT{kunD 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⋙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%0DyT{kunD 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⋙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 z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.ttf?v=4.6.3 b/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.ttf?v=4.6.3 new file mode 100644 index 0000000000000000000000000000000000000000..f221e50a2ef60738ba30932d834530cdfe55cb3e GIT binary patch literal 152796 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

                                                                                                                                                                                                                                    =v_rA!CPE#mM^4@)}X7qf;At+v)G*FZd&; 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 ALjV8( literal 0 HcmV?d00001 diff --git a/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.woff2?v=4.6.3 b/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.woff2?v=4.6.3 new file mode 100644 index 0000000000000000000000000000000000000000..7eb74fd127ee5eddf3b95fee6a20dc1684b0963b GIT binary patch literal 71896 zcmV(_K-9l?Pew8T0RR910T|c-4gdfE0#wKV0T_7z1ObTv00000000000000000000 z0000#Mn+Uk92y`7U;u^!5eN#1yHJMdO93_lBm5dc6WY?}?kwoQRxJ870r-=0+y%ha*vYuUCUJ?P7_3+uzWik9+_!7nxs;V)%a4RNH^ zc4m8B@+|{zEa^4NCck}}OyG(NDl>kjf{My9O=ulWG&(tIM-}fv z6A!D373NE?xA$4-m)kO95k0xyK*tYODl4ALJ?*1sxjWyV^(D%2EPtO@;-V@{l;!qur0sm1n1+kORV!d6824Ou#3nIYjy1X(qjdu#foYPG3KvYpHl^J$>L@W~;6gmmj7y}hY+ z*%10elngK%mf>)kmtk|3oM#F%vwyz-seUsri!-}CbFaX$3j#~BowRibi*&DU5|l^-9DojV1KmJ3&?*~yNK2{0#ZVN1ITpSs z)hb)%mHH+owyJyZ;=@2|SH_isxWXiDHvg^j1gB#B94B6P$PL*D(x<}Z8c<=-s-GKJNgzh3?2GDRN3z0T&pzuKy5 zEZSgX?$}|6u@yprg9vvZe-G1=dzY9MP9KfI`m zF9dV4DyyHdvHNuonakq%Z})dn-%>?ILFE+}GmvqYT!PvdS_xd~FC$J2OUk!l z%#~<%=S>TDVW41I*<5F4PW=Cb00Hpk(YL$<@W$Mu>H*$ccI?5)Ybyi#10WFyc^d*9 zT@NTbOSECo`VV?Eur>U~%9S8~$K91%FJ7^dkl=ePDPVU1KT4Jdkx*U?+GziVn*ZNm z5Ly&~RfHJE5TKH{G%~ix3^0v@=3$)LA+`D8|9u8QJP8m}&P_bPBfQPx@EC?6#+x9u z_1@$IZu4!I$0sO?FCpgIyQv4-cKPrfii?1^7rz$?-~k8_VYCtR5D9|~OhT-9L7|MZ z&De)b9BvT`c?5=3T5ZKWH2FWU$uXUn9o&g#QBPhznSb=-(SMJQ-jlvWk2wzDF+&Fj zixv%P5LUoIrnI-)X}9XCEb=T(;%1}UX}6kK6DwIl!(PUnZ zodpVo#2~T5(+Y{UT;*~#?fFdq>}+jWzVpj zD^#_xDk=o!(`H4DWN{OkJvuTv8G>h)GALN?mvB`^Dw6v;T-*|(!jWpiqsT=X5~if+ zT4dex{{WPu<$a27AAm8mrz`uHrR?V_Y-t%O9ovX_rx3$c&hVA6Bo#2 zibMgz3{CqOigan0Pz_xxP-+aq|pHZq*@VyYNgA0bOntBr=*fq$trp zf#s#7I(cL%p^{>X@XF{2lg&y7f}C4Q(;7v;kT#5viE9Wy&5+EwCzjj)kRrnuIJn~d z8SwB(@QWf7H*Au8PaAU+2!v2Hh)RT(Pwoc7+>>S!ny{Qf_$DcjfMiNw30-cw6_;oT zX!TY6tNIn@lSpj-W&ED<{KH5V1Bvl?jGsC z`Q`?Ajw5S8mx(Y~Ib>C?OKO{rN|o7DG{A!W zKxQzo9Pl%yi|_Dq0=LZg_SM&WL6iam@eQqQ_k1MjZ+}l6>AlS+Hyy7(u#cGxs;~Xc zJcK^~TJqb>FOVsX?3mj#XLSbATwbev44iR1j7dJ=qq>QRaJ&shK$roRrpOwmVOFnY zk<*Uh(7UD^95cl936EzFwE$se_i4K1OLLI3yD1-LN?r46eN&0ddyx{SOU(6ewwp-y z=bgwyta}0?KhM+53EWKrej{?$(j>QR0C<15+oE^SCNT(@peREXs>Rn&ef#7Ke3=oA z_V!J?3^qY9^Dt-|LjYLq@~~|4&@Kf}tBxjR+bnrrG#1y_4jcr84UAJ#f}xkqIKI6#y3LRuRw7X9+t-{VpMl=_71_HYDN^Hev z?aq{SHIAAMAK#cAZ@TV4Y&A1-Po%t8GI;;ctaZLWtj-=ynw;sG4qs?4H(YmT*6N~l zH@miZdmd1TpS5_9)aPnNHa@sq{MO$URk71S0B1)Mjjh?ASS}d$zvPlj-z?|pt%Lm2 zzKS4|W17$mRVh*>SV0&JlpMg+R2#D}vOOhYGjpZZZIkO}V!Gg&iY5%kZpc|zna*gP zgL5{;u;|*d>#OP*xi++MzI-X5GNr*Q>*NnR6PnLAGAd>V^I52JGd=sosl8eXxHT<4IFVcG1Jv9|5oy6{Yrq88XTyGE4pP*}UJPOtX zdw({brBa!E7I2Jbj;;<5E9Y0+C!V>!*^!3nZsTxfR>0XAR# zvlqsjOG9K#ST$fs`QcYK*tM-S-&eu}E0+Y{l_F)N*OU@VG@G?yO{q>vXdrgGPAQDT z1p`ir8s`vmTh}V{W#Cc2+SHBhQO&7nr5VO}L2-jdJW z!tr90Qc~v%E((!#Yy5{nWaqT?G-%Ya>CM2{ts^~}Yr#1*_;OX>9e5VMoG^7yp5 z(Xy!snhKviAS%84VECkXgF9W}aIB?NERQbwm%<*G5pGX$6?aTDuwawnI7ARFdC}ak zwed&n=_i^jF)t<$tNyi)9$PBJQTc69k&a8Dl`jIiKW#tY50ZMs|;h8LrF#Bo~_5egI$UBiPF#4>~$OIauLay&K@ zX^#xuRO#VpcrY1`4~4XZi+w@)h6iXa$suYibVB&I&r|796R_bv)76ptIS^aJ!Hre- z&kJ;ihj52R-@c$m@av0uDnBbKX=J;vziLB13U}cY>hI`p*5V2JM>k;D>m>Ud*xWKL zy!2PNqc_$vf|DAxVNpw}N}ne(+{xIG{Qio1NuhECG{Rn#YK45b9q}Yb4TWy-qNft> z=p~-^>r024RwC()MD7NG8{Xh5I9|sk5W(lqU0TH{h%Vlm`_OrJMaM>6qFnTrT<2@1 zShLW`*nRdGLad2(GqOcS-t4k0XmI0X2&7uhBgt8^#|KAJq^rMq(HA|DHj?eHH~p9< zsJ##xGHjB7*|w{k2FWBNRM2XtC@i2wpP5^&fSm7JZD$Z_S=P)yg;*Mz%c%JDnrq@Y zXhu>|xV}M`lyN#JyxD@eqseVU_b-SPSmoSmNK*OU|sZ0d(*s%Kb3MY;B+8{X~j1ICPM?FR_k_x$rs zikcbS^{mX+pp4uXN!aM+aB$&E7j;}o+bpAe=_-JfaOWYObIP;0oQb%4wZhZZ?A&8s z3(o~>k-Ph3m#=W)6jKPlVe3Mx}X#Ch5)4y95VuCAzuMi;`fhkJLI})p)z-c9*Zwk*{R! zoFhPXr1LjY60$HcnO7gNx5%q%-p$n9z%uzDO+?1BJ6cS!N}@$ zJGcJ2rsBMV1>n2YOjmmk5Sq0~MD?sdm~X=x<7Q$sHjn7=x@C4U0nRrs1bUysU|FcR zbgqNN0=2AlH*qiIweEX0wP;_5sLalehDK&)%FzEI6qSgmk4e6N8C&jGXzMeg_S%~J zRJ@?BZ_x{Zs94*~@=9QSz(Cmj8=iUFvX)AQkL7oS)k5Zkb^CUp00S&&L2%lS8t`jH zXee`KcDjwn-I}<7xc%fMfgCCiV$+F>0cy98YsQLsbm?uz<; zo<<#oY6S1*plE5h@up~87iwLuNzy1e-Kdd}|s zHuY&lM)(BZFh#4}IRPZWvmpH2daniN3yDPC4}>tT;n@|Wbm2VErvS_Kj$`P@K}ip+ zf`3{JnNf$!C}RM}moU!-pO@e&*AYAeQ{sIdA%fB#`3{>TXGxbxLj{S7J*ih~|= zOy!4Vm0Hvq#Zf^&BBunwW)*ok{~^U1))`tjSG^(i!*>nuRw=*enD(=Z?#ANzcotCv zb*U(FfANyZ>+puUc`f;XNH`dI8QNwZvNNl2lXE*l>9oR7*r5vBlWR7=!Txx6fiL+m z=kUhG9zyjtG;L`Y^U3%ijZ&J1kkDL2FqBu)GG!14sdjiW`|$Gs9j~_K(Vl%!M9S(Il?dnH%lK zv^Qmpe)<~=rHk9>Jf<=MHstZ;(2dh+{@Xu49$dJx&V#=)>1QUuAYmLL86g0cI?DaY zOh6jD6{PTGtZk5jcXGR0X8dw+GJi}7X?t*!muZ?)4?PTc9c*OegpGws;aIgwCPAcD z*6rRKUB)oD)Rg6GG7^;_<&-LG?f<`0<&Kto>79m(+r>#b@~e~<$#;mW=6xGOqvh=+ zHm81{kAIXL$su|mqnh=mFV>$sfJ=Zw93;r^s@!!ScUHR+&D(Ab8vaBRoka(M5^QAj zE`8}Vxa`@mJjrC093k|D-b=7(wJRf+)=kM0&ER869hwSAS|gJ)R|AJsLPAhc=#m2zRBr9#=dK-oESBt5vPq%@>ch>>aVi$+hP5ap)n>L^QdM6#4tB2fav#1q1# zx$$sPBk4N&Q}6Haya>19_MI)nR`AXS;DPUKV)?LdJ5IJ0ZcS`3QeSe5(YDMIkERg7 zqa@>FPgHj(cp$}6b=$gu>G0gfJ38<$7~*tWdv^KvHkkx1Y+@NtEWj8letj7%`{!uF zV$0JpF~Vqrtc^5l6AVv|ftziV%hV2dQILX$;wbSCO|5j0gPal*kg$R_Z(t!6zkx?6 zd>suEuqruqYEBHY7sB-7Mq0M#A5lqcJ3RWTAvBAaBP1;aSL{?kIdWl@q~%@sWga43=cx;YfCu z(K3u|?K(`;LG)Zibaz017;IzdLFE+;_v%M z$j@^#eua_G}wUL8&CQvDjh3$X~fN!g2m)ZXLx>x*MdpbI_$dv?b4n* z#ac8i+v39p9*XaiL;ezLHLnSx@c!uFe;tpsm7k|K=J)OP6n0i51YB67LL1YRphO_- z^oKRuXAe2ob??kazS*H?+uSXeiy&8O0&Od}c;T~DI>g%o_i9o!LWOIHf2+xl)*h_3 ztdVz*9C9_W*sg?rCJ5*CG~rCy%f132q@BYMu5(Az%KMv)-NG9a4=f`$mPg`l6F#!P zPZ<&8!tnR?%dcsrghb-8onSH^PJYQ>A)>PqIqy$W{Xc5O;(soS>ChUz@?T5*FvfvG zZuH=*Cs&V4#M^A5sQFo-t_B8 z<+h;*v9>%Y)uP)xw-0BLC4iIrWj^|=Ie_Yy`Y-FzB_{*=)kyRaZ9bq9Z2E+lG>T#D z|0T1Y%(FY@o_S;@XV+>ub(~KCjfj=C_GFn>k1%YF_21e|>xET2xUCY0|NkVY@u0kG#-Sl=VH%hbHBe^{(sl4NHLU zD8NmDr|>yRz=;t)h+SC}ViOJO!r62v1P4X74q<1TMzTn+^`J&|?L)4GvhotG)@7AZ z5Tnju%xo$c1XJ2%?O!ELvAXZ1y6l`Ia~5dZI*SvUD4fnroK(lG`J7SCrPK%L6ako{ zm?SDzng_F1t1WTm(!bn`7;DnkEuHzoNuy525+N@gj-`s}SC*riDpHf8YWdA7R_Zxw z)ILVLRN+KfRWgwqJ2O411l5=)nU;bnQtHvFjF<)V<<|_$c?Hom$GO-M9`eK%LwRnX zM=gx;$^G~70;LGI_9Z-*Jxeh7~QK{bpC^=PxP zlVC->h_tUEiQH{5IyzV(syS1yD*!gZzvex;nGzVclJig{NzCf?5$0f0%D)u748e6b z57~b>^5?bVFCA~YIH~eN8n1FoeqN4;qg>`pH;5R%rD= zF3YkjVON2%t4zzL@Xjdvum@jzOvSV65vSfVkk8Gpoz}Fy609-EVS0jO=iQ?q zZ!+E9(8&BRZd|!Cg*+r4&!zh`l{6T_R+ql&moQEoDx|AT09x@^mGhBQV34MD!Q~!9 zKiige%VjLyhG-{i$O8hNC@-Icc&~kc6pweWk*VxhaB8ilYqf=6-gL^Ui+r+KM9(wmrjp5M>BhJOJa1#DEsr{oi@^*RmVy*2hc<|b&A@g6(@VQ)cN#1`wse9} zvjNA?{a={<^fDE=AC?m@`(0UBSdq$?jI*lIDqdGnvG@C2`YX2E9BlSxA>I%U@PF3(J+M ztfsBhx8>NCgBL2iNgQe04N2QIv-#QW>WipmG0+JhP&>pGMhK-H+qBAe!+8&nE9_C| zVAgmDG59jeVipd0hR7a}?|HQV(M+;uE{xme*RwAyKh#=_(~*LD+IOpIcYlB0sPnS7 z-w*BMv$9OCf5AkUd2*+|b9Z4#&aD@E+F=P69(Ggn>$2{hO{$%eki%9IETpd7G(C}B zN)JLv3>!n#Ll&9dD_H+4;|TNqQhNw}IkO<$6@L;2(?m=NSan0+I1HJuM={%_Qn3`B z;L2s0oW2#|;-jA#mlA5ZZ3PqGI&&1l&qv;q;L)SrFM7z+247M@9 zE5ML(Ue^|t&K)hSe2#AIU{yG1^yM$a?j}6@ZFI8*jYmQp+T7c{--pv_G&dS$gv{thY@% zso^>8Xp9xyfulP5A z&Ymi^Hn37#N2sjTp*de0$89+zBd_{yiY_M}`~GUBa7Fb=MsDw!F1tpi(5&}upEV5+ zc#Xq>$$onGLc^FFcAhOHdVtGM`}h7k8a7R`(=%6FW|`Ss5@(FDb=EZWGUcaV)q&lK#75UB6X!8(A%gQm}-A0g?6;8(_EfrEfX3UsLXma2wWxrNT zD=b=W-nP({n>QirDyOAHWjQJxUoBZjL`O*kD_E?O_>s#*zv61#VX`4gkw5ubae8XXRy-$pT}F*%7So`7 zC3LAHOQxGfDmQ2ZJuunSVj<5XgWR}fTA`^|p3-BX5Q;VpLkM|`H2x{t^HWG9uEnv| z4MUAwe5YvYM3MqeI?L1db^3!WNs_!W7Y*u;y|9YP3+ii0TycpPk18yl{zX4gzfCwA zMVlxk04U0ycwDgu@w~zo9VC_lAEQ8NX!cpBG)%`3DJvzVM%emVC#sf#_@f>{@2fo1 z+E@;+GYYja*7Qm>d$50OqJ8Zn2Q@}LhaQR zIzTCNR0t)^CzB(B#fa)wDdC%%)Im|(skvm3^pRneYzv^d-wp$mlt?a$);UD0+)+xK z=KoPx8jF-oA(g@)54w(CDk24y57Umjnk)vk;VLPq9KPD&aeA7F9Z*(CUU8$~S*aZQ z%Ed{=Qg}MSX<&TEl$$)1h@Gg++oAO&rK*=!i@rS2L^V)m&O|1z^m{NjkU&sDZ7X>- z7muSSBBBaY#cR<-sFAXda`f8AV7zFbch!2eYzVdH9Mau^DJ~^pNdDdRL12Z7x6mLNG~%JO65XGv7phC=n6oE> zptAKH#9Fl!n40TS)UFwt9BRR|K1HvL4O8~M6|W79PTYWoLV*eL`EU+%#?}%F71I;R zr5;USc?dG8q?>J%BYtzsy2qHJ0viUI{?qoER4bWAY2lSHBzFrR_ zy-Oc5B?e;KgIujUDaweBs^%CV;i6Dt z%E@}kToytRZoR;{r20VH&6n=3AoQk-SU-WL+cJP2>w;Afj-n$*^x9#YrH^NEhSX_X zF{>d)s!AhNDzqTZW-p-;w;)CT*m%m;PtY1qDkr&% zk$qtlV7+&;MJ3Zb$si;3BC7T73AutHAhS#Egpy)22p?pwC!9RtHH90YE2G**2YObA zZJlg#+3{rBcg5YlBNq049((6%9{Dx2i}LOpae4d<)hvYeJ}$444j56X*w4mHa*)r3Hg#W4PGZc`M*l=Yl!gi3dFvo+kme;!U`i}0K(dp8A3-nvJ zC4~CbGpb+URm9O`@3w&8B!6Od=LN0X<ezUYv~I*si+OJ^6Ro! z&r@lX_@lQnqv;Gg7lC6C0E943?jzaAN%2QB7kg=Db(#PI{-155Hrix1Iu@Nk(lFjS z-H*j5;(3s7;N*_3hAAIaar+XD1rCx{x2WZ5V~QQZO&7%UF_-hIoe!yHFTtr?(K1R- zBj7=rdnPRSB3PJ{lC*`fE+KJiL5>V4ono)W4unO9)zviz1g#vK4}pg}!+`mV_ZRB6 z0RaUH5~LT|tlX7VhV}s+WS#Vama}_70BV<*1_}fO0uns&&w~=9__Ey&@b7Ez=Y{}I zb$fv)4N4a6L9Tzpgx|j)b6a4ugT*M~@mhZ}syCdTwQ{_5itJHj7L2!6t_r(Wsg`ZY z+^$etOV|M8?Qbn5GlFAw`_Q2u^Jf64dtqshX!mp7E@MAqgpECUKnAJsrQ^n>60OfN zUg(2JW1Q%Yty^SqqM-^6GP=G1o&moPJN*5Sh$0$ZTV&f6*gVqHF~#60aSK#+Nm4sylw~t)AG~wOWa*ZE6s?U+4A>TiB}?~)_os;Fn#93B$sHiJp~?P zZ56^)(~>Ey;V6_<+JJBj=HDoMV~3CHdi$3#f|u&ZT)_{FDSd73G@Y!W0)G zRjqE%p%JNR+KafkBNAA0gvW`6t)xl{cHXm%DA&v>x|TRdjIf4Y=pZ$~={Lsh;m)M& z16#WbP_EkG%BW+Xq5klP!KFpxN7AaioXv&Oub`j0Tf|o(2+N@g*1cjV2&U5-mE4|6 z-cTp39j|Cz*a2Fbz($2H|1JxfwaHxp_B9A!3u4PTVYW+`Lm`kW9x23{Dgp0L05M$p z3%iOk#QsVhC&RJ{LMN1~fu+zKhL_~);SVYfd-7X98niik3~^*$r^9gBUY~86mSCG0 z++cPS?Q2r#i_q({JZy2gy4<#}RB^!0gk{VKRi7?npdB&1CoAud&Dl1`?lka@!j=Y2qL=sQ2Ky<$JdPyXH^N!yOG)>$o?ZCJ$sIsf|Vk zmuku-n;a0Gk{Hl2X}*3+4c;)gmP?`Qe!6!@{zWbxbiVW(|}#%bw<%R>0=W6<&xuB`!{*Hy()Y%2&@I-@!%K|DuEL^Vm@6`Q~+2kMgz)t z%O@bmdx_P=5)4rDOrlGGm})M5DO4g+;{+C{v6R#sP%(n>Ses{Q@*}SrFB$rTUm(8p zxhE9y9$r?XrLj|+5yo6OESGZkkp3jIHC2Wfg60wM;WQ7rB{iVv=X>R6X!js~a|k|| zaxU9QiJ<77Q7)*o8kGm6E)8HdUMpB55_P?%hT*%#_nSE%y_mk+Gd3*S8c?e38(7awbfK^z~Z};x7DQWo*IL)s6gm{SgENK0Z!AHb;c(jq&zY__lQ2 zkOuV)S2$QzWN6ULH0>(C#?q?83-qfLMGGd9JY;B0;2Rea)LEoXG|Sog501{CZhy${ zZMe!as=son;=|~D(Vic6q9~n+OjOPCwUL%r?c@fYVXv@s+{{cSQZoXZs-GDgwL|b1 z;GqKtdkZJeY|b>U;eb|Xjjq`Y;u%J?M{V8p&7xV8p_Cu_pdek={4xh`hDN!Iqjuzk zY};^m$ABU$-S-S2b@KXci|42VxJ-hp)@bm?Qj1{NRHP)ddoeR50-Shfs?~v$O0{0K1PBX{ zC()8f7^%SJ2oV_|q1sD*}^;7XqG8jw^ELl%fn0r{&Av|rml;t%W^%>`ynr7qmy zMStM9X!MK51Hm6K(T}G)oAPjdIOH9hN!CkyLW@#Hu5wOgA(7B!!oJCV12YT(Z1}h3GZ@<62 zd~md_+eA{`DB;Qh_#F!nx_#H0!Z4Qqa5OdIGwFI8g2O3+4rh7xZId22a*+>?o@d8W z*AJ28mPc${1u>t2quHizdqrNibjxni_illCOZq#Bngpd*3j79hz~@aI&x{tD@YKSjx(X4d<3S_NN^!C z7UbEf0?HfuYdexfc??vOg~A}~+yJMP^5fRQ%cL-w98K{9gd}DJ0#M?_rE{R`b#8Jj zrK+Az1jnyjEj#A^W<4r70I>zeiMn{Se|bhEd+pX4Q}HV-(45BrCVuK{T6SQUuReOd zl;PSmztnQ~AxsFAhkQg{o}iY(8&&Q=Sr;QF=}MZ4u7?;?==O)W&86R;7f-9iVA4JI z4^)nWt&u6cEOTPzx1*F=_SlE#Jy6{ixuxigQ9ip&hb}~{qfB@~sM*7znAPkDsh8-& zfml<5`*bg|F@9)mw&Q>jwq5?Ays~S3&zX+3_LK+rQufgmjfMAC^GKdDC6mzVbTI?L zum9Cn5KoDp_R|0*r4nM^V3L?pK*s`m?(B5GXM&oX#AieHzPd`++QI|$ohoQphJD;?Nm2|KZ+S4XvIHC(KTuI7DzbGd-~&II_qb#CpM zt&$0*LxGk?V{K_ScU?ZKx3o_VwVWP0>1%I#xODToKTHAaH?<_0Bthm17vd40Q|-g< zT82=Yh02%6d;$H^B==J(IyKCZ|P=SSHgy2yF|YB{HH{tO53k3vfSG4W+!-q{4cp83-n0L ziV|y;XUQUi=D~TV5!>=spl1qeOBh5CTliiPh6RX=maFIS6 zl%SCGX6jb@!3#~$_puMy=D+Pu6GMWBoX?eeOtj>ToX`kd$2IuSB!ISqBhR<(ybl^y z-(cixS3ARYivJY1OtHc+&dWXezxYikk|TB_wuUAmn%#_@fwn7bcYASY&2_fhHPz!o zc#*KVbPQ40U2FViWzS@nvcw+CE74LJ*{6Y z=uwJYY7ToZw(X&xO*PjpSV@@&hPwFzVJ>*H5pFg8N3YiG2m5b60>MHsIe6Xwa0&ZU z$wVq^EQr_bm`f0M&DXx(Sj=aUh{L;V^J8cVn5S8A5+4PZIswM^f_)itMr;eNBxz#H zq<1zfNDf<~J!y`$F`q;c?SAfGkI_f^5T4S^+Jao^UJ!MO2RLq2<6?5_di6Q%ON zC=aBtFDxTb6>G-g7MA z2^@hIDzrzA^Cqp(DthnY@4g3<1|>1bc*UBd!14oc$gZ9C(Ra(hNaci?%nEY8nT>u> zF^-<4n6)`P2|K1P&pN9hm^1izx2pyXhh~ABj4DC8bV6U>_sTF#4JvOh&wNvC6$l@3 zHF5O$y^ETb37|3R#=h-3TsUJN>Z--OV2bs^wtgKdhl|161GN{sK#&ZWs>^WkFEgK# zB|GDnyE!oiw2cm3LFE)`L*pq*$zI=b_;tFo#JD=ctF!P|POWG|DD z;B=Zcxswi59dzM`=%=6Yg;aTgUX@zTP})?`3Mpq<=9Go4DdQI;jFi&~10QLg6tKFH z=HS&5vQS1delM-p5>3JCs@Ow2XVLL!Y-CcJIF}oaBm&h^Dp@Q}Wv9q0tE{lrS~)%A zT1I50i)<{KJBi)3#S0h8N=at$!NH+3SXQ)0;qJl4OUs0`1Bfb!%bdk^Rle;46)TPJ z#P71zcGXU7X%o@W?7b|{+8SM=gtBrSe*!Jf025sD7gjH4*>4=AT0P%b%a`M6WqOPi z!K=V-d1*@Czn%t%uo=Z8srYr9s>^y!?|iQ4)-S0(nt%33X~zN1wcu>}FfaI(fMT>clQ6%XDJP#pJa|gx5_zREr-awknAn2FqZg5Sx{Gsc?B@RaFJERnzT4 zyWUiFiP0liY&UC&`T5L3vRXX9E+ypC26NrxKV4*G&NAg&3xk``jQw-+P-@& znO|mfL@m+mn`6s16ma7tqsB}u)-c*ei)pW8dZeh}5-OMKSp0-5WAKMt%)MBpCrefW zRJtrp>l%Af2{F@JSF_efGsya{;e~_&lB{%Q-GmHs%?xE&h^G${W}!GYP)cf^&!};~ zdzAQ)2LkI0QXoIT(_EaQ~0}QOuG7k<=w-rqdqL7*F)-PW+NWBRU>@w z!B*fS{(Q5OVNi2gW2eZRY;V46zt){3r?G+L6gutli{+2B#B?hq(PEY5xk(agbXp^W zyZQ-M7bYsubPkm9rTrYeYt1>HCH8#tQb^^A(eI=!-gZl1h4YWj zJZ+ zFM1g15?=1r_o<{Egn;CDkWoyIG5dLey;DSjLdCj&DZtS}b*y7)XHHD*Ilp2zSc6rn zj6dA7yhu`YJ?uvH!m&{s&+aKfjN$-deftu3O1SEsV~ntR{EYV?)IO2fDp-zH62t-+@fPtu zt4)Rn0W?;-0QBOzQW-O$0az^2H|3+j*954v7dJKGs7Fz7ke!?IV0@6k^$Z@Z2NBNN z8;=e$zvfbIWr$r53S!{>Yoe9a6`x%?8@8;R=R+kj)Y2)KzYOLah!g;a`(=r*%O20j zs;F}N4=0%ejIC^_50xE236@Q!ViZQg|EF?!WZM;UxCT=qJg8cl?cGV~Ne*%(vch(2 zj7N}Kue~B`)kzA_Dw7zE>3M&|KwnphH@bUL8lxC;n>*RaA*_TsNg7yOp5GzXMJoL) zat$Qs)W@?|yEf%ky2#kUYQ+6tr5O@d4qc(@XOK4{ln`|N1gf!TF$^t-YazEfCn)Re zyhZrJZnYdm+8%F6i16!HDpdh5n_KLL&J=I;9?U{u^V|3xrca(9edcLmM(EY1q|GCD z>aIyFhx*z*0W;DQ!FDBL5O;}^p_Xe=%@P*u(lKNUdYz%$?5;WKhNqKOo{-=DLD$8| z4j$Q${=_n?c=v=E$+=pUz_2K4pdp-UTjIRMI>e4^j>5qIWamL(sRfpWCJk4E+XeA@ zIx~6^&DWwIEu%D|8lyM-7j2@c>)`FFSWcEfi8?wGnuyb}R^^}Rz>e;(7HR?hkX`(5 zpE{Hn90;k<5(Ld!u?ia0{H%A%wv%M8?tT2hX|^1fKVZ`&HCcFHw|6B>d~3GQ)ni5^U7ysEqAkQsWB6JlO#-M z@@4dL1>er8nsq7Vq5NjB3JmY50C-GjAr~H!s+j>8y3n=TGP2`IjCb{c{!3x@dWpv& z1PDE$jI_s*;u=6wLqb&R$B)6Dq;K;R2w?~xe*u_;5tlJZHiQN)=d>1&0e~=mQd>?1 z6(1sb*CX=}JA_LxQQE<9gd1&{v+@~CBV&!MP|)G1xN0^QXHNBYlcrC|q@;=>EVzDl{19@$4pp|gTs_cGf69WQKHapw;}lsUZVU6Nh(kp{t;ide6DP7t`xm~Z%D7!vMTtu zd2dwFMKhcXjqO9ZZ4kd4(L`20l|Klc$~}9rB+oBksP*&y>q&j1q-`TJ(GGfwrE5dW zp(+?mHzP~l#7K4FcyN>5gNnlo?!Pe7`|_j~Bl8bzhv2-}?2Z~jwszfQIAlqZ-E00vdu4AoJ<>u9!4%Z{jgG>C?xPMO)A0Ev5F%-=E z?0o$osyWP*`WO5~^MQmDkN-j*^FvDusKB+TfY1%kSa9-OUe?*aN#jjz2iU{iESoJK z2{HuApjrBKF7?CwxMtDWw_|_ovsH0L)enR$@34Rv_(Kmk7%4*}%2QGq)&}d!>(*tm zD<~8j%)VY|IG_S5FKVKE4ynmpqeM#g9=YtuwGqhQnNm5^I>h2W(Ur|Zi)Z7{y7q3% zU0b&x_M>{mld!lLNXGM!m^m!W5Z@T~S4e8d?)OE-RrpoI%Qx~%N9FfzhU|%;H~Y2C zd{qENK)S!Qb=3aa>k?(dh0CRH6AVUUP}&1yS2~6tiM3@z^}?mArG-v3^ zJ5*O3;qWk4!n>3|GE~3d?7Ipp9PZv~$wTIy$~MB`+DqE3uUHB<+S3&3JhFG#>cUc1 zj0N@`qwsQ(f2G|;)4(pJ8R!s?lACoDI zk7>fmz`h9De26v_D`UlsCtesrq-^X*=B{Te99RB}64$?mxwRLV>{}EQ?KTS*P^@yR zkq{dgv%ulL^gh2|%D-|_8n&)}G`8_-;Pxws*<%FIr}x-NZJ1p~JFniRdZuV`qr}*# z0^17qGNJMaQ<(iUe}q!-SB9#Ap@Z1x#!%f$ z?9h^x6(t0lJ~?UB z5&3amHwz&S>J*KN;5ZTit|hZeC=1U|vf)Kjtt*#HbRG52?ZGH}e7Jh7I+{WMp7~=w zxG~MF`51_XIt8Mg?U;4iafER+p|}!`Nh?;+;VwpyWN)3dsU%!-X8a;(U2={_hig># z8V}IQFVz*dKN@8!k2V>sd=d%&7v7fy1$Y>?h&9avlj}Y}diz0wc6w-$0N3_pF&+qW z9FO$q1(}EU6Ed%5AaL)|KF%4qZjH%)P3hFNait%3c-7;lTOQkDc!A}gNa}h6pim$@J4VqRsuAOPlZ~RL-u`%3ga7CTF)+LD_EeYFTrU$FbpTMNr&<6~hwh zzjF^?p!%_QsvVE&&kb>A+YNe%09KzT{=W4Kg;pzT59MH92|PKm(h5j#zScYl^O;TMSq7VD82%3qq9wi;V)C~7SR zBvRA~%lvF-vFgyA)|3_09oMo5X;q_^-Mh=P&YOnik_PWov43j9rq|kn>h{Yeh?8om zz$u=f((hgv7c1(M$T1)m13AXdm&-0QoI4}dVfsHsa3^$qkJm z)&|qDtOds}u1rrD8g@^OopG#!lO_`D$EXZ;zcuk_Ia^}yJMS_LJ5Na2lms)Vc6fmk zjH%#?i)ZQdVhWm4aKxUzLNHu)rKnq5AV94A@^HUp(7awCTA^-+IatAoVILNR*UUww z$4gMfLjAhy@(&h+mLZ*@A$$k%kb+;Jwc<2F!Hejj3x6LHfQN2`Yx(02p;=+rNwL;w zE9>SbRX>mXjzr3mES3I!>mX`On;;QVQRk=WB%n&MHa?LFzrn8q;{_kxWa4qZjSqzb z0@z+W8e5dapb~I!7z>6Y!2MsOj)x*Zh9ru`4Quac-&($0_V>%51 zYkXYZ_5=hXCK48OCkqn8^ySE$=tGz~E1N^mXM&gQ>~=zrO-C)%a^8iIrF&I<@xhxk z&!7D%T(tM?V@r2F#6$vwl2LOop@ii$ilbYJ>C-J`N5yc`@&0=jln+O-_KI?6x?#4g zMQVB$RD_@^ZDag~you@(oXv0K-aBI7slQ$B?pj)1{Kcyit>hC?I?$u$oL<8XZ8HWBb>Kx# zAkeX>0=NQ6&GSFA%Ox!8$)iCHnXU73r{@EZAmpzKHN zPT3T254=T!%6op^8Tefn8^y~Jdvw$CLHC1qIs<{>GlO|@g1_4=u_-?CmYhLiKi@N#}*jNF_ia??=vyl6#ttb7?)lUI`HghjN$x|4FcJ7E`~oO7bSs2Bva=?jlR|VNtFe2PdoSgtR!>6c{U^}Gk!l+45Y?BgZO7|)lnU` zfdJ`1v*ydQC2lC5j^{sw;^sF}Iki7PdFrebAtu6$SO3LBpa;g!-MuP}t?+a5V-pi2 zrezwJO`S#@43Sg7~&X-C6qNvUVJMDOG z09z169{{$n+dAkQ%p0}6bzp!vWqFGgko4(U?zJTza=Wh)zVikvOyM@H_w_QdySke_ zcE9@q)!XO}(s=7;dswUvKj4;KHVK#~e4(lt9?sx~?TW2|2|QgRZ$J?&H^ zRQVZjUIdLy_s9k0(fOEi)YH4skREppO5^aQpAU1p1(KLcFQwrpr+krq$*?36;4Zza&^ zQP9$;Fo#q70o~Qb;S1**ek@=~nrtzPq*j>!QXL#`>l0~Ihsr{l1Z?=Ap3)fA1hcsT zE@6|^FAY;L?=`PQWXkg|Pt+~#{0Zo{XdjRk?W;D^J?QSE@WUq&D>iNlg*tKIjE z7hvd=n`*52wH5Z{nW1zb8uNdLN%oaU@o-01_eQfx53guPmS9MU5++iTjoYM--LRyE zPA13Llhl+HL8SalPqZ`>0W|U3%t8&%-1wzF4t^T`QI~4smik1&8L_U!1dqrRsVJ7M z=DI!q7Sx7LM>PTN*aOKZvbKkDysJ$I6xBOy#EcEEs)iF@;H`hcHZQ3#e29VAE1j3O zu!)I2cW)i*#i$~z_TmML6$pRneC4ipxX+B7`mZo3s$UEeP`la!2!R!OENgLfL%UP? zbQVzrE&C$~T7!!@wc`b6Ot^`d^dubASog}G!ygtYr_9YEdv40j*h0tcU+~T*qojdiDoFqf1CQy^c@Io{dB# z>Y}st7pMZevtX{4b=Rn}T)9O@n1bJ+?J^a(I_wRwm%18d|H!bi;*NQ7hz+q__Xd_H zxE`?vH?e8}iIiku5LD_7F5!Z{D$+-TG+*EQd}DvoBgX^rkw7mT;3@)E+Dd#k`Px`u zaoB5jRq)#WzF@ipfDKXqH}Bu%vjzR{58^IDAzzvh(>fR%3ybMP$k+Lb-Hmtm_dmg) zwFb(YfHAX?Sxo~l-lKvV-2wRl4fkEDxI;DZADJ>v>t7Z-dfaK%E%}c=pGrLZYL_k* zf^P3oLNL7|1(PZZ)rX(Q3F2m&&bw%Opf}I?SQyV-W=C}`$3zfD8*!%!_1!;cWE9`f z6XscKzzHAVQ2B%e|NNP6hp&74&%*fiK#cV@y(lld{6I*g zOP(LYN|Cqju%|L;chaq$h5MHf#4>2dG1a-p*DXGY_t$ z3O6iFYR;-O?7~Z={CIM@8shUe8yU61E8s2NJLS}fFieO?Qovc~N}58Szi2Idg@tap z4QSRKns+t`0-KExw(=gsi2uu#R;aoKO{JdCbW)BGPC}3`J&8F|{hzbsZsOw;`?AjF zq#anuMgw`RrH<((HNRNwx7ghc7%L6h(``I+fVXA<}8e2Q!Zgxqq*p9`C`j; zKTD~T8ddn%a56U9w;+{sIH5j*c{lWfvHvG@+QPfzat4dfTpSvLWdz8CgIl?{^KKdb zB9@^P8}BUW@_;yVs;~ul)*jngj2$HH0H+SQS|C}QaV$24cio_=;2&`IbWFMTn9me> z0nO-woS3LgZHbOYo@&VrI&tSJRdwnDEX8}LAF;IXU2&SurQ4a+8r$H|mrO<~!Bm3n zTOs*SiHHPnJ?h!%gS2RzAndtoMQY%9&d*&uD0I5%y4DZE)DB|5dMxl4Ox{Uyyss!<*%ho-wF0NMW|UMTi|dw z^pI&Lgc8X4ld@n1izfJd>oV7TE4Wu{JK}Oq#i~oS#VSw!A%+meELx@95(?AOPX-3X z<8S1xWj@ss{a}GnEbx}7pRc>jaCfcm6aL_W!#&d;`1Aso9$UgQ!!Z~Vie|YlP}a~- zxx(d@9J6Qdm5t%fJml4y0$=peVmnH@HP!(qii+u!C>x_VQ|=}ME+fhIuK0YJ{75W* z?~!$9RelLogR98>6_UC!(K?2=>2|;WqZ`Lr{!G8odTXd(VaSD?dRaECk|@eU_iX;# z-`1wjQ*O;qB{(V2HtuHO3QC$&*~ZFY#jM4(KQt=&3!Gx@kzyVKSgPDXe#B#KguL8t z&Pq|dO2*SXG8KREr;qt^X@-1ThxR_;KV`{bF}e*G^ulslgu{$J52P0(_T{+v8?F+G z-74}Mnu{v-u=5DwL4?r*-~wB2gOwy%_{nrOsunzUS&k~1Z&7iX-1N^rsU=8P(SIRL z!xk#iLM`V3(1`+S>3#aZGPVrgMx$j6(tb4gK^0q48oo=RVeivW_iVWQ)_;bpVN^Px zWKG#trLCwV70g!=&0(JE*<;QM(IYw?_y5|y{q5E1N2wHhzuA~GMCKfoi`gYvQ9mA_ zHD~owPFX{<$|&-NC5d6`R2(j_`b9&H+7+&B-&w5zBRC0U|2gv+sSI0?7QjPWi{Km6 zI~T>;-@P`;b}J*x_Lj<>WnXC@)OLGn-LvAXI?cD=iWhDMn{SyEY6J{l{6190rjF%--NaDJ z{1gI2Wvi5=Kug&C$ktL*CouXEG6X2Fr5M%s!&7SZ@>q7^!h-*PD}%@j@4AG+Gfi-u7T05PGUGgCw#l|ZfcL(sB%y{pGq?m#Q># zvbRvp3Mx>-V7PH#T?h4>6_Njjs83WR>+F=+VU4-c9nCXCN=$<5nE`6G%K*hXsQ31L2A@sE+qTMlZhGSgM} ziu5B}-enR*#J~*S)Kg+aEJCxskJE3B*G+mhxfbl7{Y(*!dQwItFWnRZ!^hR0tz*3) zXZ(77wzqd1tv7VjO3irm78!yKH7EPSH0p48E*NN5kjgBVF%xNbGrXGNuoKi%D@;b1 zRe2{T#E)-D6{VaKb&+=4RM7Es3{i(Xig_v)I@-$&MDz4s42>pK>a+IAt>*(9ax0OO z`(;Aks)q+Zuk0WatT+9BfwkG0D)QEIcFJCETbmJ+X4d%H;_YWxhiUypk2QCu`2=ul zqatS`UYl={TqIc^`m4qM#zz6D;a=Qu)V0J;!%&De(#T$2yO}?)Kc@h}=8;EZp9mNF z0Z^}SHED|KUF{~FIvO<=xGMP$l81?u(Vn~-!1T3(SQ(-Qw+z1c%>+0G zE7_@JKd=-sT|Yf?sD>W24;ob&GV4__WjK>J;w$~{CZcd3mVQcs6wwH5vSi3H~>e=l5sa|QQ zsJ*heE6%7$Pn9-y6OovY^*`VY{t{1wg;pmDHRcl!Nf? zY@vnEoVQT-w8xKu9;6I!TIGPq;k4`eafa{v~3=-THmX9PR#AGI4Sg z0+dMN)aZ#3gxv^ck|1^XCj^g6e-fia_7_=QAi~MSr@$jpV5$Cr8|Ya`baBOSmxLhs zU=kmpUl%FQqWZrUx74c?GfAqj+0oEjsraI0I<0~a>O#}tQX#Iel2|KMt%+h7=fw6P z0F$MZT9_U*{(uo~_oL!K|J>Y0!C;+M zCyzwb-t&V8LPZxAWSGmWAS<8NMOA(moV138npw{QqDejjO}DLWxH*$cqRH%-OK2g% zTBy^;Y|fnHqvFR)ol;}O6w!D_XlB3)GEQZjh+#!p87ZYPj(gk{s-&V`z_@v6Gh{@$ zP1`v9G>Cy%gsENyW5Ian799^wrBa?|6kC&BIsvdtVm9DZMu?YtCu@J^?4hqmA%>KR z_cj-(T5(U?BL?#yFH*^)1{gW^Z}l7QKj+A_YjB*&cbZ9Lgfez$@Sk=i-mScblzDJR&ZleWJg{moR+o_qn#G*^Rt2bTEeP zps&4tJ4Fe@p!R%i_LLfP)gE?dn~{TP2<$CMBLy!~19Z+t5pHJ*+XuJO zKKYHY8@aC&oOplw8zbgIz6QnvL_x|Hlk+=uJVgWK%g zcqoCZj#RSB!Ls3@AN zC>9ec+L8r%MYCS*sf;OqL~s+hG2!(}haykwA{Ozexg$ur^k0<=l>1&268Gljxns8{ z@9V3uz2ws$zmR_@hcQuQ;W&@0#NFNKUU<2@I)=Aq(1t9AJ;x7Zw(K8;CKBjHbI&y0 z-Bs;Mg{nw9215R=fRfh{!|6&0HZcoum^^`U9G2jQ*ztrf7@UY%zXACD4Y@`PQUraV z`a^tT_;_hJXLPJ+z&s`Ti{rO`XMVSK{)D(j@`%a14$f_E$g_1bqw@E+FF&Sn%c%mD zK`YB=tHop0Cb4z<=oQ*Dv|JLcJ1U`5l70WP88Oon`^TFKQsF=@}@f;iDp)v z?-oEpG!W3x3<=!TCW*hEOb0~kyK8r=r1k%=VJwGy?T>iY6agz~W4qM;jvrwR$=hZx zy?S~;YiqXa(7Xq0q<&T0(4^eSjdFKn`?>Pq93f(Oas1i|fj6S@L%GC^fdvB4sE>OS zPQwq$-~4)lt9j_qp0C=GA_P^ZDA!d7G`%{}DixIG61MR9Aw0>6*p zGA^m-q03f0*m&H8U_(bU=~UcZNt8@Ld`S`>7JMO+wedlW{JrGP7ZO|SI)|MgP8Q8rZ2}Fwhj*MeYORW2Cz)XxmE-!ig=3yk#JydRkm*nb0F*U{-N))C1*eO|rGMa2(q8xGZK%>=r{rOTPE zj;S~9_|a&8ZR+r_lgur_US*y&(DGW#9&_8kMYTR^dkraETGsCzBfk&w`&yP;&xKUw z?ilacJhvkhPE4pCbmclPIF z*HHdA24Jzjm?fb~zMPK3bNUkcJnW^kFGN3)u;INjOE#}Aj%Ql~C7PWB2#Jp<>ZD!2 zG7hh$R%T2wCjVpSz9v*;G^3C5avG&Q{1NhWw(w_e8)CfOdO-TtoY#73@!IY7ef+(h z1w&m2Jz-o-LlI-1qW8hH-$qeB$uow^>zn9e8R}6uFF=P>^~xQs|G)^zt~{4(B%hSf zMdhwbWr+eF01%Th=B1Z4c$ULMMK+#E`q?OoFk=AIs=wqpBz;Lg@@KzK!dCNT6u+;X zjICxl7+Jler)yc>RDfeyA^qtt2+&Wb9S*uoUumDL&g&W(>2a4TEA90yj+@Biw_saj zQb{A;UrX%?A)+3#FdGJUQ5La1XKYH;j@sMj%4FXRZytrq6YAE+Y5wBpV_RPb>)N`7 zgWmT3HN?xcvoGA-Fm;7Wo}6T@_Xs!U&mBCJ)fFm8&JM2?n)tvqOi;N0(syng(+jfA zXLO}tTCQBlo0zW`%#g_Ha0N*!fUuZnT0E|ntkF`eh5pv4{B)C+i-`C7iIQF0k~3xE z!LTxQOxGJGPPh8bAvrlWadA@+qZ&;nWC)@t0Q@iJ0L@@G+Aqwp>;p6%_NH$Ce%<9p zuk6FG!w0kB4jSM27*GOZ?sHZR7{{dBRmg)cVWb#t=Jo1neLgCtU=% z`*|t_2&Dx{pCPR*%bYeW2um8fA~C&m8ee=P?J0hkK@@kD`VBXV_FXCN1vX7A<17q68h@p7h%hck+RyGn1<13$QbC6@!QJFB{JdHBpX;YAYt#GK>6Ab+lH zQ#{~r6r5hBmmXf0GS_HyW(|VBdC?)5kEk)^Iu8yFqW(`sYtks8GHqT3MAqyegUU-?%0cJ=G1;Ttz{rmYecR?wq0?&MZVG@x7#?YPZ59 zDJ}{%J#b$`*A$w)amOPi70}qgon~P-amG{}TirVK_j)v!b)o2$t#p`1ToeAZ`;~sy z%6`}TOHKrC-8lqdPk&z$V!;Q=u(Uq=gb0*}?G?>GB89ucLb>%=lzlWyVN8UC&YWM% z8N1M|uexVYbJ@6U>m;&PXyy4=JLh^;%TsMSz2x+O?Hu7}H?hx^AZD{1;rxY%JkY%~^yt{b*4oE-0)h_VZIY^+t z`F(TrJVbKdv8w%~Hw($gi~%idCv{(*(i907TmrrCXUw(ieh)%>xB|2nm7Ki`6Oh-Y zKtzeuF3PnaC>VlQ4kGxpnOzL8$9sDUJS)JqryyD&(h{QUM}%1`SnB|md<;CZja~)k z6x+RA&p>QAE@bHi;cZ}i zf)YkynUT{!=IBa2^_NK;CGwRtsfPt_lPb(GU2AtcGE+PWjDkr$qaI*P43XMNNIneV8o0l*r$M9whi>OfF) z;SNuSm>Q!b02o!d0cyk6i0DC@fIM;vfRLsf<@YQ&KibD>`Q2%cNnBt_?@A!xQM_Lb z;7GkPB(g8lzFbG-2M{Ajil}`J4;RCW4j(Imn>HY%$y8CX_(9!Hg@OTS!Ghm|EG{o^ zvRW>v$3r0YlU=qF5!B_NuYgr8CJ}&*1yG^^n7Z_UDUgZT&{w`VbahSSfK$#C83G|s zWzYvAUqvT};?oB7Dv*|*PP3t?h@VhJB@jKXlORju)_U@j$=SkH%7_2|wG?l#Dp89l z1j2yLV+e>}y2^j}=*5eY7(lCPsAGAV^52aylt8i_fAX!fsl=2)F=j@6EzIn(_pbfU zSvunv>ld(awE(*k73R0a^H{yXJg+c6&YHUO)n`m}hCXyrWXTJYXsaIVsVS%n#nmL^ z400ta+cCqNmg5^|CbyDG+O1YJ8<0FR&kR0OabM5MCRfrl!(MtV&2Co#`UV5zI_t!p z8PV3upf5l-luIgu+xHd=&ocBzgE2gGr#3gxM(q*6C}}Q})0w7m0n6#_V*qw~d3#rk zdm;)ZK?(wvhfWG=1R$iOSa-C^w7$!(31HUkjvjHfm65WALgi4gi=i<4Sa-BIpk4V@ zym0$QXWJn{*mCm$0*&52{XNPGAPN3AB6VjMI1vDpvoZ_^GdrtAc}UPc&l?`YfC3(m zq{AC3ZUY=RwbYH)IA6W&T;~EHq?+}6$K``Xd$d+>ep}~^WpWGd*5rtfb$1*Ny`iAI z&|})Vg1dKPOjzgqew&XO>n)h1>bbX(S$jJfw6FU%Cs-s_bZbjN6(uFre%8e-b-wg7 zV6@W9XpvV?rw0eOGhFZ({m0&UV{f7dJ7yfyy=L)3s^y)I{6imcoyYT;kFg-ycpt90 zJ8#qmyQ#iBH{S|f`^-1qaq8M$#;I>s0Y9#$ju<~$SWOd;TN-xv_bj4Xo$tt74!1C` z%La2mR~fFszFcSU<6h%t01IQw!cK`@n#1U(qJ6wux0`xr76!s*rvu>rlXjIkgK>j7 z5uXQbn>4#+>9zUt@=Dpf+Jn&1dtH(C2*tTD7xbRYIo7&@CK(iJ7S%Y1b0)7KU=Xi= zIaWLhJ*QvvoWfK-8aB_94?R~~N4mJ?>bDiYJAVG`jTbJWqHF$r@ah`i*cUf!#uiPQBbMP2 z$U($R3b{@j7${VQJ4!a{hdqWNVAeqk_83Eb1eshxZn*)7*(#BL+r7OH)-9}4Fs7Xj z@habcF4?XDcO9@8yJPBa3>eB6SuE5NdgJ3+j0FjVcqAVKRa4Ix zaz+veEB2Y!%J=+HIR<1;J`F`i6k`>x;L};w$6{i!yN`IiwkC69?NZ zTA3iUg6nGcq3&mAu6W(xT|VibU5Q@A;2`}Z zI~=rU6}nK1(UYNu1MP-L*ilGZ0ey3Jx0bJ3Lk)culWQ?)yV%8;_L8hx701XANFN?l zZ7NdcKvIwqJt~g~VHb4AVHfx7>6Kt~|0G+=0SW=8egD-*$Cp1iB%c4#`ELSgK-I5K zom+2}kHj@vr;2;5xs$j-eLO?Xc*TAdH2SXUK;e<-CO4@lqS-P{EVZ;^L;Cb)l%35LXTZVG<96qSKur(q9wqSFnYBJ#xDQl z+`xhgf3{J;UJJTqse@^uBsQGrA5!UPQbu#Q9T(F8pX5auY4$*4F~51DQhP4Jv&X#J zhmoG^ynFkI5wm*SHKWG%%>7(qh8*t}yAP|uG*W5*z}T z{*RLd+FNO?!&{9Z8Kta_ivjw0&&jY;&{L4H3|lAkiIuT@6Bv|lKyZ6QiZS(tg75rl1Nk)}9%p(WNl&|s;tRJX@~tT%qg(OLv7Bjh5Eh;ac}i?EN&#q}W~T<%)QHH& z03ud#F2ePR?=bGl>D3v`jg`3@88gmlHhT~@dA;^Pb2c$-jZfGaI@&Nqb8=U)hd zbBKA6t@`ufZuU9wZv7oTH}Cdw6Ut7AyInBD)outG%|4SL!9-#qu=R|<^QcWIW;w~F z8=?{)CIH14%uvxyE2Cq$XN2+)1F?3FW_`E3?6C_rdtf%)KHz0xd~ICyu(k(o4~G=b zh6Wa&=`xWCY=Y1#pnM9KISECkf$$*MSJO~rGAv*v0$v37?Wvpzps)?GLOdU0OrnY| z5(v1e4_`L1tU`K|r99K9KeGyIXk<+AoEg0Ev73Z-PMw|mld|{W%0Wz%dc%=Tn?6ZOjaT&ac9c4 zHVy367+KEH%iW-XqwI=uqYF5~nur0|c9wgW$!-}I!-@6p3I$gv2rUb>t&N1f6sX?v zu@V!+X_32dfl61T{HYS0| z#wU~aEjcpQZaG-iuK9btKlz*2EP#hKNu}lr119wh^7Bj1^I7z5Wbqc>u@2mZHNbLn zI8r9>E1LHC^+cAVIy`Vmyf=@6qvY)sUjle;MX`E$w+}Mz^oF)1m2FDuDZX!DbU5U;XaBUYktQYqdD8tZ1$73KH=OO5ym?{ii?*UBU@V) zaiC0&NN~$@9EqG^P^%g8^|sJY0vzqAA7k;{Giv>o;D|Weq5P`=#l}n-^hp8i!wM@RQWup+xJ7XSkZ zaj4CWLzPSrRCeThR^y+BU$teb8vheY%dgf&+YXlkRtFws%Oi|505A?DW`!;!oanor zJLWb~MRb-eYqcxAd`_rW0?bjvuQ72bjetPP0yP7C6o*vOfV)-aPRB>%#E;#xf`L1r z{(<3OoN>uMS)2I z+skBbYi!BtEn&*v^>#zcEZfDw|eDcYOKOl{8uUQ*`fO)FrR7!(TtINZC@LNcu*X zGABl7PX>{YSp`o9Whtr15m>pAxELQw zcF}Pedh4JtnTQLg)sLstS$Hq@N6?F(M7TEa=dpk?l{dc>fu*bwi>0Pzj+v2hm7Iyp zNVpQIFu=iZ_=%h&PkGHIThB^5R`#8r1zvu8@Xb5SSOCAjp9EFkzc_%u?w&zud6>>m z*Le)F-(b1HD(x>rcpHHv#jaQCo0n}LbWTFWV}rDtU){yzEvFPO&%-=07!}6|O(@R0 zSq#$(OddVvTkqtY0QX&&en?r=+6#FCOT}BWF0$)~Bb3chwnZ z@5OiPkXBfLnD6#>!=j@Gi!UXh6jv4@*mFQq0It#J8eD(th zquE6{8Ni>M9NVX`(x&8E!r4y}ssBNtlH;<=DJfmn(8ryJ|NcF;m1VgsMcrkM#2=SH zp?}f0?c8^0^$)*|ZX6p6;Gd)b`UuJ)&X%FW`|uX9Ta+>dMk-UmY;@QMe9 ztKOb>fDd9Wtf>DHTwp>KBr9rSMbYxK@ESJ5_oysGaFwJ?2@^l^#y5TQ;hCJ?hEQN+ zdXTja5c3e&3gU5s<{PWC$(6l+ee40FC5;Q;eVh%*IrQy6aX>96b>~k}lMl=TSarUE zER=-s_ekt-TiuS82Zek|e|W@ZbZ;^M0|o{8^;g%fsa{=W4Tr=$vyrxj1muspzln)M zaUz695+-ZnuRddJ)>ex+PBH~vp&=T6)bKDAvWP5+3$wrL>^?KP5_bRNju@x;ee#xK z*NsG@Tlyr4ZN^c_EY)}=FC_HWE5?Vb-zdUI*RX&vM6+q}PkZBPi>gE4Gz4Y;&~su; zu6_99w`fsulGe28xLtW@31a!Z=KK}YhVGi%b<1^ACWN)qhbZsu;=|+cgtt!cnA-UJ z$r|mdJm3!0|DHy2N4+B45Z+LU63z2PbW4ZyM{{eD2jxGO}$T z5Ch$5g0#NJEY<{T5J8o|`m;%0+TUr~OAP=W%uov!J%=;w8?;@Xp^ySAe-}&9H*3$( z$5?-VlAHJm*DM2wunFS8dg1`TRx2^7K+8>+M>v2?O+}g&6LxV_DZk!d5CjN=0{j+M ztk~XoWc8&>)8j`R!j6y2S&uYsPs>uNaK8}#G(dmbtcIgR0+}Q!If@FRx~AQ(nV?Tx zTYK+J(tMZeOOKde*Nqr$QoBdea?R0Mh1Jz|7E8*KX$|K2M>P&dQKkmerS$fSq&zFs z(Bfuev)tuz!taF#*BT96LwUR9JTr85QcYC_a@S%_J+1867UF@qy|GB;9d9h205AGKGF-35U}~WwfIMSUkd_OGwV)wpK1ryyb9Ky98e4 zU4gvx$L5ny(+ZkY7j@ySs{LeivQ1sgm~RvshO#q(>LDyhERF&&$9_A-9%^8(x>?l) z=w`eo$<@`XZq)g%WuN^<@&<}p7RlR44{9r&qehMK8)A}eqH*V%`c0?!$>p-f)Q(TB zL1>ZZEI^$g(*hvV-~^>&I~`V^3$^-Q+s>b!&&G%h;VT>yGEk1yn=YmNrhTj}^{ zZ0a)@b}zPVWKLr=4_-~JwP@RzK}c)?ncY?Cp;;5!wQB(a&I?Q4fTvaJr=?gYrre#! z;miav2&JmeS;RhCn5hLi)JznibRl{mZdKy`E!A&g^2I|8! zLu+&9LbH;padZx&1xzI5;C(XT9B8)o(qVGSzvS|Tb6u4tG0v%G$=T#;8a{rRd`Myo7P|-Z{I-3mjJqxsB7mFe5B0DSmLFw)eysvw?_vQDyFs8DSLnjhgs%VJ2ugYsU?)9RP-sRO@ zoJwfsODGju{<4{u`DDVTa{2AD49)dqVlrzY_m+vU@I`lto*4s{!q`9H#lY}0Xc#@4 z4wzsZL?HX-8Gt0Ik&&(RTm*uZ2{d!jVBs~G6??XKb=5pzhXcVOtQGK{0nwal*D6F8 zs)K2~N`s3l{ibdL^_*iff%rc)z|8}@(&XjE&|cN~O8ZxqUkNUO52__D0&zqvSIMtT zVRjwU-k%fV(_^_#1Q$UVXLT9;QgF9U+RvsZ>4+^e5gp%t#&aF>S{X3UVpf(+siDc1 zNZF|{Zd$1nVQdy%#geD6(9?}h!pJx9mWKE%R2kKQ(4r!AmUjI~!!fa~4O(It%E8ZX zt0{0pFgE#a#Ue=~d;V??`txSVpphSqE%C|n5pkPbxE3r%|5#6V&pHb})4P7+)^kPC z&Wbg^UzG_#0gx%tIO4GQjN$Uu>wC7u_|TK^07F2$zh`~3*l|EySlF}Qi7FE&67&iM z#a{Biz}^GpH|K+_IyW6zHXq|)7Ekpav^OIK>61NP+mQqFs5GOhb`of>Qa8V`|JWdK zoUnATSJ*UC9n}=4=q1zWgIS&in>)9vN&3z$U8?{7T^G?{eaZEyNtC17#EF|x!gaJ) z8u>X+T9%sMQD4^Xk%PjRF^^M0wXv`4V(j<^L}KT>%Kx&l?Sh)ef}%DC^6kqQ1r6-T_RGga@z;2varE zl06!G00@8q90Rzwbuc#3VV+%ZE~QiV7gVu`L6P|^D}Eqtf3i8z6?CTJO?Z0}J+hqo z7CB`R&n2XpVA^4wIKx4AFYm_Xlf}ap_TJOVzGwtp{ZlH-o;>XmHSI3>jP7ohAfktq z!bAkj^=5cW%AKU8Wo9s}Od12ABkyk>vMt(TGuvYx_;hIq_)*;K=XaOqWNK+3MroKED6| z4F5Too4a@L>ZM)%_4I;G{q^d38MtOG5e7OuGd()u9n_9suwQFbO@hKJ#ine3zON=G z&FMU5)4w6*LGw0c+>~HNjohzAD$@1)~7Imt6?mYjaX zMk|2qWFH_$6NlEk4CD^{ow}+eJjz;A<=D4D3{)%?GUCqIT>ds4t zWHwgco>sx0E07on9wlTMV0`%!`7=aXRFdME5SXEVNtWc9J*(rSNxV1CHLjOMs~B7_ ze0>WPOb!EJ@<>^}x;g5(AK-`x=H>l57r4?GXHS%CCmru-|3amDL1}@}+n7{2R_eblWTjV3OwJ8q#3T&I4MFeCHU?`<6*R)21X1f#c4^loE&3i!VGj;= z*j5Rwt1W?OFvmua6C=q8?una~$L$W4$N;kg$b`_sxXjV`qlij03u2T2V&g8h82_N! z-AR(59E#n}`_eV~8h+fkg4|j&>W8YxXbl+c;(hVh7&9bEotWY|bhO?d-e0p2N<6av z-Id-0lF)^rt{r+T#}ysk(~;rMrFIJkB)wPO%}b6Pva8!ab|2Rm`M9MWT~}H=b?eKW z9V<@-t3Rc8kbGa_Dz&D^#A?zFW1daCA zED~`{0y|WHw;syF%Y96JV`J&ou2RW;GI-O3NoY;{a@T8}v2x7`iRYxprJBM()gEnM zF>pgNUNzp10%=h;VBU&$#R=x5vTXtS(BYtDY3 z1jMA^G0oFG=Jng&`JaR1eMUY13^qd~2!dA8YgZ|yt^*!Pjvo18!Czw8UKPavR0^J0 z8`Z%$7BhYRJGS!S2jA~A;H%^*q2 zA}I^S)bVm74xsT`bemGl{ww_+I|~w(Ve0FVqzsfY=?l9r6a+o>byp_&i$4eVqZ}&_ zQ=7s(3(CrcMI+n005~)Dtd>mzjW-5_FTq>oyt);e{=q~3pOWweXZ~+oO_eKertX zjnZqlfgf5L10}y9LwFVpWKAx_ER>yy_n2b8_&zLd3(ZBqUO9VIx@3Esroj-G5hfEJ zz7yu`j9ervQW55{*&<%stVt5YcELlFO7?l9p*9`hL_W;?gX;15|I6vIG`hy`oM`az z*#D}$A29y49_W&pF5n;UvEH3NmB=z(*MAcKAOe53A7UP%WYl_UzYM_3AwJGzn3?FI z+2h}03H5ITvs(2eHa&}EUq}i6aJvjI?iD4i$^-H4-mBZ=Ga)iW^Ady?8W3htN?6e%VykcxCja~@4Z?LCsMWWBP;G(vb1m3VV=7~#^$ zFN?hmYykN>3XZz5;IjF^QVz}oEk@?I{9{H~E7}rf!e-OLZ2@qPY=8U8sCoQ!Gwyg> zJZrh<@DtHfMYQvR(H(+H*xO7=zw7-mL4qg;%5HzUabpLGo?F;|5@Bw`HXc_qI0`7vycDb{NZkZtB~YPxO~~_DQP7(!XkB96yaDQO~Es~s--iPly}7k zMjlHZ`;+@WC)f-|pWC`;#*=sAHO0exrBx= z5A8re!#+Sf`gxkVL4W@hohE=z8B}X>&G$%?Yn5ppKg%49%Ni>(U5;ijd)3e{kFEfu3YlQx>eU57z!T2@oBg%8B``6Y*1m%u zIo4K!h09lVSo$65>pgVzrRus10^dspJ~G@U4R{Q4I)7n(ij)owhD&Sfq={FrnDq@x zxw6lzua(KJUmej~i2$`iH#R#vAv>}K`8O}TSMKO+^GB@pofTk@+bZukHM65Mzt6y& zxdv3NNs&pa<^n@Oz06-;f#yrmmC{+adM98;7?RQ5R-UU-JNr}j4pmWG zgoK#6&^W-~uW(&rLib=(gp?q?*n!d;_PRpq-qza$#CfgsiNbupKiKoYp)E8#)h)+A zoAU&p4Hdn5?xy?ayz02`N~^JyXbUdvcCc`a^F&Dq2Y!B|Vm*=SrOVq&CsdtCy7-BB z%n2gXQcQ*>I*8MtK7DmxP}^c+zTU4JsH{V>gO z>?`i>BFLnbPLotWM+F~8oE#WZV-!-wE--R9SD@CKnvzLPQx}PmZ&$o9W&-^?Rs0V9 zN^dHth8?cov9PCBvA$~6fyM>mqEtx%l^Uf)yE1p0fH@{ZHF%nf2Lvy}>&CHQsW2&{ zB9P35NXPPIwuBIwoItgDXXJE=9^#+qR*@VP!%dg6!|CCYV1|>a)+1vj#cvlDiH*$1 zS!KE?yU-t)5?De@23Y*g=7N!oQ%z1HN6K9yb*(Ax0szQ`J|W##5UNf%*r9E2hKuGA zsi-3J)rKLMS`S;^PMOh^!-%gkrM`k5Lvu~?qtg5zB6mC)B#rI3@4LBWS)@`yPS$4{ zJ6L4LA&AHgWny$MzyEC&7E{2oLXd58A&;5d=e~lotEbocfjo?We)%0EQp|AyV8%>d z3XPdGjwQ4qIniOza@aMOn;3V4{jylUtCbie66~>ZK-Ad?trla1$vFz=^6}qM&IV-l zsK_`K+lPp9gDbeUlj)G_5P9Sk13t70O^CwiIbYPM&7(drO!%lWOf}*JxdzE#404ePmOF=v5mKy0+GKO3%d^FX zVXfO8J>oG<+Myw5PSh#_fOqnOmsdgF5cuD5LW(nu2{Yr|Y2-hzEOao_)luJ+DS7H( zC*2i^rZZeGp3hcU68kW12GGy!%6cyddL6J4(|+Pa7bX-M4jU15b`r3;!1g|LP6KNq znhjEG5T==c-m$I5J&pbK5eTnNvn!dbR{Ul>Imr%YQ(>jji~Ce*o_kChk<}11=alaf zS9hc<`_q!L>I;vX7Uds|Zca&Q4Cqj5MH>X}ziO!`DGHcP{Lqa%+lMx+ZrarTKHrlY z{jiK%Nljvflc=J2d8wRh$eKbhVR@J1|8Mwhsw5oNZFEV!8(D)^HU#eW(MHA|e8zhg z>Ak+b_8_M~dmySYCAmJJU6GeCE^t5V=Q%D@K$)>iu1(Jju3Oo#q4jN^2RHiHQf?(h z!3raS4snSkGEQ0M28V3?*go8Hfavflj6ARX0e|{?BrYPmYt=bm)6*_xXB1|yo}8JD zZ-U9S7p9Ubi%XmmQX<>4J?Z4_#n-l~sE2M0;>u5+)ZwfQ2q`t_cIDWaqw~u4G~B4G zx$~cbo?M-*CpcL}Q@RPmC%^AL;e@B$nz{+p0Lzh68y3s@y8=ZcXP{W!-1BbB{=kMN z;hF{l8UE4X?$`spY{RZ@LRFRJt0cE609CvMck&o#M?jYYpoky$uKPR(@Po^=h$;h6 zhMkjN!+}YS!Jx6?L|w#s;jZt}&#LTti z{;?vfn-x-JPk=zg6ZRr^Z>(iMYPFJwWcG8yYv2jeHL{SMC&P>&5Tme@TVx??;wkcX zMh^=6C<);jVJI^$KOr5kzp;46e=TeH=i-#uNp#Qe}|1tn2M z+ePr_LKc0(;rx1_(lMXNJX6Z-)h7olCx^pB@&1(ZAlkW_hvlu(Ae68#i*%+1xWdn9;7pgVqcEwMA_ z9pUWSG)No82r3r}1XdjlaXWtD{K_-`V$zR`kRa*0F(CofS6{z8x9JXIkh}sGpr0{J zD9+qa5&o&pX-eMd`b#eH2hs)q*#(AlkMX-h>^=qrmZn;v#1k)hJ<~k7Jrtwvhc=$d zalq4N$ zoVK;3;xlXw=Z?V5vtJsvIbvS@Oo23@6Paa??#+_suT@2=opCbKzN3CZtAJq$eF>J- z*J+2{wD7jCanDAqG3{bx>Yhx#)Ins#1=5V!*_LxmcrP3!MMnr$XW&hV7fjjce%H8i zJcl$&F!kGXtt+)0P6B0v2z6qedJ>RSx57v=u(XLrm=e4XL_trf5`yS!Fy>UvJ>kNj z9C>MkGYq{%2p=mB26X@vV;jS$;?CyNNs|QINk@9_Y&Ey5TDORZoTeHsBSvX!bpVCo zU=R?Sz5no$Z6~_XAv1kzp0K+ib3JLjL4#?&6L}d`xlK05s$6b3*Jm9Nu)K*Hu8LjB zBt#b{@Z$h14urtiS~74}!h8qfK}wXy;ss0)II4z{gcU(O077Cpx%7l}y(8LD%bsTn ziUx2}rOz49D_eBqyH_~8bMo%#v>;wN;~4T(NEV4Rj3L_%j^{5CP31(qb0Al^@h7uN z#5K-z0=;CjlG262QtcqzUNE(0F4{_rV;xy;&+n%E8a_LIW7}wvfXWe3B*Zm47SF1Z1g>H50_lZ;8M6jyGbZdrKj(dn{iLE=d zL_h5Mf7QPNXqu+F!R|&b#0fCW>$$64E3#AQ))A`9{odJetPwbI94o!;vR7YIHVe+a zco2sx`Fj8<*&Xmbu7fkw@KI+ls;A6BSSB7Wqg!XkM^|uH8`hIycV^)rnf}Oc+!kp( zs}`NO`S+c+umVTy+Jl8FMV{MmURBGogHU(UFpm6Gdp&A7=8OZTH0<| zSla&CeQQ;_-Rj?Oo^s+bVfK>K4&R_T!Vt3AFfpS1G8#OoINf0*IcePD{;-S@^)2gG zi>kkLb3zw3o+!iCae}<@C%Z~#ypky%un*y}{H{)NCULPHFQ(-jD&ADpqvxhsMZ7Ji5nlPI@4Q zlgCOt^ofPB;H{ppG0mKTp6Y?K=uHb?cFCgwv!p^dx$wbA4`P>SR1=c#GBz>JWb)?_ zhs=x*wo%0RjOg?BR5a7^AiD`C;qVS)5jb&kkqpa+G!U7dQ&`tLxu&VCsU{zXK^Vu~ zJJfSY3Y_2F&w%4iU4Tte-S9~po=3`0u4@i=1kCBfJ0w*fW_6o0O(cm+^vB3|7I#&UKVj!IqgHg1amhk?!$}`#u#H$Q#(Nz zKyj}+44_*9=`4e^(Wj0u8nDBa$ zA%7nM`pDu?{Deja9|OuHTQ-7GkrVo`wudsTx4Za1E3*6v)_>hYc-Xdx{+x9abA8u} zycG+k8HYJ18n$&@Ovkum%JX5 zC_wD&7XaYllN*meD9n?xNCQ^Svw`CGb+L~5R&!;OX-ssh%o@L!#nL~wr>AdgB2xrS z$^}Eoq<$?6liFGn^H?+`rM0#ti-3=~MX(m9ti z;aQoQSVkH(U582=L(_pX_(tO5RG*{+=ua0r$~@?i0P5rvOJzpv{)XD_nM(gLGRts_ zd4|Y=)fHczL}^Xs4F+{!!Z%0*7MtmRD&36Ub&m!ML2Ky{d6BbPKQUNuw2s&<==97_ z$AX^q*WP!oU`S#s!*dI!6AENQxJ?61EN$4du<-e!1 zZPC*C>7FD|kYcsbqTqQQa;}nU-FH9~cIW|MvH|sRB%gEJy;vn1nD%qSmZ!0y0R=U+xROUrV@f?sg&Y%y*kM zy~~7yCS<nJuH8`qd09;Y-OLkY&@sS0RUYIOh*Y}(iYyK%F7JUinlo%Qo5y|((PxQGPb^4 z5c93Kj>QPM<_SzsrNPM+rq5`ML7TcUm0Ul7_Rj%beAy=w6Jt)AND=CQ`AQPQ|CwG3sEwDtEGc~(g{?9`zz#Uwt3FDXQAZZh*M!Ufr$>tLcXbx;E*VLbuLrS@C{L}E*yY4 zPX&}$Obd*F9G`c+k(`3T6fK78&fuMGKjeU*xrhaNZ)v!U1Ff!>X||&&wTec3 z|8o>G+QI1l@m+>l1>B9qRo`w{^M2WWn9Wamt%^uU+7B_ES)lY@VWsCwJ(-Moagu~g zKv={gYTx=VaoKKanIoS&mXAmP!N4K?xpXN8yttkLj%&Janvn- z?6~Vh%d@NJUksW*VP+q?GOi_CvIe*z4;?3-0P0HMMA^AcAD+cZtd*97<)O0%3iv~w zA)V(8G8IdvfmIZ52FPH7DE!R&Un~BrsSSiR_rDzZ4PCE0#hJ%-Y#{eMB{2z{pss_v z)gKpbt3Pahk^kGeE6@OUTTq-IL`#kr+QxbKOj;6tzL%1dIwFvQ`6Zpz*-`j({}`n! z->Q)PCe-hWcXu9)7#qmdL|{=C8bg~!%Z}zMBX}<`gy;dhPo;^Zr-r<)C^$Iw2*Bsn zXB9dL&YHbpNrfVR4(BH&$Gc>{ulrggf;vuY#%m0Oo-#?aH;&$o<5-IFlO%~%Dbhe! zk?cM-_*X@!YPCa)vgH&60fm6Ce;lV9N4JQU zN#ekl%%@ODunKB4m?HK%Zi`+84`BvM+sOt)BC8K3U=b{`rx0TdIqWwmzI=_E}Y?wmKMj;`Dfq-a_WHFq5JztPs3$f3kJU>M|BeCq-PO;BVheNW`!ra@jyU$LqTP6Btg?uV* z3LqT~$p`?k)-jw~>}--g>HaQ5Ysa6DE2Z<%en%`$><6*%7hlp5*%~!EvK)?CnwVDI z*SGExfRHV^tl_23=qJ$VR9)Gp^mJOvx5g2>&cQ3qt9!jGSwt9`WwnFT(AI4Oq;K-t)8P$--!Bto+NL~haL46;o>J8I4D!11PXyr& z0JVp^&{Df3KOaZLG05uWtWob61}jeF`;T@TcDZUa>>eA|J~xn6#F1S;Xuxxlyc6} zjW2#`SBi=T;v4E?O-aCH)hS-9mpVC8#jZ2R@Hn{c(K4J~c&u+=W^VQE^}?0oR%N>_ z85Sq8c=X-NTK|I)CAclmnTjChGm~K0m#5p7NKabPtn5IGY@q_3VC{rxsqwJ%=VZ4} zJM92<+YOc8on*{fIkTNNz6yBbK7D~qwuw`>DO>t8*H=C7!-qaNz6tK}I?W8^anYeY;V{G$T ztwZTFzIU0eL%E;x8!l9N5jWl?bSP!GSv1*IUTD|ahCkn}`W-Jnb>r)pK!L`+jB|CE`{KOUYuFgU-{u`a8*XYu%`YFyl0$Zd4mK}czlh6B zdl*d(P*uqp7>gzTJlw6v^h#Aot}4z8q$@!bHy{s7z;2-S-`KU0v~`Dh?o4l~{TY0( zL&>qr?HFyCSxTBGqwFP{tqE8p-*T6-8@&W`%VSKe>R-P@Nc}jFdf(hx{Mj0l?Q3O6 z$z?hD-jd1n`U%_9q`_MoEW8v$eoD=W=`#D1go%YEQMB8@KL=}u;Y4vjc{c5j$pPwU z&AEoU0&r25S2Ef9-`AfKEB_%PXnu1ZnDv%@a@Js-t(2L;C2EwXehZ?4YPI8M+sYc)65$?Kpn z^s($4XSjSjTfgWlM`5foVf{G1o57CLXw*!TXr^gWHN|NfHl`atJ{p{&EPe6xn(22* z2?6I@1M=WNK&7*8(6SThBPtAH>Oz_+64=~ze?tepk1P{?f!#UNL&f10eF(833#|++ z-FzE>+?VXHFo@v$$oF958dHs1tom9S_ueia$AuUpQ7}Y5T)&4$hr(s38H1a)te+l@ z_J`;k#JCJF89h%9PlfK=8XfNnfExTW{o&Bi!<$MLQ)^h?A(&!Q6$iP0p!X@xpmhI2 zu8q#l)Ww%1?E~;uY4@@p9A&}b=8#l(5BQU5v!Q7y&Bi?pjNXuqjL)hBZ23(cUxwJ* zz5xc+!FCeglvlrWPA)+zA8&$AHBkPpvNCVT!xjXD^nbOO$i8pwNM z^O(Os*PCz*4+tXB9{F_}Vb^sJ26&>vx}gHF5RM%CO!6WU(RoDzA^=He0|Kz?_hhCt z&@+#fVr=~BjnuzYKw|Jjs>~%5G41zY)E6ig&7ZE((!U;+bAgs;E9? zFTM(V5;H1oqM<&a&Orq&eVO_FgM|&#$Cx1%H_O(~>FFWx(ERzx2Vqes=j-}_#Jb}> z7#}ai@{CviVtHsR9mUbel>^J&=UvvBiB$|^OyXGe#Eh+`AoG{g{s1Pr=p7px@IcS< zRfc}CD?`d}hHwK3v}JAzhJapgg&l~*w9ttyrJ8aZWi)_X*4&XbyCBA4LOA4)kk?%p z8qbz*jr6`(?rEP;S`Hv!lYte|XJAi35+H0XPq2^E-L^nE*a>)!R$VV4AJya#434m{ zIjg&U83CX#wrPL%mA4R`S{R8v*m^4gUBMVPr4a<&c8D~r+iYz>OQ+#kVEDeIil9OriC4I!41OA?- zT;+S^%D=dlM>76BXvSoE?_KXmJm>G;;vRD@Yb`%U&_X5P9Frj^3d-oK%cvL>ua|)2 z?>lUz%cwD%+puKPklrne87C>W&XHszAbE2;mIu!o8F^jJ*N#9==JQ3TC8vWc-BYu0 zdFw9vvuhe-1g9McTLNROFUYlouyg*q$@DV1a|YQ42chBV7T%IgSg(~o^q%hXH+Bd2 zwvz84x0M_DN|YffLPmV7dP!kMR7P%e4mTE4oB4{h+_f)piA2_G~tTt%HPQO%JS~ezIx|FLuY;^>y>VP(i>A7^MDzoHb9Z z&o67d2RReBaMgUo5tb)G7gmT|FvYFA1A#vhVdsg3^ZQ`;A*0u|_u9&&k_rAd=A=&v z5T1?)`DsJGTVya-PeKZ@Yp^n$IyakT@{rbQKsGPE9%76Py9SbPQxM=}9{0gsZt|O# z^tegUYc2!;`G{N8r;*AJxVcc!W2D{$=^IGiqdOEH5PPk&gVozp$E--G^s=w}`POCZq?#q-h?8G03G_$7F zFQ0E4!$^XtZ)Nj(>rTL?R!3qlkoW;%JF$`QY8Tgo1*9Ch8XLJKj2~ckDH2-^@9r{y zC{f&g39dA_`t_Lo;x~~dywxm_EIPw#r$o%GtJf& z#OAi1Z$_*u#@_R?W;CIa%raJo#+fK7z2+Aq;N=m>OF1F??4ZWG;~SqpCx)8y9nydC z$l$u@UE21zB%l#noJ$jgHP{+A?6%v!^zvwWT4)JL5eUzMf7>R!`uf3Xdh#31^>Yve zOoe~+p*`;Sh|Z-(eUKA?^%qlv0GeE)$&k|>w=}MD4bVmBuLH9nDzL&1;}sg{d;M+h z`|Ii2F)QqFn*MrOBZ}$doIvO_N!QWd*>X@OXCc>9{ijb~rOo`|D?mL5D3VRuPFSS# zF`%rV@){!=4QF%?DJ(gQ>M3T6%?P6d&_4K=7iGPr{X5lKR}B*voN1P8#;!^S36ul{ z4ooU<>^?{MRvYKSWAZ*kh4E-c&;kEKZowWus2voJ0(bv!zvL0T{YC#KM=i927&TYF zI%by+GBd!fA~cU$t7W+HE}>y%4zjsh#Sx-H346HsGoCf=hee zX%1NjU`OB?Pq-``**cIHp+8lzyeeAfJFyyz4xP*QZOib#BT>#QJh!)Cb-`}bs0OvK1~vqB)2JjQxkc+D7l3t@ucg>!rz+;B8!?MkF{4MsSp5*=oGBR-rED zsmM{2fqt|B3*&Qx}0p9+HJJ644G^sd=_Fv`iv1(447DH<_|d z$`C<%&9Pq#ObGQjNPA-w&(uslF?r6^x(l1yml8FphlV0NO9;_0Sn|S#Jm4yK;9m5K z9idM(`0)*&)T_2A0#@#H~D@9gu(u;7yzk5q1$55(4geVh%H&?*~f#)$qBp- z8GcYb`lG9sbd%iRnOY=}yQGHkf4p(32$Xn&wmAWMLc~mK`#;;4*PBOf2=DRe&evlg zT$eRBs&LI%Yv0V7gG^J3qBRY~p>-@2LJNtFd&-3?SVBXKuU72sVJ&84wz<&U0=DY7 z(F$mUqMNBecsyA`GOXM+gBsY!zLAMX+;)S_bAAV9o;CYuUf!ub1eg8Qh~bnaD6&(IDc+M6?|rYCqxQO!1qWT96&P1nJI0tjwA!kw<_Ho#H6jAHAjL@1J%cWS8`8n za1J#>GiOrgdF4iV)5XP$Zlg+Jry8ufIkV#6CF7^nH0rlK+JDX2eo&wL*jw+{{n-Y9 zcv*f<1)$mQk;8%}MdvDx;LX0lH_aYHvL6wNdB)iJF-sw_VM%@KI+E(?=>j||?`G9> z-I{LM$uF!W!nnncH_7Ks6(0mIi~NUQ*#BM#0R*?rul^O7VB5N}?6!(tr(%&7o;`g8 zecihQ^t#ZbJeNi_!@1qkeg&5(fcYq)yS=yG>8-i2YR=i;tMeX+e58ZQK!K5Yw$aaf z$5_7+ggt?DqcVrXjL?4D$kN!^V6{r`R^mk~;>LNW_>tw@}L}gqG^TwZU*9;gS}4q?6CjI z=qXvK7sXNKJ~sPAeJFHjxg>c>@o|+i16&iCDMZZ6_tu=i*0?CVJTi5Qorevkqk8H^ ztlD^grT{S7=*&-+)~YD^lzfAyRD4{Npb^L!0vVRn{6S`VY@tpkfd^y=!%k@3RV-!& zH3Gt=CyBQ0KSuh9Sob16geni2+%ZI@e8{#>9qqQyA}@%UX1o417fmbB7&I1L#UC*+ z&B4h`VP6EGl8w^=n`+s>m^4jE-;iCC?E#q@9-CwUTJL_v-T#L0p>LAzd`I}1s6Nz0 z0jC^+aA^|tCVqNkWIFy0fRJGyGKz@t-^^1)h>Nf9 zdZzFCYZSXa@a9Q3UtdIod#b+0%ep?n6T3wY9qZ8z0Wg_!lS!hN>!e%2-#6%i6XeMOL4He{71h_TbtG&fY|ouyNdK0* zXVUS8e!Suw28Xxx!TUp3BrcAj9$v8XPom4mmyRJ^;_ckRA<8AVY#mkw+8Evv{0|GLdGA;0&X?L|VfG2rm+l}*);0244e0r?0zRCDvBWssbP;) z;jC4LxEx2KEl%eH8x)ku(r7iEWBkH}nu(PN_wE$57wMT560#$fPW!hqj8O3Qzsn@$ zc!SGXypq&ykPTNGS;-4hTjq~bp#FYGAYp(%X7Z87%?=vNvtUA!v3E*IPU}2Vg2)^VDqsR;XU`j-PqLAj4piaZO< z#QQ@sglX3jaxo<)8N1Eh^;5=%0khre5!LHGW)PXr7OPa;zW&C^Y^W#0LNQ(0aHv4n z1Ji1^ZHw*TazRSafM@E|6G>Q4%+C+51yz^`@AdC$NQkEA=rUyKj`jTNwRxJ9ym)2G z`+38W?4^~*5)%}v@bA2`PA5rky|cu8zbD<3v6-kK9Q?QMvKi|g`kiQ!M%A5DHL@~Pb zSPd%+nuG~v&i^(jd8$EP1$M){QPNHjFr9fQj!j6{i$SMa%l)KHSZQg<1=0#mc~CsR zi`Yt^&`4PjB{Uf?F_Ak{xHc6CZ*S*jd?ryYxFoa=4W?Ms_*G4_7?E6YDW=3?rHHO} zEK-w2=E?9FL^z2_X)b~%81Qa=NQ{ZjFf~AwR7eo7*+UW(o5++A_+S$hO6_y#jIQRz zh-|AZbdZJiK*Gb$w5W<|Ni+drNIxclJOJRxMa4+; zIXiSkNV;R&rbPIj961}Pb61GnF$Ti0fhwbL6UyS4bW;L5YeAMhfQPvy%7>@9b&I8Y z&39AzoRoXnb)Vg%L!Kg4)Z$mhKMS5o1x+41tfU`1 zIo^F=({IVy#)d8D@dhK!E1x99{HK)rrahIq7ya&x_S$r3t=EUpFw#+P-E%IxMk7aI zwcE2V>B7!p%0`_Gv=W**YI_9;M_>kX96ds;WHQ6Xdu;L&1LbS1b&cpU_i{)kVZRvc z*C77V%jjZPy4{GX;q3_c>yGzF%jiemAhS3=&XG9}ZT8y#W2@hu- zIb^R3AwP8#Amf|AEtUL4 zi4%v!g+}m?j!U#IIe6SXm^S$8o|@JJ5KB#Av?gIK7ihu5@Bj zV-thP!DPzQLj0 zsmAr0{`r>1#ZurMo1p%*yENZp-<=6ToeIUM@teD|)69G;FFpY@N7J;`=-=O;$#`EL z+G0xbd0WRw_TbME(%o(inBB0!UNPW-W`6<|#`!Q2Vp8Qh^B18>hJVePd@|1&lO8?a zZ*{T}Z`ZnQ%MTzu zljM@@T$E>$L~!;Bzm(X{XU{r4QUHVulS&BCKL7xd^5`i^xBBjXLo3hyNSnS--+9LZ z{bcb{$;;QSfKj8{&EsAj=+ZuEHFMHsCmDOW4#Xmjh3NWw$LKIoX#kfNhCw$s2hah? zxD$L}4gkpf8_3xci!xK)MZ-COl3j-hWSDAml|LiV-(X=XDNx*jXrjU!iWe$x9?o!22Up89#Oj-F$#>%>jsdPbOeo`c?8(A)e#MmUR3wq2Hh@FYEK6a_K<`hm{P|4_n&*Q( zk>ZoTEH|#be7V**rnaE2WbN{xpU>U+slM`X%e@BeV|@TsHpC2uru#Bev69FG0AqRi z^1ny6kNzz$s+51Ks|8w)pxgdpp3>Wg?tdcLn?8^!;VJ)>gfYEy2rY33jJy~ZY`h6P zm8L%@ytG>i>J?zgImPbK61%DxGpI~2*m6dx^#*0 zP8B>Ro;iGN_<3~5AnTFWBNq0G>{1xZvD{+)g&i{BV@c2$%<;=6ADfE=Rct)(us__v z-C`I~6!^p@aKXy$%P7a8{^OR7o5sP`Iw`xCM9+_D1&H7riNnN;%1bA8B_e0kQQi)6 z?NGh6qFgGeC=)x{&63fY6w&plc1bg8$KV~;5a+Z|C)Sm3swfxlJdRHz?c}IxtA)sg zfSm3B{oK3n&!2tfYNYkS$fJQpo4nm3Qj^ zAdSh{$;G8i?3CFj9L|h09@YHf(mm7>wS9SA`KTzkeBcuE%H=B(ru}Zpv|7qxPm{8Y zp-{WY)4ozR3z-Z+J&9r9CzAqqQ|7El=Ak-%N>@eG74)7X^(Y)#n5)QWFq(f|aE(K& z->S8o_>GT8^E|3{9b}qklSBEhSo{iEaFU7#Z5L*F=T(F10JdIy?jc6(kLrkVFUkS; zamG&Gg6&9}nmZ^Xc10e@dmq5`OGJRoxzz~15Zgw^`kJv=JPVg?1@KZ!;+n)br=0rI z(ftwJr^PHp72XDU{ds;pdZ(Y~W;wnHi5t^w@-ic|5Nr@n_V8^C*6gK*_K!JuJxzN` zLkucyXZHSu>st=fQ*6N{f-XE7z=kT7+?+;CWoNc7hE>=(1*9kye8GY39d@lQogzjm>z*-K#BthXB2pr z>uOn*ppNpnM;HsLS#fyW)BopPY9v?J)Hz;1N-nf_s+c~bH=d01+3MC1R>tE=DDN%r z`Eflj+$IMm>4oanwH)3Yv_lY?sG_l@RS`|R9e}p;>crTRp@%Z*PTNGXjdyV}S6)*q z=OmRfY$#E-yJX4^{P?{*C)`3#3^30q1H6oc znL55XJ<|4&g0?_eJ}#zE91fDx&Hc-A6GEQ0$BCpzRz!8v4-Zb$sodfNaa5QyZj%j^k#DA)kdGDh>2U^x;P#4r=aBdv;2{OQQL! zS;nAKqAn7z{&Dx_R})Mi1mYwBn0sIE>Sj?d*GaGmZ!L3_YU_1tIbr6~)6QlgSY+M=M;AlXUQt5NL=&Pr`i;E14C zHvCJv{#E0gdQAsjxgUn##qC7npLTkhe&!3io012uWi8F^eC5ZJd zh!MsK>MF?Ne%}?s+Hu!K1&Jf7go4%*<~UC*s}^6%>$`>3gwy+|I-$#ZxuLb{L!6ZM zUlQ-|P;}|7bz84i_}=nV26-2F@Z8tcRtSMK*L}RMB3mPrRf~Dd@zx@NlvQcgO9Mf$ zPlM%Wley3vj!q=ZB4Z)|RakziR~Pwp_4-W!W(T4`dX(0ve}MsZ7#r`M_}RZ`=J=_2;6|4eRQgWF!|ywsNQsDt1-R9sOjm<;#3x_iO!X3 zUwm~8=oD9jr^~I z!`8;ZW)|$+w?GfCvRB(&?7;=c%?%Fk_Oj3&-_cxiWGzkiJYj45XmDr-Cd_yZUb?+92|2l7#-I^$mq_8nY8kvSh4}fPWM|T$hPnvQ!zBes1zmjqs zDhxnog^^hF8oSw#Ifo@+HM;yIwFbau)FgxMY7yh2U4>3x*_;Jr1&dBEj0?sEDkPZ< zcsW@u2-uN9l_4$6tP3MUow+m%aoH_#yFVI<=>#%(L>YVynEiq06z&8<+9$2xS~1Ec zgMH79^3z0vmZa7sXPoQp6E!bO1X#;i*jtko|2oFZMy*jhsYXBBFr`m6Wd&H14yL>l zc)jm-9vig$E~ew0Om5e(Ta0eh&9^S!01NS<)%6@9Z|=&NFz=bEdpFDCY%_QFm<>HE zmQQlsb}2q_=jeJ$$Xwts@%P9o{3F}Y5LW#M1_%S2ai44q4KBm+(9p_de=@sdfVL!< zUq^BA7v|wB&*F^?6cEEVGJB#stx@f*7`eR2PETs0S<~=Mcss>L zddd5v!(9i;A~unzw7Hf5D4FE1@I|xd@#K6uix@LenZ54t!XOrJ&{HDU4LR7Br@)E zKi_Y1=J2IGkG(GIeZMeY*g3#`D0-jI?dSbW%v*1jrxeoL+?o~FKk5%2&=m{T)ns%e(nEccX^cPS9bL6{3$UHLw=Ak!wu5=K zB9$=-AnU!O_UUvc8kch1zq7=7#A?vd@J)dBF12GG^oE+*u5%l{_WcnA2_TE)_zwQk z1BV@Mqlh@%nL0qfHo7w@FEQx;A_7z#=~Sxh^lUPcphu3cXW2uHj*|N*NGQS-Qj1bK zO+R}Unb_jXiE*^6e~nH?M#8dT<^UqVnj`UL^_r_zIF2w7VilhjUc`_)m)x#2teVGn z##`G%W?7ECT$j(99vRcVNVjx1h4Z0uLCPCjJ>XLqR2ZLiknV(nbKxnpes+bu+jdMq z06jp$zewO@Iz8=RO5tSW9{4(sUJ#Hs$r@rqpfE=gE61~7Tu=}>RVNXr>GXVuLjSyt z5&O(-J>GrCZ_eK+D8v=2j@cY%Oh+^H+t9uR=`-Dd8)@hStyIFTdHY3LR+ttDH>yHc zOP-d5CqMoWrQb9$DFcgVbEL-Y(dYTD1N`7^7|>hYCO#E55rhaI^M`ABiSZ4d6BLQx+q-RBNd(F>YQ)78<$<4ST@I!z8z)2yh**S1Qo*=* zvF-W>@z~StSa`^qzQWp}8H*Xq`aNIWQtR*V`)Z%s+`0}oU>o>RyZ<@<(#3SO)FtEi zYkOXR^p109a;TZI&Yv(-ys0%&6+m)Ea>CzmKUasP8N|USqVpP-rD2^+$)J6)CeE@n=k6z zAtrboSj%0{4S_8-dqlP~@kcy6eo%0eu&9Ijn_KRp6eZvTasFsRI8IZ(@4Dt zIii03s`=e{S-;1tkI+D2q(Bit5-3SQVoOj7N;ncRz099lv$e0PZe~?of2R7$)6`{D zia;Wg6Qa4Q=)eS)GU_{}gkIuLso%H~1g!%}qL`DI`J0kY9hVsI0MG$`vk8Z@WRrqE zUGk5&SF_i`2h>~GETo1fz&-l3eA2*H zY$+rA@`F*`+mF4tH?Yym6@eYmXm`P_kk z;kQ5AB|yY@7VSDB^GfdK!O0!6sNwbZtr2pW1rskdPF-zC-Mb~{xdRf%onv^#occbsV6q%+f1oKlav^ZqwXV*m6$QFl;qV1nj z2;5R%`rgbd5j#!Jzls|@#`Ebw!4Y9&2t{Q7l$?Lpf+mC1hBubw@CI3AGT)FptGXtK zMoqe~s}rQoo_U33xa=@z-+Q_!gKx4da(KgiON6`@gea~dR9Dc;%eIoAKP9h-2M{t$ zNq66h2de*8$lR?+Dx`pEd7dLtJYiyr&`Y}3t0~AO+9g&|QLYG&(Hw<^sz{x%5^kQY zFHMQ#7D^(OBW(}5RV-kpsD-=17t63Yn8If&5bT<#*CHhCdW|~KmK9-o78C2v- zJy$xrhsIWkAh1txDD^KU&Y=w+wrOIH?Bj`5KnLGG;J%8_M03l7Ml~XUXf}rWY5V3GbTED0!?cTCww-YKi zS}p@t|0**>C0|8Y-S66O)#%VV+BD>`TDH<#;5wvO2e0$)1ejE2s-HK z?HBQWBuJ0+V9MZjyQ0pV9<-P(Rt;n&!!4wH?ACho4$aO$$vDJ@O8=<%zE%1 z!Q#}Z`OiG6yHyiUO-^@$n=5WC?_3$==U}UaO};{+C~p?~vn7k{Y8@;lpS`^(6!>`3 z{1Xt@PX5K}rgidavZ$T(RqOhkS+;3PqqQx^IX4hx0pz!&kW@YDJC?bZ9~f-rkhV5^ zkT$eYy1VQC;otBou!3TC(qfu-#=ss_{E7L`ABg!ZOfM~T9x1fmj5|Z694YUyd3af2Xr}r}4FjE!3aeD!UVt#_LKtFA04=7z+j2Oz} zVS4FPYp|Y0T2mD#aB<)@uLsy|uR{H^_o;^)rU8iFSNge%XyN$Pu>m9lo#0dir|0zI z6Le2Z5yR8zbDu@3u*sELO{rY8HKs;cRqI#64Szx>0IKqSd!E!{IEJz^CJ3GjZI037eCdwTeHG(F*3FW%{4a8H8m!g$lU#i*mn>vNp|1YVG>)feLCEpJso@v zdqs?d{oYX+xMi(%;ZjQXDO7-whfHUP@aS=G+4}J7S2`U>!Y#+fhZeU<$z+Q779Sdq zUG|(fUHNa|Fd8!)pWKbzIx7 zhBc~`(>K|BY}v16WN05eYlA% zvAJsB+JDGoP1PyM=zL91X{uV%8;_xILXu=L^u(#H@g6Kn3YHfOTq0pmC76v0AGI`& zFM=VSXq13-ijkEXcgD~3oKfw-zgaSuf?d?IN}Prz6v{=g62KItdKw^6rO{ytLJh0Z z94yuDmty|SsvT+X&-3_)vsay-OaDz7;+#VX1;aoTJb35eP8O8W^YgzS&YS40yLaw~ zo!#_($6lZHH`Id%eXRvp03Ui+3p@jlX_Ed=_rE5w2y!KJm+XVMc|S4is@byoDbKo! zXR9Q5c+AU90tg2z>1I}k1DP(TBFwa%gh5sAw!7xSfd?DOA%bZ+-0Bmk+V_$?2vfah zODH^Z^?UUd zO@ta=c1X$BsBon3hl7AnC5bM{HkZAHnlKOHum_HNh>}UH|4uS5I$OYC!trq9!_r)P zM|D8gOQW?E7%WOt2Mus&c4%!9JO>zY$so~cI7sj==0yXwj9IzV{llU5wdK4{TPoiX z*zB3@ISwTZ4iYVgo0_Ty4GJnTj3y2a{*Og%*g2|OaZW&78&HH$yax}!E;1C96f=N+ zOtJVhF8P;2-5=s!N9@*9B-^LsYAas<|MWT@E2&avcTDi>IR|VB8DYrZWq^!t>ya`_ zP4vQJ8z-?}cto-(SL5^_rJmc#c|s^Pf83_>X={dLQFrr7b8<6?YmAuNj5zk;32vi1 z^Mef`ZyriYe0v~}_&6Y^LS-a1FhKFCix$=`#{$nW6`W@J*F3+n)qr!q1{-abpE7o0 z!TcxjNg^tSnu$Lja6H&?&e-=M?D=)s?4mbHtM{C~lY&t;jPKJ3Zp&$-g?gIPY{U$T zA3{U%rnBFDpEaD84>lZgq5i?+uokcRoY z+10QDTu`0y;$6x>BbVFezpT&kVQ0-QI0hPpK~{+)jm5YOlpVsA=Ww0j8xv}+gTY}C zGS~G1yfEICw+vPiZs&|NZ9|q>a-soT1+?fa6>DeGuD6=ciF7N3nWQrjeL*lh$+UC< z%P!E(vd-MT$@y%KQBkq?YP#F;mfOavl*kB{m1lP+?|f^RolT}ouzd?sCC1*-T;z5g zp}JRFyG_yUcaH3%1`8xCpQI?v*%D%;Ww1ktkt^TfB*Ql#)TV@L93M?X3Ax?S+nK2l ze6~xlt;Qf(V&V8qGa48bVC2ZjW4en3qzIvfds^*9!NBi7gCl$T3Y&F-GorxNrFjk$ z)@U;ebVJ1lNB;B<{Pq^slmv~6g1d7w42%{%s;f$*emgR-Oa4th>WA3=q6hLJA?~PG zDXp^A5ICo@Sdq*7iBdebk;vG_F<*Lvf2*PufJ&!{JX6@h5f zQ7XQ0=%g>`WB78he7$^_Y`SG%HhH`Uw0irUljf}rBhCCQ;c-IB7OTz=0 zD97-#OLFu3C4uNIj$$W2iJkFXD8H^h?@|-5i_-bmM9;SdinYCbn_#=!E}22p4l}m- zHjwMOlN9j?rDG#Df- z5G6~K0UI3>D@nRu$obFZF7AQrsKbc!h*P>E^rf>PI0nEHY%N|Hx$>ScxZEq$HM_?g z8*SuJ_}7pKG3a(#`P9wnQ0;-B-UBv;znN9&ozyCaN-MSR?~G0AM&Z8B2rl^5guB$e z&bicB^h=kU)LhluIC^@mvLNPm9EJQoYg@LdzF0qo5dE6A&EwV|hpN~vq-zA#)}xZc zOsCq6*l!@u&^pzlfSV)L0E+cKkY~$E18tUquu*)k%YEE^m$mU$W4jHf!2Re|coh z1#nDZu2gTBD* zA7YXqqQ>mW-ZlTSx7TQ;ZRHP3E77@j zTJIAK_T%!QrrS$I8(k0~;w4LQ;iKAf<-Q=hxxHhMw$=?R##R3d6sn3_zsqi;8RZfT4U)g!bj*ef-`t2Gwyzs466i#PPv8X7E2 zmS#%-P3~w*+)Xrn{?jz7ER7qJYp%h9RtyaiVr@mnDf@m|>(lY?x#*-rs;EiS zeMNDxqvw`;`{K!3rP>@PE(@Y8nlrJ%A)_h!r|^^}&~`AbFZv{Jr|ZB)&@+Ip02n^V zR~l6b=(`2iz{9K)mOeho{mTKr7Qhhe5Uw8rG;olG>0Z}GOJ`IHu)M|0BR?Ngv;5{3 zF!a>XImGfROkwWy6aa9Mf(MnrXLnK5bJZ$Z-5b4nH8FPVn404RUcX*jy^N$(Su!)? z7i7r3(K~LjTvf`Kp<9!y-L+hyBR@GzWj#;Wm1aV!3*o1{k(I~TBE-WzK#xODn_atUzr=Hs=|qu?-^M2;UFP#QQ5G&em1R1n}-?+6`#f9JT7d7z35MR zOYwAB&cx(a<|XdG%Bo&Ffz*VZ%y=+WeTVLGjynDK{EaXZK<{xC@wv3UOL%sKjFzeWt221N+S`T0zglp! z*0yzVtaGt6mhh^D$R$%waYcD=Nb~P=8~C+)!_$$CLmQyhEEM0N%!#P8IJ(;uH?4G5 z5S6en*m1lG?aLFwg3{^S&mT#hOn0ve(?Bw`-9Z0xsTtbZF;pEP-7p@811NQYnkdUj zG;Z5NW*{l4G$J>$A>GNDYZ_ly6X#mUP)2U3BqyQmlq%F-W!o$$Rt&_|pR?HB?66F3 z(Z(ZJf<3*{F^RG@>9CDQ{uYjwmimvlJU{~@iHPf%4I6ehuG;_d-0354x(C*8MUPz! z@nDLh<7+GMX1;V(sIvea6ZP&2;C|N<4)l}9I2a<0NRXEPlF3}cf6%e*DW?%pRFG(gN zb*T35SGC$=|57QDX!I-EEIq@w;T6?B0^t^Dnd5+DLr2;RD%O#xGLorgSx5Qx*&lc< zJt-bY(|WwRty3fB0?`hqc|$zw{@h3u1I)v>L*xS2{I!df8@E@2!U6-dfwED2C0$@f zUL;-&<(nEoX!I{VFbQlijA4XuG_ek!#iM5 zE5A8?TZE#MW$b<>Q}Y>(DLhE`?DHHJcSL3OW43DD17c(*FatyK)oiFd9I)dJ8;dBC4u~SvWadku3Ei`L7y@Xeb(@V&%BaD zheL#$_=a?Wga#ySI&`$@MM@@Mw5@sXktTG_exx}F@Y=p>qmV)szR*sY_d-w+48&yS z#nwK2Qtf4z6m#Q}I_1hWX?k}W$VzT6i-|93PGiR<7q^h2?eCnbNJrRZRrsc2vdn9a zovP&KVLU#OCmnXlR>;<&i!S;3UoIrC4QT^+1Jw&_&36B4YKpoLfBea?$UZr~*K4C1 z5d_{$GxYUvuFLriiue}aa@A$M%;e<%JA~(ES9dpd_Ozm5j5eUwdJiY%!sdLPwl5yA z@~&I3;Uz;Ok0!?CCgxk~!f!ZKO|8kCEw~5=j!)J;q&y<0lXcSMjP2}XCKpno+uUxK z>+-uUS3rSQvAV76-oD-XK%45krn5N?gZ%RG$^8OUJc`M${kzdNYiMM3J{HohfsQgZ@+& zlHjGA6;k6>;ac|XZ5-Fz*U-3k#`p3Xx!V17_(Yn0SXt^2?1REm#muh=bPp*BF%AX= z)%Kkg_BamZ73={!zV+Vq)nS&*Tpvp?_H+BviWRfV`%TMdrAuSRO;#)~Dc^WFQ@9H- znq>3Qwn7I4f3O+&@3HycX62WaI=%hMf#j1PY04RxIyJQX?zN3kV-a-;)qDN44W&})6vU&de$|s zZ|PhUos!pHpQ|$HRc?7)B5c2360AAe4G$Myk1 zE1c{G-DNqF(a|X}v{URQ`E9q{H3=NQHB!NP;{xB7^E`reIG0Yk{^MZGc#nkfNxx%MK*u+Gv*AHq#_CUMH;RwMaXpqwQ9z-6a2r@0oQdQaXlvhckE%Wr;f1 z%el|BN+(&YJL!ACcantON_50{rZ*+0KF+k%q|3HARLxEP^_EIzNjlDtioR)SrCJ>Q z&BnCQGZr4Vpl`0#Yc*vV9rcIr3FA;k!mY5`*`x*j6Szg7f9jh>mhwbP+rfZ5<8i}x zPi-bpMZxETeOLu5QStLeW0o<%ys_LQkdJAsEj|do1qXLvvK)?`2D)p^BbufKMWoYy zn7K1^%FA)ix#gebKaqhGvJaRPCrI~=vd%`@KJx{v(c=H{0u`IxlYxYcC< zSs<;=xZ?566bT@tYDyS2SVyYiuuua>UAb@jhf^?}m7ib%|59-+%oC(L3i<+Nn*VPN zdtcS6!i@F5^>aNj;A2t6(K%9s9bq9Q!Rso8H^?+yEfDdlnOq2)i6t26y)@jDhnjD` zs9(y_0Ss@)<0BDHXnQAF?+fQrqR(t^*1GbNhb877XE*4!p4=MYAB16)UtgcKZjjd+ z7e`H2G+qOreLCNU^;v|k#(mjkAXtnTwsbz99c;#KB>E3-rGUVe(@kSq#Tw>G_Jc*% zFK8OSTv0}ar{eOm`ffI&%CsERg|HFf*{K2FIn>PT>}Y#|Xl<42ver+K2YffH;^$HV zkW7lsI{#S9I{uTI)-BGZCG5D*zpew|yt>&ft${k@7g!}<9{ip$dWr%w8y^1Mj1F?Ug^9nwCDuIXZHt%b0sF1{9>AXwXg3>)-#_83 z{ra%ojK^k2>MDgj)|;@~I{e@J8$Hldw4-S30h1^6hX>WWFK(PMdpLa+>iUu;^t_6k z!AV4Uxat65xb^@Kq2U4bPxAE5-mVTt*TZ(kXjgYo!u~ZW6wc1lMc2KUo<7u4ez5s_ z(Nk=t_z!L*wqs{|JD(eNY&Egwi5AD#CZvvb+HhX?`ExiTE~s$fu4;>a0&YNbRc|lk zc@Mp$!CcCKQMZ3TZzp>(n~m=K@E)zF?CQ0&-HvVUoqgWZVmN{#=(c{r4K~woy!ris zm`i~(17V~{b;m1nPRE!r`w^Bx!Y|@pA1B(7G+T)!=ZJum#|`F4Przugz9XHyYgNto zo_fG+0q;cH!p+&|#F`a0%^Uw8S9>20+g@du4b(6?C>NHP4{c&*#rsPfIPyCk*ilxR z)r+{eVs|h{rWq8+(L>{DG5^F%lf%KtbccAky@pYV&avBdZ*uM&3VPPYQF67@z=WAh zg+37`gas5(ijrz)hX}JRhJ!LUGyG9Z42^F0%(Ut64Jc(7016)(??bC{F)q_1y_;7a z)~QEPsm=9#%{WR*Wpd~tLtOEM{!RM≠dR0E9ICQ{-tcR;@{R^I5P#1GUH!p=-{c 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 literal 0 HcmV?d00001 diff --git a/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.woff?v=4.6.3 b/clones/llthw.common-lisp.dev/gitbook/fonts/fontawesome/fontawesome-webfont.woff?v=4.6.3 new file mode 100644 index 0000000000000000000000000000000000000000..6e7483cf61b490c08ed644d6ef802c69472eb247 GIT binary patch literal 90412 zcmZ6RQ;;T2u!hIBZQJ<9wr7Vswr$(CwPV}1ZQJ(j;Ou|mT%C$|J1d{g?CP%SsEdkp zQxF#i0tNyC0ydxnLilGvRJZ=u|JVKhO7@3X;RV7Pd`6E zpk~${rvI2E5U>ab5D5Mee)_Dxxru=>5U{xaznFi|1>!(h1v)hU2mi6AfBt{tk|Bb^ zWSQGIyZ>WL|2|?D2nfbsl?t=W+Ro@-oYcQKh>CwK9VAXv*2ciy9tc=b|NnA{KoLOj zYz=Ho{xSc5?^pV7d~fF3V0?Q!CubmFWhx*bgug&Q*s|!Oyr6C-hNl1KitJx5#DA)& zQ)l~U|C>ReDZawl|Lmj!FVlZ^QA?Y_eZxrKSYLk+)DRj1N#F2a-&hNTOtX&{0tnU? zXdURk`=*Zu*?oNzeFF=FhEsiga}Wg?k=R&RomhANffI#>5RecdwQ$yOKLOqx5aRJn zq=_it5aK|ixlq4={^d_6_R3^AAdTF{%xevAl~*s*oM#EDqdOn~zsC0$ix@$i#`kj{ zF+#n=3Wp+GqXcqELONVf#gbrw7Os5Py=M2apKPjw3d8CE!XaPr5P7#CV@V4cE}pzPm9K9+ulXz&umnC-T(6)MS@OS5J!2BtO@ zvg@qC+nm+6APb=-NfL#?Ia1{Z!&qtzLf~+TZ<1g%2N%;Banovy)2KBzvpO>5?9JT2=#@M}M*SjazyW`Hgr_QTm)_BMKIU@Yb>AgqxI~L*J`wBqJnH2E#;Cu3a z5e^9cMsU_Wq+V*wo!_}xo&7uVodNZ;y0dFL&=>ySDgy!k`)@(qH@do^{Z*G!m_Bd1 z?aI3^mMg0(|Fw>lo6wt*m6FxM^>b4RK|yOJw0>}OFoy!P!oaowlKHY~@nkwyQ)WHG zp>k`0CK&~>>0?%{oMB=_rh}|6YQg1wj+fpq7nenPz~d~W&h54j-|LRk4Bsg)f|E9P z?3$>%J<6y_kYoIqkOvm}(v});(=Vv(4I0N%t`9_qUq2;EKj3Cu_teC*%K@Xr#N6rj z+(U|W#F-OhK`fCaDtuJfvTq4*s!sRv$&cbiI|;l#g}?7-PVBenkGAjYm?**K#TYUp z2MG7?W=`Te)k-T(T!iuQmgeCI)(!gM>A9AJlAv4ZqMu7xG?S$$ev@!oEt*&{Y_h@X zsxa#P!n=(5keV@$YK0A06p0Xh z{G)X=v7L4k$+D9r&0F?Mn=C&)Bv4Z*(0n0hA|pj)*HiAwe5{2F$+5{87cjKilhRJq z+jFa0WB2vJUoh9oFW6T1GqiKkVzIc9`I>td7L~23^v2b4X_6zPI5lg_^U%aJja$D- zx??f0D3N(f$g7jz?x7XRG1_G3F*EAG3ughF7m7jgxwb8$FMOV!7^d=a;1fD0s9p)! za=KiW8Q3RR-`!xX>iN|rU^i;zybsIRZgztEW1gD_8|L(w^>aV+<6HSwrS^hpa1+`N z0WXeD6+5FX>Q4z|u2!I*8AFv3tc|QM+jS8{o3L2GwXEBWNwE~6UV*sORD`&r+L6pT z4|#nAk*4k=%PwVVmUEutChH0u>>Ifct1-S5qJ6U=F=f*Q*O-_t|btQW@;uQ zN#11kV12Vv6xMP2Z0mp^KPl2VgLs0mQa?PJ9za-H3$j(RyHxTksPQ>QH>BcZy+^M8 zV*@r8T3>r=2=t2_O6nQP`4iRIg+*KVG5O#}D~^CoDN(m?(Yn_0+P5l_)cqp0c4UU_g;F?HRuP@zF_cO54W|E4F`z>v34o>|M9}G>3TJ7@ZjI`ZI_l;H#m;RJx($q4{_(65PXT zxsK&`QFe1K4D#XtifFqMUq@f$bQ5lr8?s;gc^|ai0`3J{l{24Wb&rtkNTVV6YGfQk zPvNQfawgA4lWyE(d?;5{#?Px4watl&Xupd$6q{5(YKfmnjeJs+*}TO!8HMdRW)@7_ zG`;35pe>vhp*LB0QEC8SkjOL!x?9HSn6uO;2E%aXlT7(UMKjEA8h)NE-f)O{DM^4I z#gIRIz3qM|WYrxCYBST#IpEENwO_*^)##`Enw6Sf0Bt!GKur`m z4Q8wituo1UbDp8Vef^kLLjD3BI<6gNRy=IOjcz%Lezo6~AAeChbGg>MJ$(8$nhYiv zzDD(Udi>5);pJ8YzfMYm6wn?)vmo{mPX$C&ZU6z^dG9zEoh_`LvX?cy>Fc>^u z`Ja?dh^hE5R=-X}x!rs8jBRDN&o+=h8jx^;cLaucL7t;$Ad8r5K>TPnhycH#VT9`V z$t zfyFB6B?E~B`nLCz!VvR@!fZ0)5aV8q${WCmcO!wBfJ-JZaFmQN3;zS zX8^OhR_}VIS<`QU#T5LD`L8>-ELo!zJrZ{8S+?+vL%OtNBMe%D2F}O58Nb)kBFNOT zxeWeiCXMavLFy~QC z6I>9awXet&!NpUhw!{S9FUElSy72Zftyhhz{Ez}AAX0bhe7N5Mm0uZ>H0T~9HPwEM zaBIaN`)DoSnydMTrIz1td%yiF4|KPp zz7^tTWT!d~1ReT}SuQ=D*ZlqPH1OYWwQ+ix_3;!z(dvuC8F0jTg?rVC+($t8QtzS< zde4wn7@3wX?r3UXC3XvZR5*QN9)O#=Q{?MG=);^~^H;bL0-R+WnQ($wB`(DjF?64X zHxEnKGNd2wg?4qD7WI|&m#?C& zhe4_@i)J5slEw{;ip^eS?{^0AMRPp=PSgtB-8wO^SbyDU$19cDxB9IE@y}T}W zd(>zGAvJsj{53V|gaQsAI>EW3m!YEB!$SVbuU2CJH zt}Nx?JI0N`-R0@XCh+OAeNMh5VQy6X!&TQ=ruMnMrKPeG;b_oJj>t8*Ovwwn8osnf zCEM51PYcUozfp#b6xn1n6>tQ(j`fA-+N7x_bR~fCuo6Rk9VJH105_tw!<)-?6VH}2 zx%HLpo|?A8f|bbU!_jyYXbqjgunDp_WB$1ArLcVFIt~G zlN+fKAUH8x#$r)_#k+pe&1K|QZxEE)gyLui8U~s_wA9pE763mBH!971EXG-1fFihr z+c*ZfMvVu1K6^InixB#XsxSvZM}nlUPawABV?m>Ebp_t&8>8VgM7H2|qGNIgbsz~* zM(I%QhjcKAa`R$6=LW`9oG^wqr5$xy4C-0h$6`TwDl{9QGVqpvV4FR(@@;eJF3u^c ze44l|V`;W)O%NBjbMZJ^gkWQ3Nu}}$piv=cn`F@=L9HD2NicYRK7n*<&0Qu#%}Ahi z7Gn6mDOD2u+DNXt600|7j10x0!?JHN4$OUp_Np6};wxDVJ;b-TM=8 zo0d?EPkAcC5#^9aa9*S8cNe0hdX1#qvIT*}U~f5t8#DU(_ccYaOAZsK&bPN_r0&%> z6Q!ASH$q3}5YuZkMEww4e(=>-Jw#^XGvnrB_*hm!oWd7V(Tw{fjiq3%-IB&vdEp&>LAm`J$79 z#_Eqb#zI5EtG?yFCVr*uRG5p2s!a6sc(m%!>K&+s3pa|4efwznYYI~|A$639Qd3<} z9Any>xF|imKa*_dtd6Q9jLsz39XotUC zK-BMR3Gs8truc*}4>8qP1J-d)*$KS(bPg>#HhC&NM3XUsAJdcr88l|lOvu|==J5pq zP3Y$!_pSrz9EAK`n)nP2UpOMp`rB-(^0uCbFq)N5~sy~|F&X=WNJ;eP?u9fJ}WVPi}cx)Z?4amvlV9+9(!Sk zOS~*%XfYFg&(w2S;(zK3{ZYYc!MSo?T0HCu%uF$WGY5m~ra?|O?3uiWU+q~gT07gi z#5G;!EBzM!YWRpcy)b3}E#Ssx`^>+}iKo+wScHZnSiZk`|6PPA3(K&Jf+fZe>eMNV zY3mLYk@p_$c@Y4Qnb~myA)c_%mwMc9fr#e=<)ORXeEI8HL8})e_%IAO%;+x$UKILT zNYIGbUX|KXZCU9WKV4x+o$7nRqH{=52$JypRLBO-pF5Pj$EvDw)U*)`RH=-0vSs15 zlt8ZmfZ}%-H$)}pg@yUuoZgZZ`&350;j*uBoI>~#;4+(?zER6^PX`y-68mhx_Z2?9 zvAv4#v7J8ekDUFVRN-|#__@t!cU(e9Gy^8QJ&K$pl41Ovr|AN%;mb4(7SDZKQa3l_6=isKA%cs6_iVcrAW^scrGhbDtdl2 zM%7M3Kp#B4B_&JSR>TxnC)3_BZuAWWU=7vJEB>qap=4IvsH6|nQ;S}bq*qlir=h5= z1oEG1T&HJRE};uBpMiHG(P{}nPw;0w(bD^Zoy8)Kk_dn#i$CNEN(A2tyz#opSNQ@1 z^QYJ~>8Fn#IMpZXolrmEZ}UV0^VXzL*W$(AY#67%Fy!B-kis>Eab*4QI&tap;LTo1 zN7&Oo7Np(}$K$hAzj1qY-!P%7YHR(_zCAr{%WH2<{Ni3-26pMM?0oEQ@1HL%8g_Jv z{VvoDUj5D`PQ`c@3DI^;y_|K>;|hb3fx(puhT>t-^_{MEr}PMwa_Ut9%CZuRpww*1 zGZOcRq+JQ(FO}`iqAsE&ZxRXKIPk>~3-g8)Y9n%l$t}qj(s`8}La^W$h%cfzn9{z{ zYWcjd2(54Pm&iD23W$EuFU1=9wFE3eCU21QO)J&|*g&W4z#CnGoxz(BNU&@XAqzTn z*^Sg1o%7a+rjuOKd58E&TgWqRZg2Pphk(!^-bf{yvuJ7bqg%w0*jS13%P?|JdOFCr`>EaKgG~9 zTv&-76RRcSEVG2Pij6yTw*ui4rH=r;bFHK!S?lEPQXPiL_!YaZrhT35 z$@m^aYy7M}htaI)VENjP2wmK1m~3zL8)yV#k+p5E4`jyb+kX=~dN@#8PFpgkat6ND z(zjH5>~i`VzVv%%&UOWSuJPi6=o!}Y?sC%0LwD(g1aRc2g1R5 z)*=oOoqdC~6d^N(IC2^e7@Du?4F@lODw4FP{|);lGtt^#oE5TN{0ta<5Qw)U7%rMb z5#9Ay1fmV;tzf1RWIzrR;svh!mHG0b&}=+Yc<2g($%xbdT%i3^a=}kj zK4AcOn6@Zb)rdl3vWyhzaD2Gmcl%ykDee3(Qh~mko)+V!Cx(ZoQkSFUy?*h_2|(Dd zbvtyW+Du%IHuv&(1%q+p)!ZV^mknK6YW0s>5l8a+B}c!Gjz8?djKika9#?`1rFm|Ul7)y8$(Do3xvVcw0U5YjlpVpCIc953zC9OQp zsVMlphf?6i$~9o;bWxmVh(C}G+DM(@7nxSfAhqB4yfLLWiEL;K$#BRX zQA-Df$$$vlL)OOjPQZQ4&5W+EdSFl8re2AooedYKOgcHpco^1K(liQ1hIfrF1L};? zz>f|F&r|>O*$MXU9_n6ZK9*;#G((owoJk3MUSwa#33S>{IH_<{s%wIp-#7cHbOf^4 zN#@C(yVA7*^)h&PwN|G)d6dp(zX>(CHny4=UwZBsvA>h{sF?{9)pA}=c?L*K)(3Xs z)7suBRA=rW-v#UX-X)GQ=3Jxd;MhzoK6B?BW|JomM;V@D;7uwopb4LC2ZHgTG4oPO zXeHyEo!}Qf(nTSL_?R|Xu|7C6Dktv=Y;VoC+}q~q-|yniXNdCEbPJ6zbb=GVYZ`KJ z;9j=8zsySeex*LzPZ3-s*~8$9u$vYMG7NeO%^hkCAl1`U_ai)l4s)uXankY3TAo^! z8b^R`PS$zCY-mqz!?C8>Yc^*wb;K6Pb#KsPnM4ys{-^-_843vC>MjiTsHOd5_cdS( zeDeR+Z5o8V(}Qv*W0u^(@_=34VRMI2GfNm`Be!F~t()98=Wjbi6@mJ`>?M*f=OX$g zGIxVGVf1iDlN9crHJxR;L&k+@=*Z#MXC#;_{{hhHWow|#k?JDB-J1=9SYRpo34od= zjGgN3D~Ses7gau5pte+=g6B-PwDlW`tr;kg_}KJWSqPunh$32V#aeCiL)txPOz|)b z>hf$<$1odo`A4-ua?4Z47^S;)j=&oNq#;A#4f&*b&QQ{g@x1I|?(``1Ib6w*(QymY z$m^W7^z#>m!X}06M(-nod4QsI*KI` z^ap0y|0d@X0>NkAc~d;xwcc2R@l{dh81?G*X4o`g(FSK3K<>9BAe>lKG~kTp7UzXg zg?}I59-}jyf|Y5MP+m{V%jUd~-)#AM#MdKI&XLz*va=9pTE>y%;izX8aG~HJ7sNmjQ2bO31IbH9K@FQyfsC0jN!E=DdDq=aC_t>BO}EPFywlN?%;HOBq0 z8kv;G6mOaBL zS!jt276#zlgy&>Ex_FjPGKQ`tyxAw5QF<_~HykcfnTF6cCfF=vy4xW6~i1PFvIl8xrymkr*Y9h3OT z-juzFFJ%b$7_=p!{p&F$mpgN=q}U$(09EY=<1sN6?B8t5h)ewmAUFeq=VMB2PtI%~ zry9^dN9^s0uNn+t;7Y#Y$;{mm6!`%Nkjs$P-H)Et7X?I_fw^KTl2SE+osKhO<@#(m zWCz)_3Wd}coWDP=J_yW^f2a0}k>5 zQ?=Tq2(^#&z{>dW!pzq}ZHm;TZ-;43%C2~o3DzuVq>-6OV;?=*Q;L!By%h+U1yons zVIY^@iW7+wZ;d<;rnb}W+?y8A@Hr);DlW5B_$RK^8`~zFFyLfL4)wnjim$!MJUa)- zg7PPYd$z=GqBZXstU1HAC%YT}c5w{9*JPSi`bqNnZpW4nRUg_w1X+2iNIHfBFm<|r z-ls+COx)4e#vLT-Q~#EyTY=kw>fIb)M)qITpFf?!vm^c$Q!$w3f97sQ&Z37;gTJxK zYcaGRf566P#@y5=lB(Ex-DX;?mbFyOHP^DhoXyqfNTS}*`P6_Ooxf2tUDBsGSmS0- z7n{EyO~~{7;JsjpJEd_ah290Ot>ks@{}SX7?GPlPjXKC~Yupy_F1ZS#v4r~)(DfS1bL)jB&nMP42LB=bZoD|iv(vhsjt`q|(kp3mY>2bZs1po-X zl?mx>r!!j_T5FGR7AkwWbQ@XWsUv6El?jOkLfI=%Iz+Zm*R2cwVimruj~>7Z;oCp1 zu;^Er6uF}R7D@_=^qlQe!JQ48<((o#{|3TBEgfZ$bL?s&oR3KsQ1!;7jdV<&3C7I- zMBL-5xD%l5(e_T`ZYFY{W7Ep8%Ab;vG07zlmWS0r5VP<=rwTzw0N)d7f;b8I(E`b| zhr3$r6p6Kb2@Y&1={Zae%0y6Lp|XnPwZN7SXHMh+-!S30G1K@-I57}5XumJyX;+?F z_fULXca;6rAX@C2qV430Tk+&iQPnK^$e}=ls!>y#v7J?-g^Z4FUaZWnHbU2^{MkYv zb#*RH;fZaBD()?dYpa&)r>nF=)vSAQw-Wexh16vBdvnf+Fr^DEP+k_mVM}o+rVVS( zm7h{oZMz{&)2Ok`AJAGG;-Sv@g^_D@?b?)~7I1k@dT2s}>+M>m+5Oq7*t`uHJY^74 zqRmtTzucgUzlGPAK6)8ltc8RGNrKy$s0fuko(P_z()XTqy+3$3BtZLcu(d3q{>5(R za+@N{;R9HUx4evNeb${J$qEVxjs3t$CS3g}h}7r)E?o{w``R+<6=j=#a98d(kD6@t zF-;ez-HzPmu67Z6b=SwbMlJ3JO!y>92*usE(+WzCxOhZ25t_BarG{uivP+rRtGgiO zEx!>%9huW{ErEEgkMoHXBmHe1X>~(G(8}0R5JUU}K1{=l37eRR23+VX;Ha)D>KQ+h z7VsvmHKtBo1ZhHRK}?w3?{_cV5nltx>j17Tug;5%Md)7><#`*^^#%6GfA4yvizC1Q z{oiYx`4DBkf@{!OKQ;&%uD&3h#r9`Qw(H=Wx%o6^Hh|?A7^LNi- zPH;EW;agomng-d&??4vaZ(1UXB9ET4x^|%FQt5myUDf{~z9W?3R*!a~_>MpLjKZ(H z;gS@b+7H454b6mF6C?9=Y1I0(l#9>I%yXa|%kb3&B&i%MKQPqdgPGh0pSZ5Ve4W$z z`4zDSue{%{`_O`@D5S4OeR;S1r{X&nhPOX;F7`rq*ekcK+nmpDxu38nd{@uQ{wRP_ zsrIAcLz_b9Tmru=w&RRDohK=j<7rSb5LL;15ja7LVFH*GVOBJl3 zjSr>YZT@fkx4G&UJi{N;J#YT)+HZijm^;t`0+Ue4*Zf)FnW^Ml?LMhRfntTip-p`e z<}Y{E4N>MuMJmzAO`~#SxCw~_Lk4yuaTv^{UBRz;RY2rzIv=DP z!kZQQ80W0BB0293H*OwGGTRkoyf zT`Kj8ZG(W}x6~7J#cn+{KOzMg${wH|^9$U0 zpk>h}7Sb*T6fx(`%N)E7wQejZ4kj?A$y3lp**B6F6f8;*jY5JLIVv70!ZSB!RJlOC z_OF~^Q(nYbR8eJC*ywTfnjV%EgF-TA<*Hsh&ZfAfb9- z3I(crCYH*Q@=yvO<2Hbg%p8UFumGDl|rVzk&B5Tana&4Ed>;igZ%)kU0&F!LQ`&@Qs7$^2|rv8FS7f70>-_Fj1QP2Bl8Q ztRac^3B=7vFX-L|&0jpN?pX#WcZ{2d(>qzc_!6_g1mKIXi{%C?dcFFyxv(wHr;pp( zWw1WmhCh}(08Oegl?^LPtML)ai_NsALA@_j5j1$(!Q>K~w$l(k*gRiP;;t*4yy*EJ zc~>tX+?l9o0oXEH^hqd6>NL$GHUgr;4$!9&Uh#h$d$EFNXKeYLJfcF35S0Isw~)`F zTc^H5nA}u~e zHM`jPXWpxUb*pJOC@89Q`e;5A^zVu>yB^`Zw+Q;Ui>_wVYvA$YNwplp39{wy`s)=& zYpSrS-fA@E0rIo9N7WwQvFIaFqqHxXnHM=u z@1P1;zr#?u&0UY@TEF4N!=Bo$tGjnRTDNk69Q2Q%4-Us}^h|V5*!CrX-eG6UFfy9B z>Ql=$TU!b@0zuyv@cNRC(NR3$~1%4WpjB_Zm+AY%*%=jJD>OM&t*G=+X62>`(JFtq%$`07fDCn zZN*iO@@PQoZ6xE^TDASj8R6u|;dz_r;)^KPv9Dtfthvt`z@7|m0I^PKf7(b7cgi;O40e)V4lA739UKxIa7f7=88u8K z`cfo-U9jK_v$Yh%Mmq1AoKDY^?Ab(}Dn*Jc+2Tu3Vl^xR<|UH}C36fnF5jPh+IyZQ zy@bNm?1)Aijvc9(K#q$7UqTh}1c52;rQs2yy%Wd_uwj1n!z!>EQG)P7o<9%dzu-~L zGuP#Y7~~r^Y_Y56DOm1T4xvrBt!+bvXJRm?j(@xxE2@wRzDOG*#e!%Iq*_8l(sZO= zBh!}O59+|`d>c3TO)#n0@R5gmHVfW1f@W>5{((U8DUaQlQAVi%)=_&dlA5u%iR#GY z4M^=6$=I%BSmTzVHTtd3jj7jr^IpF05#tg)%w%{!udMGwEJ_yDSy0U5+OMw3yDX&I zE9RPv`qt^G?OAiB-RLwvVH|HlfLcgS*zFf^9bZ`DAKw>=0=_m_Snte+T5OgdUtEIh ziS(;5sqJ-1=9{DR$K-jb3EPog0nE6Mg07hxm(TaGXmQ>O=EcJ#Y2v zQ8o&p^D4acUd^z-qp7poMEBF1jG*Uwo6-97QzKJgyvaQWArw7Dfo09_lWbmuhH{g; z{e4#@Pw})|!CPT*!~9xnWnrnIs`A&P@}WqDX-Ktky7^KV?E7scBi|42#owM0Ls@uH z9p2l*V5DP2JwRp?Ks!R9E7U1c;vMMtSp1J=CCM>Qg-A5JHwNe1a_QvOc4O9t>LZdMI78RnIbFig`1xKxx zB<6*%(R`Cg-!c+x3Jh^O@*%%*TsdYL!VN;|vTRCWR~Kw+ z8`bD-E9!V=@(Bk)ksGp=WRT*UBYE%T?yaYj>UEtuh$xpyCIRwm&5{+$0QIR zh!?e+q2gbPu>-~L>H0`+r)FP1uZGP5yBEb4z@CLmQ;6`9{c4KUN&D~q@L2G)oi>KWDg|-s;R%(8gSWKH?+1J1L-P2@mnsVI*d5Kj%j_9*Rt_JFY15r5?tKJbtVI^@g@#=60n z|EmmZu9sh2=9*|UKXkl$ngAlGATF>KC~LnR`Q;MXbX_R=w|Tn^;?=J8>}|)y99~nvZIpCWZS7eFnPA$*dP>JU{h}n9 z;rYmzL$o#08Zhy8MQqk!Z9+PZxcJG~bKqC$vQo2idEbAM1U|{S>~zM4{aL z(PiokZ!Sf1WMCJky<^5AK^j*6rNFP(aLxHZu^bv?8|%%f-X%5lTB_i1{{7tqrSNHz z=i@`jH+gssph#tVxaO^p;Imtp;+^u_|M+_Uv`7`oSKv5(91@9^&(TiwD_oo!v)KR# z^iM6A!p2J7pn%FH4auwzl3&KJH_#O4QMOl$Xs3*nkZa4>J>1PELYbPjwmSA-40?PAfty5fNxkQV$gK>c7E8JTd9`G#7U_xZk-s%1+nK6JaJzn zA@ud0tyF+77?P>wclqRgo)=nx3(M~6Ct~>BQlel)YHwDhtm}?wDjDjrK8=4WuRiW# z@fDOij;@{(LwG8I_5OZD;adUsNkoA5$*if4_`M3BlSJseQxjzk+(!P#k0>;KS< zlK<<$kCJtqm5L;6U-I8sUM=5pm)KAE{Q4Y&)D3>*yuA*YEt}L0X0+>(t$CL&3oiVt zR475#rt^?~Iho7#A1U0-%A^Zfw(|1H3l3rBY`-~Ug@?{M+r9&PE;>*^SCqnr93sDY zY7+16qHd%lN93nGKXn%2=bv*K)94u{GCZJkg*3bipIs)ZF;q+IEDNS|vL6JC7{iXj zWg~X)jXhqy1)mBvyE-~Yxd_jA>nbw#3pv2g^8!xiabzm9lnrQ23j}9s)F7nw%0{M@ zr8|pTH>%O;M|&`&UG*{qvWqQFz+eC@k)ia+%0U9_0st&qNfv_IpU7>tFg1vf<~i1TnLFpa^rGO7?`#qMWXij}P=S2mG2 zIOswwI0*@{b)^%IZO5q?8}4?X>0ynREeqGBwE=L1sycEaw`|1SAZN8^`SBkz4UD-B8b zk(d$*25#ch{c=n9XD0gPPN$E-&(S09!illP5_`4IN>1 z28wO;ItZ}SpPJ=uicjlVc<_G0hEn_$K_}l#ewej$%o_wfrnhO_*7hZX4nGnvccW3Z zIGznWnVL2q`Aw&+So0T4d;a#i!>}CO6|dSK)kd$>c&I-j242jJ(rP);rviu1n0~zwGBOz{l%+1_8c_Z)6y=Dr29VemPatYXfTlMVkk!uY7BE}P4 zRkG%P@n}U)yFlP!#~6@kg4y(eRUCwEI}^s0loQbMAx(DTCE*mGG}DwK0>N+hlbM-_ z(he@;)d3b>;`P?*XnIf0gtI!E84MA?tm{Yak~69DT-e2Vb+HuK(lwF=8qV8W6whAJ z$2CN@&XhI)oT1CTb>8)WR=YqoN$F|=~&pXe!0Kc_*CWrNeD8@G5l`HIoz0hOYoQM!F-i@;1Qdtk{ zygK`$Np2?tt~S9&K3T_T0!ZF-I+) z-BZaseaq2627lTlr<1|L3d>JP@vLv-8;-5dy{4u9I)B3Xu@d$&&=sjep+B8T6DETG?u%L6)pvjjW{A@8tnZM~2#WB*A z=he`PEm#?tSWvQT*l)0{DjI0ogUbqLxsg}X7UgKwTmp-- z;3<3P4Isk;iax_&C4r1Tze%pBnkfen*x=UiKMnGkmyf0BvJ|VC@^$xP_&ptlj|?vk zB<_(64e_T4GCmXpgI6++w4T(KybfQPO6T2aUb|tg#a`#vL|y$Z**bfcg}>1+qfocs zV)yK1Bg0q)(|TCX7n-YbIS(F)9FKi zQ-AJ;^1~B{f1@8A1VXd};Hzkx_*1+%ogUA1L~y7C)XDIjCGA12nb+G-biu`PGSCiQoQkrAMKTn-hrt1&p-YEvqPdr#Xx(o_Q;!FrKvP)na2JSQOr_> zPWSL@#-!B7LvE_KQYKl@;2dt&gm31ZK2v?B6f*sCo!YB~W#o-0e{EPMee&FNw_@6E zqH@k2r`+{W(YyXArimz>95A<{H+$(u7=r`!u)E6p!gGk%G0fz&3w} zZq9GtG-Sheh5)Tq$KdYxURw8FpL+3Og>X}-bny6{8)aG2%l-8}Y5Vma`x%fRVf)el zwA&)G_8C)?dH4A_A%^JZrM^nYlMFn%01h$r=xN<}m{z*=>+)6Zxns41#PyGzlh^MI zi^rcY0oxcv_6~Kqa;N36(r*y%8&9pTlk=X!*;WEe{`3pmzY(S!Q2^%U zIiv@KBB#R-m*(-`UnpOpAs){H7_A}UyXI+$*Abb&nlZ)+Sj0iql+7~uojQaZ3j=O% z2H{h+y1V)2kL#A$@7WhmshmUu51K12QLd%NZJ&}9Hx0>7F>U7<%V){0R;zc<*Z|>B z=OwFmaxNGW>V?}iwasjMKD+pW^5Z}z+85#MNbI3k%I|oUYjMXj#pxr6u@_-gKdnmW ziTI;nHQq0CZ3XjC*HFyz`6m7L$Y9+##E zGUHloSSF0J^%T}wzGLS&tYR@4>)WkSZfVw5O5aA}znLF}+3vefqDr>>S9+>=eE$aY(?XJ_>Gj!dFl`=m%F%xx z`{{TH^b+oRC+Iu-S?~~&tK4Yzbo}(!VioRh#_3&T`|8vNG+z&}dOR@t^DuvN9wI?V zg>PggGcw9$?1^1T!q;uZ3eM}Y-{NNA!eGOD*);wmIt##Gx zt@O_{hjhkn4sVZamrJd4;b)UsZYouUl`i4nWvbB_Zi7$-YH!9;Rm>ro0L>G9ARpuQ z$32m>%=c?4lwL_6uT}fT-7g$+le2T-uZyORq=36E?S7W8L@6(>>arC%I2c#hInjCc zPhzeutbUY;V{o1@Xz}ow+P6GU+tcPCge_8Jl8rB0Go^c-OgpzHw7w`@*vV&0z(EMZ zeZ>Fa48McDd_0uhi*(VVL(7a=WCA&>STmpQ8nMB5hNBX(ai`ZThK7o8 zomP>tjZy&8lziMPYKX&QKwij?N{rbmVG0BUcwc=$`X^I62-L|g@MV0t!d_hy2m735 z+_{n4&Nd2_)ayitBkSPO0PH0t*RZK4;p;9i{S7y2Km8x)$VQV%1;8UW5 z2dD|1UCs(M*#5ym(_^;M^m~1Wu_{Fs3lBL8aVkH7@=j^cwPI%ObLN4z%;X^G%2^Xk z8s>D^xRH!>cuzTEEW6>z?wi<5CfD*^?@EfZ9^huN==u zMoVFY&NL$AuRP42cfdkZ@bc|D-i-dVws{L|nAJ^LR?Q#o>SaUjclE@C$^koS2Um$HyxHPIGF=j#w}IWJ9~V zOoZ&rGTGgSvz}hZn{i+cuoo6%L5K{qd44kSXInVU{&$m-PjAG1j-we@!cH+Z zu&)`AL$0CwFVJEO#rPx@dVeha(imjUt3xp7@N)vQSxXE)YQk}OPAc_4=lgFr4 zScK=G7WO>f{Y9&dHxOqsNLbnFVhEH;HMi04&%_!Zsm_~Xfzb|iMlS|?-O_1}AC{%i z5`Bq>Nciq<+!{%YT_uGQh_eb@N%m@8$REaPh3QxYr8nqtw&6tA#=)?gMPl-!BN2&*7%> zo|^j*4v`|M3b!qXu-fwZxffw0oo?zc!!6^xTf(%8`kPpu3!KrC{&$DfdHsssONQQgCJMP@TodP<(ssGS_j1{?_=;J{;!XGo;$WZJ%sj0Ve7Pwo*>ksrV)gdLw) zgvQxR3iv}vVC2|j9sn(;0Sm*XL}yX=*hQ0nabnrqxOhi#I|EA|Xi zSOrVESbP!nNj}~1Er^jG?P8w$m`3S|UG$iS8Bny0FIw$m+EQco<3*>Nym-E!Zcm)0~+<4`R zlx2av8>I<28>4pYJTFbp@2rHjakGJX(KXA*ZTf?pfAh|Gp~wjdi*~V{f?N<`xwy?* z>*nU(Xr#-+tFBe%_IXS?wwqfx{|^8$K+eC5Fj$?lA2}clTTb$WksjW^E+8<7vZC*=w*Oy(ExtSw)LcUgYGC)olC0f+%FKMP_60olpB-Phl0S$)*7Q47?$`!si|o5T4WyIw2c|o`ch-OqYZ`B>ZH1wrFO+M zJx!!Fr59B+YuU#c!eezd&+2)lGGrOws!LgG?UVGSc&>J}vf-)-h-%8D4mV=W8e<2A z>XJ^-b2}TAv)gsa=qyhF1KgR9(uFgkUt-TV-3JSj5}K(*IOC&~mC}pEXv`s{qGGH} zlv4^l3ac3sQ)(*{jU`!>1hksdMNbGC1+OQo#VAA!GDdr@Wu6 zOUf_|g|^F;g)K#L!&@vdh7fqDu}8)W%4Re})(JmU#9~7Um&P$-HvcHA0gB3Mag-Q$ zWix3p1}Gn8V6(h*ltgC(y@>50QO1{}a+{Qn??EgSxtO3t$d#dVX*BD~vdUrCqwVZL zfPAIWkU_htjU}=TfUjq0R?20juS|+fNG8PC&M-#w9VHni0w2qiY(GjC;-<_(X5BIh z2`oHyK}-A$zjA{GQB+APrq8M_Jb5Nt9cQE$NpgNU#dBSHjGCm|xj z;Yy6eYBPv>A_>UqAi5O1C1m#T#0w;;gpnxl#HdjIv?zpYf}$vy2qt=Dl1RuZn0dWH z5iCS+(hJ07)ftd%(;>Z}(-EIRsg-I)0T~TuY!R{905uANjz|Fm?~w(bM})VKmNroo zY`8%uSVRdrBw^la(b>d<=Su>QfjAdYvx12k*$|N=XdNc9*&KwH+f6)g(qT731d$qo zFfU@Sm0~4W2f2vB;=rO!r+0~hh_Tt^AVRIqV3Gx^PYNqoFiKeP3XssDv((!Kf-$eh zB0>%}G?FnDj)(R+oJI#Qj7eb`eQ>8^H$N zC`xpyFmhT2linx_7#5R2ta=M?#xQqS!90;%y?Y*I_}=i+Y8K7D1BDIvcNZitIiB#>QGB z==5f@UO*Nr5#4lRttQ?ocwj6IRKday73g7v+yHkq$f~m-lNH8H(n}C%;1SF#@8E?R zUQZB@B^?YX47b$_P0%BYB-r#k5k-?oEHIKw?vW6(K^Kh3C-X387MMm9i1ElYm5{g& zVahWJiK0&rn;Ff69Zfa7;N%I^COK^`EY>;?7YrH^cbKRAOLU$o7n^{P>5AW2q}a>REE_LV9vxQI2*^lMd6SHr(63Rg@#(;&lOivJ=M+8C_WZ@2*2TO zefw@rA*f^b6q`-`&9{UHZq!@l(w)ffA$jBqs>zCvZFmSBh|RqH8I7?N^cx$D$A-6% zwR0U@^*1>+U5;8fT|0q#38sUn{5!|DT*v!)j-vi*p65ouMI{RH$Fc^=%=E+GNUqHK zq9!o@Fqwza-vZFzHwqk+Rdq=fQ+HJ9n0+fMA>1g}s|vGlcZO3`g?P$!3nqUbeFDl~j#E&{?)S6>H`v10lK0gf+yTZLZ5 z(~qMMo`JGII z26P{~7y=Zp$rPt|X)F!87&5UhX%)OtW(AD=ZsL6Y*tlHO2pG*pQ?R;O3R<_IXtI?Y zvvV$U)41u}3~o8MmT~kcfnw9R30Z1bd*ZKHmpF9guURwm5lm)@2@ykHTuOnLK6%;g z%eLMm_V4VR*(dO0KYMNHTXOrIw=d~4ls@07jZW?q0KC^tgCjP zxK((M3vx5L%S#qhfE4!gjBEo^Y}B|*29=G!l*6)R5h3EvaGEy0w$H>$b^uBWWR%b1 zW-j45-)p{jlb-~Piqsyr)_6_zBjHaA?457|BgPRXG-uf)cKmI1{p?iOm@mWuzDbL;0b9i%qum2}NZ(Ij!&dhY| zgVgFfgSxCH-CvTpX{N_O5XI7RNOlT;Z=b#Sbbj;fcJ%jL*}PWNn^WIW-^2f^zURoV zK7aS_^GOZ5w z^yXc=%=%f&5AI#IK@u99&)awZ-sKx4NU6IDf7v42%z3{+e5cp7B$lqbWI;@OwJc4v z#1>q#PJ1ECV9>JIODqE5NxvAx!?0rx=>g}n@Ln>QFaG08*od`5(yLzU2#0JrK>7Cc z@n~Ax!n@Ne7Ol8(;GXn~db581e7(7TMf#qB&MRVzSETM)*ftIEeQ1wP%Gp9;$Nr|h z$<8o+6g!i9o5JjYhdPX5hpyF2Y=9P_e-GeXPF;GY{o@^s5z! ziw}=kYjZeo_89c9ZJn)Qy7kbX&X12JY(s><&imtMH(vF&$UGV=Fp z-gx}6>+l7JZkyRqd~)%nn-2~UUGK8oir(Tky$yBI8uYNC$7V99m-b$}Y;`xDeaS=H zAG?I;uKUd6|8`CBNrTDOZNL{UJiPhxfsw!WuE;Ix#j`!px{(8JxUmt6~m zZ5SitNA)hb;F~Kuvme8wN(9+Z}8l< z_^Pki`N6SQ- z(!Xzd}?xmkFpI;MKGRxDZ9w|Z)wFQ;oa%xttH zoIbMpI@1E2dpvAUu1Gacao5y#bS9@SpPN|TlC9}dzom_t#jcR+FTS|($+$_54D42~ zP;ah8j2l-{r301bHnP2RjF4kQQ;^AMhGDgjNKl0ucCb}02S~7FF}Hjprzy2iyg8lK zB$nJIdv8<D9Zgoi($s@8`2Obwu7l zk4TN~w#d9C^OxLs?a~9&tvX6KUTXDQh0xUIp3eEX{)JOpmp0)1=(qQBp{WW`ZtSwx0!{f~``XTq)$?c0>~XaCJZHFA`s$6@X`z-jyVD)FnRFKO6>a`#WD0Ir z5Yr%`JS;VQK?$zgS zTGig%CWmFGWCfaAX=uL0f>*pcuoGzgsj>N@mFO&@)9Q^b=-+bX!DqJb=<0UaoHYQ#$fXnadfudlIOZ;pv?seig@QD?B#XAg#b?H%(!vv|Xym7O!4A%w|F z12N;MS@M{WQM7ucxKUB>_|BCBEi*c%2ZAlF{R2CeJc<^+SQ9>VTX}Bm9A~J=ag6`2 zz`fk#n$?KvzRTnM=zrKhzP|C_2&LaCulhuNm3wTA%1s{k@l#g2DY?t!5dO%QWJqJ4G)- zlf3z(D6&QU4Q{fZI%Ut;U$)x?k-ks;@c%OR9`J1xY5(}nY*AlHyK0tfS;dkZ7df^p z$=!!rIL*cGMgkotJRvj&dA5yl@2{AXrY#U%;%{{O$<=MS-Vc6WAnW_EVwdFFYZ?|1ofw;TO|^Im+hsR{kje^8F3 zZ&woZv*g0T}kk?WdXO!p{9pj%0hwTDDj{x?w$YI>fP9pgb` z6)zi_W47>2&@VehkY6N#$%-EmWLjtp3Pm6?BDsKX>2;92-Jp3v!^$rHpi3?CUVVth zN-5T46Ld)L@R`; z0H8Iz-H35b)iGO@%ZF~_OvxYuIT>bZ7K;H7L|C=QVMYX~h{iF%vJpaI!IVWx%%K-m z;$Q7FXUCWg*t)}EOWcw5Ya2yPrKP|5+@JSt`_q+co;-hXdG~a;8tNfujvTrFhWq!f zZJx@j1NK-=%lv{BX68*PgCIJKtkZgyPWJsQRKNF|1Djsi)zG{1;`YAVJ$jF7JZHBw zpLW9scVGCxR|}f`TNf4Av~8N#SuOQUTDusW_tzt`6)0D?t~|LvQ#(N>2U99X2H%rb z&Oa=MI9)!^uBouDX?o%>lXg7W-}l7M)5>Q~H&_`h%b9E5y7&5fFX?Z>m9s^wo98)} zJIqhz#~E*5=zBO+2SR_Ed)v94^}RbTYFmA)ht={GX1mz3@W6X_UU1(R3z~de7Zg`d z*f?iOwX}TY&Dmh&oNdcRa|9A1yZ2K9>=9NVL>MliTa~R#<51Mk&zNAeLW`~ z_<(kepBGzk`QIyQa|ZV~YGeK@U%9ez)k?hj z^3FD#?JRiFFzFW0e|KppcBz5~Y=L>C*dDuzxO7`c52NGWsMi*-Vlm7gjYK0>_O_o& zKY#mr>6;g~YmN!xvr0@k2`K1#%&Y+-zH^3nMhB9QL zWeBDLDh5M|QUW7(CPYG*M4v{|B1nm~8LS7SHd1s#zE~jxd68ZNLGknTPm|*hCEQ1N!0ZfoG%g@4LIGMr+ zmFEtRu_>ach?n?B1~4Dw=(%+O_NJ2}duBQbdu8hE?0m;0j|~_^57T=rDKc;5bCKZw znPO!8IoHTm6-Knv@HP&PXtv+wwZs^0NS=cpcglA+>_*D9G^LdB6z`56`P^Jgu@fVb z<9pnvnSU-0H)NJ zFYlBtU80>(-W;=|={eS1K0&)!dcfCm)|}~VYQi$QVdzuhiSMiq{(D7PRdsb$*^WPi z!2Fq4N2Fs3RaH@mAe0nUsS;m0%C2pl(bq%X`6FmNTSwym$`yQz^wg~Rt@Erp=_w@kgHC8En|wy=gKyJU z4SDH5f|}0d%R8r@e)`Zy=~tkzX4}MwJCc4MTm`-vKmKaZ_`2dh569TAC37MU$u0>6 zF$6#auexEM9x``usu9cl803#Zs`>UerB7~sNP6{56;SWh8cnLscenLDw{O<0eb4nR ze|*y3yp{RgYk_#}t)TEtx=?yW`sB^+*X+?2sP}20c3B_F{x-U5a@)SVmHP`;t>6A8 zDr4z!EB80{w-|TII}ErM2dTO_9Q4a7$66Q?63yC`E)?c4dH}1e9q|kaFJVI%|2BgM z`?tVa!n=EYu>3f+i!bG&l`%1Dx{!A1oPyI(S}64uYBV;Tn|24aCbQPeSs>4YC1Yg; zH;$2Y7of`VD%ILRG_WoZ0N65C4$!lBXyH&MlQxJh(AhK^vQlP1x6--LP1We;R)`*h zo;5lvD%BWScO9q7QC&hg91q#27_+xx%f_@^e05fs6Jue3BiV_+2j&tk8IdF75eG~v z+3sV`Fu#K&VL=8udGp;W&Q%jut!nBqS-NlDXE9a4<>XBIHL`(9zRRu<{YNkMi&tPo zE3gi9eRCxsXQn}g9{C{H<*ejgPH8tgy=nTs((dU^n|L|LYh<%k&X07$-YNd&%Uv)ZmvZv*7ALizW(TE zd%rjZ+`_T%PmQ#&ylAwyJE0seFdnJmj$d0+!RSV^P5`b9R z3o&|MXu^M@m5vxsH z#uS9T$-szRGMUNv1ThNF8rUQRtU;fO+>TD(`1Xy#+Te_pGrTRdS2XDK)e9Rs&M8+} z8J$_sF;-RiwoA8>UBOIt&*^AbSgqF?L{Lc`2lIY@IWP>~;{|D|tfCCN{=S$#+;`)R zeOQF4nK7dVcIbizQ5z0VZPJ!-W;0i!ZJL^&4u`d(frU>2^QGO_{&^pS?<|LKITlKp ztX)NoG-4OlKv=JAOYx3cEb(SzxtoU*qmb2m8cDWz-CaszhQ>5m&4ejb2MUx+??EbO zY^f_{P|9k=b3qa><%0p>$>PPP&qVp>rO7)VkeBJPX~kef^FeP`t|WXgCaRQLLTr;H zyj;y!mWnNf`Tfhsj>2mMb|v_ z^QW#^M3a@*a1FYfr>l0#c{3|3XP!4@)l6N5?xt(5xe0A%uDWGob=T&a!dSrN3e*}eH%vhT* zKO0+{Zv}MY8PBxM}naZONuy`C2&(#D`yl)gMcA*pdjen*sQMx9Y%iv4#@de8EGwJ4H*Dx`UTJx)rMR!JxFvC*e^F5x{fV>Zj0$TNiUAnAG3w=lwi^lg=UnPeaIJq-lZod`{I)| zA^Gj$kYTHQhDZ`M*|3Gl^)iI?-5&;>oYvgr$8PW5;=@3FxY&!+{wA}Qa|S=W8y~8l zj9Q15oemN$%dOJZgCBo1nDfYdbeLdJ0)(2Il`{~tz{26c$sy1 z3u+pL?^Cv`Vr@1c`$n-jh;*boMY66?3XXat;}Ind5M)PYV2Db}E>Mu#vm}8IGD!>^ zw`U2B(#MdzC3`*%4yBgtVW~Z+O>=Q#kr7d1KRz;yPW;GVupbrtCCi2hMYi{mH%%%F zymF^U9kzS~=PH-n(49zh|L~29I?#WN>OY`Le0(smX9-5U#EUQo>G1;_q+~jUp3i7d zpYq`Lf`gc$D~E?(Nwvw+fGQhhDt9T;Wo$AA%kVUt&FRnQUY%S|!2jzf=ff%BC>Dww zN5jP7J=oQbO{J6Qvl#joe+0A+eJD_di0viLcmpHTKM>vwh(>SPv*)mE_m$&UL^K=7 zIJk2NtATZ-kzHl>VqR3B%4*b;X9;Di}avge^g*7EDju{=-!Och#$yV z_l{G!G>-btV%U$iB|S_%PrXI`k@^}*P)1M;DnavT?&|1>eRjltU<|J6lbsLz|Lpox zVXHv*7FNgk-~QkKO8z&! zH0zg<*Ix@jhI7Cl9qw(^3?kOi821rxR)hIJ(z}0b?>mk)VKffnwA>5Hsl4(emHTD- zCP<)B5_91s{y*!Zr|3~b*D^^D9A%y;;X9IbE6id;qyZ8Vn+#Ba!7Y z$F|odYQ=EtD}iy%h;t%&eOU$xe}+cFnthu!F&PA6n1MD(tg|uMHk+M>$+DaD8c5#G zt6xw-mLdmUL()1ib<6nqnIz_`Ol9n~OV>2A#4?lhN5w7$c)A# zc62n_2xVVi5V5n2-KI(c>0@bNFd_YZB5wZPfka{;)$8#jQ>moK)0@KkL>QU~0tw7M z!8!pIT0O0r!_o7)U>krPzvW^|i>{&S{FlMXeFB!-<4?j^_z(C85 zmBYhZO%@Oa2Tmt%yVUBu?TmZ6eVwb(qPxN$1nxGMkq%i<*6Hp}TIFjlpQb+Wg z!c8y$#&^|9l)U;-+qF!_P9jYpulLi_Js!^x$-v;>{P{ zwEOpuqNZgA@`!7n8w=|}nbW<50Vr3W7T5?fWXD-5vV6*)u`|%rhHfd@y#br}$!wPB zKTuaX*u8;Hp5O#b;KLibVG6qjkg4xLKN5cB>|-3K#w<4v^VA$9>yddnpQ`BO8E9%$ z!8UY*Brf*}PB5u-Vq}Q{De(!8Qv@$BaXdlR3pJFPAfw^$uThCLkfC&HvJr!s=mLwp z{F;k57(0jTwFmiW(b}$Q{jga!u3ttrOq$RI^iLaV>eOJo%x?H*osd-q-1?`^r%6BwPvlnhzJ#((#GkeDBEemE14F9g|_$?^o9{y@hI{M0tNk|n>CvxUzOdLCk zL}?I`bBQdhApC43tCGxRxs}CSmLVJ=1!`p=JJiAiycfg*-ss4JA;p!=u`lJ9i&)I< zHtyT#u~g||r}R4^$|Opc6o8;`>@u3l;1}XT1FGU`wmvL(R}_P_w#Nr@Re2CJMkn6Y(jZ+QotUf4l7Z^5C(B`^aFQ2NB~&e88X_jt zAb}epxX>-Y4Mqa{QKm5T@X+LjXyh02iOSCkyehpKP&=FjRqBFE?z^NwJ-)^vX=PuU zX|gZPwABxODGh!3;A*r5%$E;-I+AStjdQQN?p$;OberxKE4rNyQx$ltU%r}r`Vziu zb?!E3xE}G{j$Jn!f%22>{n+CIe=h$)-PDen@k*_#3Y-o#uB#OP&*~N_s4``$rAD_w zRfU@WZQXRlcfTB4`7?fqxQqSxDkX!?G|@L<(kTW1vzo|8LGZ+XRCqO!*edKdK=vErjT zq2U14Bc7KI<)u*`^xjY!)go}>Jf}Q7JW6ETJc_vHP1XSc4rujkOG-yV*iz9Jqktf)Wd*qQz!V(%*QqrSza z{94uTZdf>}FfnOE!)ocyw_d0utB311MpM7#aiARY>A5-^sGs+ z;Mku`-C5Lw%cvS^6153`hn&h96Ui@1hoWex)S%|Dl1kaFs9xwKs;kxZ|EgKpT* z@z_J}zEA)4Z`WHyw$4x^hMg7u3Y*<2u6|;zXep~c=g|FoE4|kpd+2}FR?v|$t$L;x zJo1wI?B~`?bx&`p9ON`~A?HwuoQ`4WKQu%&++j0RJ-1l>Vj1}Af7g(BZ3)RGWc{E- zX5<{PeqghVj6a2)V=X9XnM#2lB8E^Jk6Po#UPX~A^CItXAFe!pt!fVQC3$|m!ZSL2 zdCg|gpcx$#rQtw&3}ZcJG2xoAR@=02qI4N!*S8o94A?3s;1y$5VDH!~QH=NKx9DOs zV>hrmIg#!gyK*_-_-83A#?%4U3_K045XP+}fOVLVLiUpsu)E%fOjh&+B+3#58(G{g z8W)l_iy~+6l}8IXwS}V#VEOfl_wE>;2i$V_e(>@njIN@{-q;a*qO=J|0!(kXVdu^| zy&0&T;OcuO&omqxkxx2W_=`ibtO}1G;&!ovl$I(*b*MybPn+#59nt`iV7LYd_Yr13 ziecg-B!P>p8!&eQAl=&LKG+Can)KjX>H7Js&2F|!tx_x6*x32fbsnJ-{QF}|QK9u? z@b5|iwjZt4Hi5RG=HmOniZ&3HZkP1lfc}dw^Z_sCO!CB4m@;XcRNtwJXYqHF#K)M* z0qc8x81N0q*ca@%>7==o)!JO?l+CXdEG%U(xdfw%x$79^hpgWQ6RwI7memSV%R}he~12h^Q;?mZ=QwYJBi$VwA?z1Fv4dX`yR<$ zF-3qZfDv^so*Cz?cqgLzJ z!0ejsy0)-T`bzLyLHFGB4PQ%ND}XvcK*yv<6wDkj!wRp=yG{BZ@~y!Q$0?m7`#_*M zPLaL<$R?5(kUL2751fO6a==WhUy#0X0U2Hgh+kXLqvpdN0SF4@j`YGWs^e-?STZYUQI}$aKA#$;^tsTYBUS zmz39mgU&=ELy3(NNtu^M1|!QtUx1`y980Hy%xYp>l7n9%wH*Dpv-~3?9wO4RP936y zN*s6o?cIeSgm*)r5CpJwHUK<>_$2;exHQQ~6HqifYEi7juBCijOdI{)3B-RSORzEEQtCu(wGnqFOlG$uXtWG3KU-11whnl7}TH`H}lzi!#y})uA zw4x)ly5MpEc0T<&{5&nuOzn)*X4E#0i-dXG8fRe6nzJsgp0=09Zy@ZL9Fg+ijgy*1q84OWMAt|ft@3ENiG^)xn=H+j3| z{>EbeF?u(u)1)6$C-%g3qJLzazDP?9J-klc>(07#;)<11nNw8hgEw83V04Yz*0eWt zgt|$60MfV4XJw2zDuDggZFuR0^nf6lyYOmh5_G32=@IT*qpn~m8Ei;X!B!JW(sFBuSEMU*&B z9hSa7jD2qDMDio)8OI*kp>mG{O#Vn7B4o@)f{e3TqV^m`{wkna#wx*@seu-F?>D&ibgRYQlQMOQlUE$|lI z0oU;CtZ%f;kK~hm8_;(tnk_s_$S$+^<4i(IZ0q@3s(r=YExV#7eWBhI-L+-!igww_ z1twtf*j24lpQay4Q}ge?@VwcbPR!Qk?3{hxh4;^w2SPsE5y!^yVD$~@*-3zk@E%)m!bdysmOP2uv#VSv8jW$;*cbS1aNx8syCI{S#uU%g;xT4k;k?c8vn~ zp8tIK26~))J9JwRk=`H$p(l-eJ}wn5nq15`P(FOcsh$twu}p-E412E`@qFfryxNGl zN`jFM0OS@JSy=G?Xzcbe+JH2_Cesij-$CW5ddV+geys5{qyuM=?5Q9 zfBs1{db#xZO0WWYo&fJ1U4G}Cr2p!VC%AtpxN%+$6ul}I-BlCf-?TR=PmP)n!eQE9bB%^0*xw@DkNT5039r5c`5ThNHvYg4O@ zE8D-lUKXw!CLMV9z@!Fw=lXBkR~pr78|dW)=2J2@4Gl;GHZ{~Nz3Se3uUe{s@=1$m zTDf?q1ztj=^}BpqCt(lBNn3q)kpt;-Ejt&lG>H~L{{D&F;2*`Ug?%^)3#o!0K$vTFIf?20fg~=AlfK@^>OThzwf` zY)ZTnI9(kTnz}vM1>bhSn$zkv*0F zbh56Lv{MRueU6=`J(<*)KUqH)ki+sCRSxqh_Vddz)(^;)0sMBXWIo@tigHm=Y-!E< zyI_J%VjCj72!O~QK^O)ln7M%*w=sfzVl*!!l--2E0|x2o&v=X3aPx;cAQ+Mc3pk%$ z{j6&9}UQuZzO#HjobY~jJ|AWYhZ0)SKWqzx}AXleHq%>iFbAdm?r7PG{#rOSJmR& z_^MibJ-ljYO8{LoumR;;8=&_E&_!rxXJGBHc9C`ckzvYX_^--NvUGAxk5zd|VYr7X zJ&ez^YK#?yQ}}Y>Madzu%0tWOZ8;~dWIo?19L%oKOErWJRnAH8&Zj;_<0L8(eUv?) zD#X6kc(ii8y&)m4rp^@FHyi>ahJE9Xv1=4;R+6)u|Bjaelxa)4Lt?LEv z@Mh^Fvw=4Qzgap4JyKo5{7{(2cddb>P1Y_!8cLFG(k$2cU0L z8ic(|&=ofp7B1;M(RW{feQFh7OBGj~VF`)@c>!TePi+r@gin7iHw3g@Ex7cC(1>o| z3y=~K8drq#k(NXGMAi(;@=KB{M*zo1YchjQ5%BS>yhIU?g&-y`miI=Xl6?t!(MuU{ zhf25o^1{>WyxM!UMipnHEBeFtU0$l!J7I8Gb3KOgqmiH&n@9#it;>41uWEYYk9u0; z0L!=4Rt=PyS(qBuSh?{ZqBkp0Zel|LW?)8>H&DC{hfz=A;0+vTBT=*`&#iEj(;-MD zlVE20Psb^wk$*%S6Xo1+*@!7Qhv9}%t|}Fb4*8=&%`kGL7}-k9xq@9viEW~kvJ2)? zm@K_f@$EFw1U@0ZiRh*NVkzNrfmE^IpY{xM1RXJcjVO~mTquLYsmo+8O(#puf*s8g zZ6Zk6x1P96;4Z)4Ukp+%my{@$e)r?cM0}HFn{UhxPFbb|zQ137*6;J}pCdZ=9eGV@ z#%-Jaf+iy|xq^N(zf45_r2mP^)Qd(WyNxpfUgh^up{z(9jAxTEim-Gep_`aUSq%Ik z3*o4soLx@hg=T^)#k67rBmK6Y*6UctAUa&=1&E(ZceXCW4b%qdc3i0C?cnsm)k}05 zjxMKd28J*IP*PlIH8HHgp#RH3 zy%kfla4gF*5U?MKhK&ZXe!ReM;)QnrWk=699KoMq1PKX=!{$U z(hRx~Kvtzv^l^F!wMT2tlXmz@zKraGjej^~3v+DA%*&ZjVRL3BhaN&r-oXo^;q+y= zrpvy2{+Rpqd1ay#;O;_&d>yyh^$T=RAPA*!iO2LSFdegMZkm zF3_H@15m>jmh^PJFYp%{MCqa@WFTWe)gGtlcaZ+DT;^BLikR4Qu@!?o*~iPUym-Bp z4u#d&IG0^(!ra_SH53L(3@1dt^Q(gbe~CeC+tJ-oz?zL`s7yu;+_*asn6<+l=&p^0 zDrZ!+jSCl;U%X8;T*3?WYulRy&a9uMHu47A9&cGtw(J~pSzubYDq7bYpBQk0WjB4~ zd>FUJ!^A~hOAG!Y`}_`PMabnB1&h5Z*fL?E^3Hanch-`T!FiyvDGb3ODwK5?j%Nj!U`7tl zgnyRsU+&Yvyt=)^|Ra1qXnlFf4j0%V9p4Z@>NdHo7_ zzXDB??QXKjQG-#Hk@_l3OwUEBsQ_zApx} z<5bV9tW5u`W5LR z@B>+}REdUrGiK?Gts1&sq0e~bJShS0kaqp+?2*oE=)m=;>|1#uk8?;(>5;TkfJWQ1 zP|pzkqRnEjjfruu-5Uw{@d2a+$p>T|ktRKc_R}(hG@UJNZakzj@5L()+uBrgcELe~ z?elQf!D#@1Eq>`k54htp|0Hm5#+|d!k@a5beS+Ej-rXw4L5J!mNA5*iof!_ijqCHU z_e#7ua}lf6n)W)`)4&<0s~o!=s^#F!rL1$WNvmZSug6)g@jZsdjCr6Osm}~%^?E3o zOs0`4Exm_!(4j-gqzCoV^o_fl27WNTYTV7cP3ylW7L%I?4Ipklx!6@CQWWf4u z-EoTf47Fo~nnG}fY?$nXXH-^y)EBb)%|7%Q#gP<6H6L+TOm13OGgGZ@2zFFY2v@ts$ps}%HJ#-XRBWTKt)eklBGAbvy9y6nHhJBo zDjReB7#O0CgQp^3KLEuYcLOl=9sG7kRor-b`nHm~k^(&krJn+t)tj8YF!P&OXi$n)v@>Pn#}3k%^v>fmpAUh3m* zp3=HwgBg?unZqM{-%|A5Ou=nx_nI+~{P4JJi%mQQH227T_Aq*8sg3W*FG}4jW5G|1 zOfx0C4Hr56Vy?6prz-8q>Sll+D~aV#AF9(%4kMeFP;Jy~RHF!{1M;iTWCUdFrHuL{ zPdY@aVllZ@tQBC|0_^#MnF|0CKCC!nRK%oL2SEs%g^4lRmxkQ>O2C zRVKy)eEMVV4Dgdlw6FwjLgdfzszcH#+JAzSS~ja6%DC|5n^{83GyMe^4+ z)PH>nRvOmJ>ZwkQ8y7gqD;~aLK>vsPaB%D@GoJjF1+3~PNk>kS9Z4ovNRgf66xl() zy<^on5AOXRr%1}vU8erVT>VGZGH{YtKVk*t6#LAu3P_%@TLTV^sPnMa$hDIvTa`^? zH3iso>INWvo_$m4^X=FRI6#d2#BzV)J|D1PIPXv}6qn`DxF2&7Dv?h31HhmKNJhX8 z7np;DZClt_+tS%lGbw%h2`c@Sv#xvV#Fnr_2pLU*;M`RvXq{EjfAQ64?zr16mEQ}X zN-ea^PVM+(YyZ?uU9tIN)j8g>?abNLCbep#iZN_mU@yFC)tdd!!KzK0z#}RLYtkEp zhWXE=H&LVN9w#2qxw@ZxoEuR+@np^MBkKNke*IoJNkcG7<&QluR_%vIR+Ej4*&Z3J z$b_;EyCn10WrvNC>wYXo7PP5sgg=Z^VLWC)sCtRnn7|NX2v#Vg_*yNP2n?$5@)8wv zx&i^0GdK`*O2ozsJkB695I53cv)LHZG$bx6=`y$7x?uVazcW};;OMLF@Cr_iMx`sX zh|X|lmDi{NqA1Y3ngP}sn~2p0-4nX9K^y3I07pQ$zkX|lr>nWHxjwLAVizoSIm-bE zIN=2a0SGrG7I=lGKv}4w$s$^dYf78kj$l`Xk8@b~O;naEJwf8iTnhGL_T`P#-~%=* z(T1TNJHZeLV@&u9W$I$3NpO2K(wH}m{HZJ_YKS#)uyKa;H%86Vf?xp}qqnLv>=Z49 zI+aG_6ucePeU5^Xpwqu&`hr{A%v~iHB^op#quCs$=}b$c|01^mX^)4S7tYwkTO3@V zbb8R?ZYr%Qwu+XficndgN$@U6Y=SUQ055O`04R65iecBp4S{;pa9tjZJfB(1&=5OP zIn|6>V?$z1ewTU+|2?x{1t&)P!)uZC*_fVbE{t4cr4 z?`?1Ql#J7>jzL=Qiq;lcEk&zc){A@&4oDXy63{AY+sZGMzL37Wv|@tRV$n`0-wT6# z%TYRQIBi-aIz#PI`E^r)*IHB^aapadNOh6*iS~8^VcpK@(A~jz`3pRMy{*PHXnN2W ziF`ImS_JN$v`f0Cw6f3?1U~5>4rnX}j`jO%t!3j%z?XNFmRX}jYMv(P18S{Q_;v8jcjAZfkn>1RcO6{XQVLDuH_V8ZP=e(0KV55+j@GAB(9K)J|$Ibqn<{ z(bF+9A$r#=5_)QD0uhX%YmRuwcrBTi7e&1zN?u+d>L(qh8AL|C*f?gj@uA%s!g{OX zJfw?Ym~hl9Jfw$!2#xNJ0h1$Qrtiu94EMdj7(JAJEo8UZ>>)7ww9|$f)=ICeSqVIg z7P(yl4Hl{O;qftWNMnxGlrLITIX-6AfZ2=DuoiyI6>9GY6&8giPC<$aOb^VT58ra~ z3mcwJJD+Y?WN@N%<5Tcck{)udK6fQw6)5bV44y0uOl%Jp76#iV1`5H<#nGCuLA@Bz zg3Ap`{=3}T+r5U%oSO;yaVl3qIe{*v(n3TzBJ!uW(vrv8Yg*;iZkz-+^)J zzBA@ZKTLXf7P>mv{ctzF$!y6GZwWXeV4rl27uw3fPT7YNbLIY<5^=;o;A9OtF4lxH z3Nv06wq_P(Kn&o6aGv%%SMY1AMVkiT4!ure|GLykzpB%vzX9Dkt=9H+nL|1xKu{3+ zyNzBYNK?Z;%vFG1q0v|gR+_9sr-AfM7PGMup5>vhtfYoP%@r5!Iz+hn>Rs; zMJCLY`!eSC0J+|bL0H`qRqXS6O-2h3Dd>hqqp5%LABJ}QVe(oNZ-mM|y<6E|Jk<;m z7C{K6lR-hP1&ITxb@xo@T&XT7P_OKqaL>BoyOfMy#iiJN#6F6di;K~x%~*joq>3WF zAN`A4HF~6Ue8FxFH%o6x ze+I46C+no&6CU-zx?WI-S&pEk=-9qIFX;RQ$UICyXj|B0E@8F_g7 z3W#h5pSHvoM6wNjbF|IEVKD%`EIL+W!x9jBfpn0d&*C>qQ>MJJ%9MM#8CMI>r_$4( zehQ|5*|DxztV^2AUpD33c||o{7M+pBEyo&lmadwjdFM{K?8K+wS*-Sxw--vWg>QeN zWl0*miqp_WoHD@O@>4z~4~ZpzdZ5jza$4H--NH$_M6J|IDFz)_LyxGw-37sByDG4$@j_?ty95xq?j zz2_1Z^#<(xj3hph#4sQ^kVbP*D?lQP8*m~=@Dc*(FoVxvu8VjHi~Tp~D)rWAsHiYl z(ivaRzr4J48qHk0WbyV-EK@3~rH`a9%fku5y(HfB$%n1cCG*urLq*B_w_Z9UJb8A) zQsCi)Kf?H+l`}ozoX1v_dxxZ(zu#}P8dw$7_^nP2UF54Paqm0~c7SoWG?@Urr?tyt zo;}+v=o`&zH&qm#J8^MRt-cX%clkBys%n+i=PdMVR7HhqwSP!(u4?bJjIW~2YKt%G z?|spvx$Zj7S4Tg6ujFvo7MgbjT^sa8<6O0xnpbu_G{srzb{lnJA+R9aWoaS!t@684 zlM%ZC>D7dlI!GvlV{sCOPD1QO+&)->#tHRw^FoZrDBOu&^xM5?M2Z7~Oa$CD; zbezHZhA>LF>z-Xw4$4Dwr>Yn3>8D}5a?({#TG~Sux7=S5Y_}T1KKIM-cuQ*Pbgc0X zsqaob>oiu~_QPX7xA78=o(&qTPL8!$I8}i~bf}PWz^V$;v?^4<^!Ic6o9kw|!YjlH z{qR>&Tin~~())~-@$QbxUoBy4Ek0ehrEsyq60`yxs2MSr0ICDWZlPxNVVfQvR>Cxr zrlP1n5oAEG)oZr6Q47+KblV?U)OTpZ4DWqYHg$}*ut3H93rv?DHF(;`&v@%ge+z(h zOU^l`0eaqdE?ByLK_#n_77nG4x@)6u0P}72GV^PQ^K)SsHG8AjDFY3BDkRk5XSIM) z_RI|}6^$je1zG@(Q-{@nEr_n_*j>KhmK75(0e9xN-?XP}z+O7e4zBzqn53H3ijC82Fm)>Z$#}GB+-hBN`?h)zmJAdMPkNsH__T;ZcmWmM3o8Z>=qll zF*NsrWcA|t6PjnuirjepwHr4)G-XYnuX6e7$=iBrYiIf=?2|q&a<|4}fp&V@)JFh~ zW|#>(cfRQHcztMx{l_Q!uXekAz6m9X_DIjh^Im4QH&2_^8WVKf_3PG-qfIoU&-&yO z3~^aHpny4GCM-#j&{pi81%>q19#{$gCw(T2rne1!wG&=XpEdL;yp8Za z61-S;7n$!1ku*6S=`j>l6C?8zqik7u7Lz--3_(c(A)B$vN)`x0#LkBUB(aA)_C_tn zt_V25TSdMM<-@44fsZ_PyT=9&du%q3edt(OQ{()mCT3=$a$3{;rhQH2WldmeI01jU zHaWB+xo)ybZ%|EH_U^JNDuZ4H4&d`mW#vswksaSh{`Xc>nKZk+si_?Nw5&-?uMQ{v zjQ9R5|0crlW^jG{rL9|EieG3@ar!-FWqb6T%8!Pf)_#gD0&YV2H4g(?Mtc-&EOc>Hdmn?Mi=;aK32X*~ARcuD{=Hwl_0g7S=j zrcWFI!sAsJEK(x@nGA_GoCUuJBj98ynq2IL))<;#(0GL|Ch_<9X2b>?BaHVgNN2$1 zvD)l4Dh{cyxJHaTQ-x~Ll+Tf1F-t3`#iE>_M=B3`qz&JoCI;LP7X}bO6`DW}p+Pbv zHw3;vZUQ3QM@a$E-Q2Xwg71k7h*!?YdRh>lBr9pC)^T}uj1UMKm6F#+}KH&It{~$>=MSPb*O3S7KUMITBYI`GXo$5ke(N3R5T4$Km)W>{SNN}uP#(< z1UijXFc<*uE3h$)MHezQa%#?25Gd5@1SC_K3v8yf0?>>rpn?tkQCfPGttb z;xJnPuxZpGU|_YpP3y8%#bKGt!)kOat(v)f^fdLllJL4bOe0X~}cSuXH9R!*>&m(zkpd+zv-N*#j+KEbV02W&yhS-hTs zwcVi!(f*S9i7b*4R>T(>k*J~5x?C}z;1V=Ev;_r|Mby@vR@&Iy86B?+dAwel2fWc~ zaxtrb2sl&~V5D^hPMQtWW|mcJAuwraHGbVtx>;}-3tXlmtxr|Xjz7y{X}xnxDP$_Q zheJ)pf*!QYc9++8Z8z!wGy}cHtl>FS5}GS!LN2SWO_2?CWAu^=Jp}+X8Bn*@n|1aDI@9<- ziAK+81)s0eYhh`Fv5a%*Z8~EIZ`N=HYR<#cTt)4Kkoo7eQ+*nT$yS6JxL3zIELYWT zc=@y){)jc+fgo?Hr{FMt|dE$WNd06#ZAY3GE=thd@rlTkpvAB9yX}L zBOLIlVl1B9(GDX9L-;B(mb8ExH)D?tivTEF4xuS_-L6ah#-~5u(`@xfzm^Vwh21sR z?%NRzFv1zZ>FMANfc?#T_e}W5 z4PQ4EfBosSztCp_aLwJ~1MfN~#+s~>@3TjNz93QGSr{$j?5KOuNHbvJD`R0OD(%-o z^Z0cVU@eyt=%jw4}mWRlnh(-j3w@_Tbd{P5V!?dAcV=W>uHf6xBrjb${o@ z>)XKEj}Pwdo8EbqbnLnHrfy{iuy_Z2P%|f1;m|o$DwD}+p6>Aa9Er;KqHuBR`p)LX zO#!~d##>555l>~Mr>Szug@H+1uRi#3w`u)zfW4}7df#q&M>>Xgh;Cki^oG|+EJ`cY zK_aFy_KY~e6t5xF!ofT%Wh~BVu}cVX&;^);E(>`|$DDxvEWj38({=V@4*2bE@7Fdr z?JzLKR_S+mH5r^H_&zmGZ(%sj=Bn{Ze>Z5+c`>+zjf$h17^O z2U$xQd+iWK$iyMB#1eZf&F3-&v;2iD z#SRkAM%juKqWxCUM*NV55vtV2#i*ZF7}iMaHj?8rF*__(R~jk$bLDrMpflAL9tgLk zoI%ZZm47aZl-8L5)p-U;p3w;?lhk|Re_eRte}Tc$x^ggYkF?4tID^tR;kLFgFa@20 z5!|vzda%5%w8#OHYu8Fi2i=P=xKJ)DgUcEqp0tXf>p#I(ZnG?=8dcX_muOqkM*dKG zLpMxzZ;%E_Y3PI`bKCU}Z6GCiTN;nI^wko<Io!{&zX=*HSG|wLwE;5^#g(C)-&%p<_slCNcB(0Q|7W#m* zxOb}U$}z@>3Zz@S%N|Gls1vXH5t21DAk?&g02)?soLVSAVx(E()*A?77fdW;#skF1 zmyHvGc!Imb5=UCQjZH1S<-O0}yJfMw0qYr)^r6AXOCLV2^=KcLKIDxC=|dC4Y94=F z!!jmNf=+^x$2C69((ffYRo=*v=hf)DNuHj*gBO_p>rX;{I%1|f7N{E<@ zAvv()FOkBTuVQsiO0PcN_v_=UAN+Fn)o8*D_DB~E-im2qH@^ggn<~tLcmCr2N3T2k ztZ~J>>aVCau_sgaG)X^wfA^OUuHNy&YyaH-CMdl1CSZSkCkMxkE1vPz=If5`j|jzl zsfVjnuMt3&zlBt#e(vM@@=Hw zLF%GspG6<|@#7Rw?PMlX7Zaa9PS)e>kz$CX0f-bmmJ6cUkw)Xb-9m^f@S+bsf|M+R zc7voAJWJwVH(e8NVF>yIQMYhkK{}0vAh?h0KU=GB6)tR>J?#UQC1auzM{ zglahY`^2Z7=*r@8rPgLthzn0+jX`$-!&>xu>->pTYQQ@D6U&VS94peyxC!kJhqm;} z0l-~hvay_qo77BwxbE@Xkaq@k~~w9TORX`oHiIU&%q=3;L{?V_Nr#aC6V zfsC_!aZBI1S|d#Z^bfK|jm+`;0QVg`jna})uZo&St)b3GUu0G%#xpWWA_df*!RbWJ z8VG|Dq|4!tF&--kAiWojj5t14K)YBWbYsUeY*SL_8z?}ZF{EG0N@ai?BZop* zxs_FPco#O`&am2qj#*pO8UtUXGP`;A6P15jzjjtt)sg=7%aE2hARXWTN9p&xW&nWw ze*^&#oO<;yq_p&@^so1JUzWTdESfr@lHqtG$6fZDaAhTAd9A*FNynDC1){p#jtXX3 z*y<=_Sf`^2%v%r%X=-9lbzwta$Los=cl=|>H_6C5y}pSa*DVGY%jyipJge(j z-CN>&X4%puuA(QJdas+r+rQi|Z?5dP>cYO3_H9qC+YFfG{TEM7T*K>8H-L@Jt(y(J z4)v&pHE>zajym*oREE}G1A4k+9BY`_o8Ihl3N^0Tk9SOr3S4nr73Z9mFJEk;G?a*W z-U%-)(zV@q%@e9HnQ{p*snB3)wlM;8=7TT2_~5=5eEt`tThgyTaW5!gqEEb@ehie{ z>+9)R@cq?Sf6q2ct|96474HMbvtZ(H(q+y{hrnOlzmc9*Fq$cLJCfDb;n-^B1j!*Jmw)b9{}`u#c-O%X|@=|qG1+k{tS=Q95h7XwGkeF${bFz+dT_=`d0MJ zY%-ZQN(bK-olfx(C|_MNrDx&t`E$IRUb$pbYeCehvQ6$-HhX@elACn?^7+jXuZ?B& zYS-ktT0R)*JhQ2U)poDz11Poy7!GgtuLJIo7eL&elxbE+)<8C?|@4gea`=Ayc(nohn3R~mZJt#x4W+-HwVC-8BJv-Rq6Oi zOFK%2m)A^l#RR8{o}z+Ii&+jGGh1*R>`8*mQrJIAuY`W-gF`R>h?p)F`u2-+vGl?T zkp2~WZrRE3{*?%M;5jMmzv8F96v^dQDu$yuiAaVevbY`3u2cjIrgkzK(K7f~oRETI zOM~dOdU3>-NFQI_Aie$Ut+$*gyfnSxHKLJZ$f9wyp0L`sWfU=egV}HEp8R>`JA2~NARetc1*Foz{&PZ!d z+r-mV(jSvazf?a4A5Sb4q|xhBVHZewSradg+U58vY*!G4Q67eR?Sua_t0Fj0$6W3& z4;eh}-HmHp>s+;6y80Spld+@swm*G%blCgc{aa2g{Zs6%|M33Uub)R>iVTLaiX0pU#9*A$$qRglQ739uRb^}KZWIe~{O+5o3DCGG0TOS7q?ShIX$ z3v0o9=Pu18qyhu5{2Y7h=Hj>g3Tm`f2^EqnlO2q*Rjqx`_gsHDvw!TGWMK}y(I%4c6k9v!jNHB_P5eR_jRG$fL@pT#UHyTG()du8SJMWzeN zxM*}%N5`>w^miY8UBAIqC=EInRrW3|y6v{2rM=;WPT*nqs+!Ic@XC;83m8Zws=ST@ zXm*%kfx}ysNT_VIF;Y=d5i!y>)lkWX68HG)#!J5mmW_8fuxBTD8w`TCv6m-f@D^CR z6Uz62@jzx1A7lKnVl7d&A|b^xm&_0=v;sPp3@NUtNXyJ66>vJ#5Mn$A0yN8h-7;tC zLv^aTjaAc)ap~2#dTvuymoa`*k+peNyyDh1w>oW2v*Q)FMdcGQ5R0kj;mpxHt+u9l zO%=DTx!W-`1Y&EXSK;@wnosvO-fML>&W}~z(|@F<<>BY6^kv$*(*K9H_W+El%Km`gz3;tw)7zUq zlbKAWrYAF*neK9MVv6GN3g(9bswFK5fBYJ8UxRQ@d|y(A-xKu`*W03*CZ_gT z-eeZmK>TeX$44VYR62u~YDj=`{CK&EQt93(j{Ax44jeaas0E9D|8G{xYNU3i5q*}I z#jAP#^UV^?S(}@y3i2#%N&7I>7s4 z{y>B=GnMG;Gw8a%{1Hri=Ns?eGxBkI%ccdzT!6BqnNDJefyK+pq>o>Uk1M1Wft)(!ae@cDoX5yJ!KqkfX6fNOW#u{dPV8S79qzH3^-T|`&o*higV6CuX>pz`l7b?dC8!o8$Cs#dY?-IEHAzU zES%E|W?p7Ig2h@*Wu-lDAEuK6|zS3GS}{_ zFZ7gZ>}fk*d1XhsRa5fJB^Sh@i?OUUf)^$-p9<}ik!mN>OupV`GO>N3n9w->K+H_O z-G68*(PBREOT8ufK9wr+MMR}ywQSbOELMw9US(cxJQuWy=f9R`XSo*N61@-Px`^zh z!1%0=DZgcrGbg(|-Nt@>?~$)1Ru>3ggdwpPUld~ZDg2{lva!CB?5X6Cy< zdJevNb{4Bg-%Fa(%d?yzmDRlFfd|%DEviCr=JI@r6VE;bMLCuN5bIM*5nfPKIY|R- zB&DcQ0l0vXbfAmWB&W77>ssdU+xISQ8@|+T;O$`B9&&0gUv|e*F#J;f<(R#)rE^gW z`q*H%8&<7pTe7$n;KkIzM?YM%-e7m|Yi*9TtxJ}G2QKAm$Q*SimtZFf&n;jZi4QHB z$@e*(7ap2p-Mu;Hn3%=*%SV>?Jo4yyFa!sZ4?W!T0=OOwIsfP*J)2*^DRl7)q8^jn z|Ip9p9|dxBF1xHO8_vJ)+wbqcy7YGR6fP$S)XiQ)49C?#POuA5sCh{^2VOyg4>z-KlWR6?Z>!MMLe= zr(zXX(B_MjDC-jK8er6c;fe9&oGb*&=ji6r$&%!j%#%EvgQMP_r*IJbd~y5Asmu#9 z?sYt$ZlaD;uTUqc_o#nR|D-;pzNCoeQq)Of*1@cXTpsHonxsz71xz^V7mYxQVwDh2 z4}?V(bZ;1u*d|LNp7#Zg+T2TFLrDs0g9u9kWC9WF+{`gGZI0z}fjpQ+T&7^M)CsGA z(Ts^ZX_ct6L=;vrmqwEd;wKU)yO@~+BCK?v5{B{6B$<2|r$&q#Pz9NnhHaZRt2)~~ zzI;%@>iyoFa(f_e+EBTKkx6nm7ptcw002&^qdi;F18zvevKStT-n|vp8J!M^5jkC2 zi%tzbkt&S5on_1tjg7lgrnBlaPXKV2DgTE2SiZb2n{BJiiDem#a*HxV2Xj53g4JSj?Vrma4agb zr!oa3CYSM1PSG>cmhFn>6|=bt+N*q| z0KKUJoJJw#KsHoyaG5~|l*x4?l#)UKge!|Yt{#uEe^X{mlT9Q(2v~n=H-zZVl8t=9 zVp33R7Dt(&Qpe#=BIuS!K@mZqA?kNTB181Q1d2q|eHL`S45_s~QiS`R&}CyO{)oAr z<(*3!HpW@0Lc;-R#=NPa%rV)VGKV*qBl(uJLYrEqGt(N0TBcR=3cE)km9ug)XqTIF zo$kaYuYG9C*v{C}Ll8Em)z+8nS+OSF)?7W<;K@&Sq(#=fi9SbfqEG&u2$Z!AYs=@= z4W0_8H%Gd$B*j2nKdKdsrWvJ4usV*P#8K>RExUM1V9Rd_zoKs5;T+T_Okn5#B( z5(6eDs%YAb355)a!9{cVFb~A?L@XdY{!OAGXn<^|$IOHP%co;5B2jSy+92Ufg7q)a z7S+&!Dp*OBYH&p+uWPTf`hii}&Y`1LjT>ajt5)t+_bS19A$*MZ6P0JLco~%thZz`)c*EVeCYEd^y z#Jw0qjits@lc`zMTxuJ2C)v;O=L;_80-`c!Af=-i^ONaNVh|NM@jtfL zP!!M!8ZI#%8_L0%MjhM%%mzbFHdn{g)(*EYE?UxP+^E*oLFr6szzHE>ZDxyJ&H#x| zQJOy;%4-xdE5ktA>Y%Mfape^(qk4nplzykvW>zzRb{h)3ybeBBb?y0|;SEEX$V%S)FGl)lGU|dmUCDpB7FN?` zPl0vkbgHhJ5mse$9w)<7haUP0)4ZGxGt!CkfBaGMoeDrEDgzR-pe9~gIM0YC2{yyM z_zA==Z!k3m_k@+yRn%VUZt6*@yKkqbbWG3+>@ABayTW54@55mR0FEAjuo%kv^Q zm|F+Z$$n;n9N5#P^?T;_bk$5M4#KWrhhv{3m`oSIivHsPQ2)35j;>&FGQlJ!)%1Hs zzB6ORpd>YS&!id&6)XdOU@`u|!0>;P18unSSd3pdfBmryC$O%>IG z=YU1j2Ep^+L)7o6H>eLWC3XR5fD7b|&7^*J{b+ga{Ut4x#r_+I8qX zM{%p;4Cp-LXe~xvqJrIf=)Ino1=YF)N(icT#lVa69cRwq(jSYOb-jBjBHnMBATb(F zWM3lBL%i9O1yl6(0#eH-8)EdtngY*!o(!BpoWA%5lqT37KEbz(NJ?SaOz9t6(YUT0 zADh;eqa!1m8aLMq2XM^_pnoc(swTVctE!r0!;_tNzX^s^jP;kVZ6e2YV0zQY`pu2x zzy!DhW(3Hv^E@AL~O4vP>}fVHj0>uyeVa@E&FD?wK;O(#soSxkPB4g1BytfDXb4+0~J#&37AMG z;_&HYeX^cC=XE9Hjv7ZY?(*jOVYeyA1iSrt6Tw8d?$gBxA(*5*fiAIE(cO&%uJ!InWy?&&876UQDlwfz$)~gadv`Vd2FG zC^!L%gPYKNG@pHYKqN;DA47xDVD_xvjpEk06~$Qy*;LT&&-Q>v@vqw)HG^(XHh9#V z)zJ+~4|P89zyrzcy`fci0r{cMXP^Pk*>-h3@_7=-6M9fIWH5>oZ_-;nMR_ z5Pba)=ug1fJpMVXQeU2iBoK&1ruj`D8qXUI)^@z6toN zKiH;oE?OPB`{;8+n{N24qjvrH$J^2muO7B`WT`Fn4SV-8op|);;5Qj8`02T1CFF&j zC$g_VHW_G71XHPo)QQDq+|fusIuC&sqC;j69(uS@21>zBq3vM(@~-RW1sX;+J$&cN zDaW2&2jz7`z^!2S#>Ao9u6(`n8pY7U#R|mK&jnTJ`HLlBXlKutOBdgkRn%G1lBGi@ zo@$?j9(iZ+?DWP#a>JHK?%#CPq2FZ$!NN7gH9+3f%V%-DIQ0R7uG;5yK-hmZ_v)Sn z2vrUSAPmI}lm`fNNIo7{g6a$bqNOBx*S~W8^{*ti@0xA5&u*%Ax%M?0+YIR|2G6G7 zd~E%O#~$0T{;@sihvR6N^2CoZ;z`z`yz*66 zOSq!VWN4#%#4mBb;l|0cZ;^v>drqC&bJL&TM>2j`CHkxQfqvTY^7if1XKbf4yB05L zXf9;VbyiBdQR=$bLy>|&~w1I61c55^i0L0n|VD60ONeci8 z?F;ZkBatN%Cr-_Bew-4ceKDf6#zrwkZ=&lo5KX{iU%_c)8L&C$=#5oV3S2bvoDOnQ zPs??Z#BpUIuOEDq^pjKEk-wKD1NrZw7x<41twBqnr@&GG_r9%Hm{dV;g}Yvn@lQ~) zZpV9Q;@*t5LFGCf*zJlc6#=ja-C#hYqTu%=H^I!OK z1iIERdfY7&YgH;h+claBv5&;1VxK2_y0!gC5xg6>79k+HzLbGRqwZeg(OyR&xcx}? zFcb9!aC*{~Nt3p0qJJI-EwUsfvp|*>l8|2A(b?76L*YY*TEBUsV~+WbsWdh94)Ywx z#LZwmDKrV31~a5QFHKs-D1|V&o*?cr6XFrmatU1e&Pf|KOhOYki#D}VGTnx$GR(s_ z4dB!Mmj@PclHDnfR%X7}W)}3ndn$!XpSbz5kDd@w?Goe#&Ylw=clv<$X52y=Ol+P= zULsB&KQ12oUqS?sC9i_gg=PYq#0KbjMu=j1ARY53r-k>Uykwv{d$Ib+1`u(779(%g zcNBd969q!?$e#AwPzcDqR@80v$^i=5{5;t8v2c8m91{fAJ;D2JFM?h8_%YbkUgXzp z_gg(4tAD%Bk8^MAJ0y4>;R=4VKsXGTYm8JjRVV1dq(G0vSw3Zg9gX2s_kh%NA(h9e zUSTh>uQVgL*8>C9(q=iIM_X^nvYXiSEsOqsAFt*e9iA`IA8+1M;IVSfH5-BXEsNUf znIBw_9)0+=F0(7srAXWQ;6ac(%gCo?zkVrve0@5brs6Y@s|jKfare~e-oZi!o;r{M{}6J4&YFXkGUBNy=4Jr z#OCa9qEjH>f<6W3aTw$>ZzZ30p(#%El@sK{!A@|{33N_8_H_7nos43ZQEI%x5-;@S z)DUVUHINS&78p_q=zxV-k;%0Ded40&XED0GYFoIh+AV*?9!MR5pBW?X_8Bp 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 IH>08b4`|GD*#H0l literal 0 HcmV?d00001 diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.css b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.css new file mode 100644 index 00000000..8f1a287d --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.css @@ -0,0 +1,22 @@ +.book .book-summary .chapter > .articles { + overflow: hidden; + max-height: 0px; +} + +.book .book-summary .chapter.expanded > .articles { + max-height: 9999px; +} + +.book .book-summary ul.summary li a, +.book .book-summary ul.summary li span { + cursor: pointer; +} + +.book .book-summary .exc-trigger:before { + content: "\f054"; +} + +.book .book-summary .expanded > a .exc-trigger:before, +.book .book-summary .expanded > span .exc-trigger:before { + content: "\f078"; +} diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.js b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.js new file mode 100644 index 00000000..430a2ce3 --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-folding-chapters/folding-chapters.js @@ -0,0 +1,70 @@ +require(['gitbook', 'jQuery'], function(gitbook, $) { + var TOGGLE_CLASSNAME = 'expanded', + CHAPTER = '.chapter', + ARTICLES = '.articles', + TRIGGER_TEMPLATE = '', + LS_NAMESPACE = 'expChapters'; + var init = function () { + // adding the trigger element to each ARTICLES parent and binding the event + $(ARTICLES) + .parents(CHAPTER) + .children('a,span') + .prepend(TRIGGER_TEMPLATE) + .filter('span') + .on('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + toggle($(e.target).closest(CHAPTER)); + }); + + expand(lsItem()); + //expand current selected chapter with it's parents + var activeChapter = $(CHAPTER + '.active'); + expand(activeChapter); + expand(activeChapter.parents(CHAPTER)); + + + } + var toggle = function ($chapter) { + if ($chapter.hasClass('expanded')) { + collapse($chapter); + } else { + expand($chapter); + } + } + var collapse = function ($chapter) { + if ($chapter.length && $chapter.hasClass(TOGGLE_CLASSNAME)) { + $chapter.removeClass(TOGGLE_CLASSNAME); + lsItem($chapter); + $chapter.find(ARTICLES).hide() + } + } + var expand = function ($chapter) { + if ($chapter.length && !$chapter.hasClass(TOGGLE_CLASSNAME)) { + $chapter.addClass(TOGGLE_CLASSNAME); + lsItem($chapter); + $chapter.find(ARTICLES).show() + } + } + var lsItem = function () { + var map = JSON.parse(localStorage.getItem(LS_NAMESPACE)) || {} + if (arguments.length) { + var $chapters = arguments[0]; + $chapters.each(function (index, element) { + var level = $(this).data('level'); + var value = $(this).hasClass(TOGGLE_CLASSNAME); + map[level] = value; + }) + localStorage.setItem(LS_NAMESPACE, JSON.stringify(map)); + } else { + return $(CHAPTER).map(function(index, element){ + if (map[$(this).data('level')]) { + return this; + } + }) + } + } + gitbook.events.bind('page.change', function() { + init() + }); +}); diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/fontsettings.js b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/fontsettings.js new file mode 100644 index 00000000..ff7be714 --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/fontsettings.js @@ -0,0 +1,240 @@ +require(['gitbook', 'jquery'], function(gitbook, $) { + // Configuration + var MAX_SIZE = 4, + MIN_SIZE = 0, + BUTTON_ID; + + // Current fontsettings state + var fontState; + + // Default themes + var THEMES = [ + { + config: 'white', + text: 'White', + id: 0 + }, + { + config: 'sepia', + text: 'Sepia', + id: 1 + }, + { + config: 'night', + text: 'Night', + id: 2 + } + ]; + + // Default font families + var FAMILIES = [ + { + config: 'serif', + text: 'Serif', + id: 0 + }, + { + config: 'sans', + text: 'Sans', + id: 1 + } + ]; + + // Return configured themes + function getThemes() { + return THEMES; + } + + // Modify configured themes + function setThemes(themes) { + THEMES = themes; + updateButtons(); + } + + // Return configured font families + function getFamilies() { + return FAMILIES; + } + + // Modify configured font families + function setFamilies(families) { + FAMILIES = families; + updateButtons(); + } + + // Save current font settings + function saveFontSettings() { + gitbook.storage.set('fontState', fontState); + update(); + } + + // Increase font size + function enlargeFontSize(e) { + e.preventDefault(); + if (fontState.size >= MAX_SIZE) return; + + fontState.size++; + saveFontSettings(); + } + + // Decrease font size + function reduceFontSize(e) { + e.preventDefault(); + if (fontState.size <= MIN_SIZE) return; + + fontState.size--; + saveFontSettings(); + } + + // Change font family + function changeFontFamily(configName, e) { + if (e && e instanceof Event) { + e.preventDefault(); + } + + var familyId = getFontFamilyId(configName); + fontState.family = familyId; + saveFontSettings(); + } + + // Change type of color theme + function changeColorTheme(configName, e) { + if (e && e instanceof Event) { + e.preventDefault(); + } + + var $book = gitbook.state.$book; + + // Remove currently applied color theme + if (fontState.theme !== 0) + $book.removeClass('color-theme-'+fontState.theme); + + // Set new color theme + var themeId = getThemeId(configName); + fontState.theme = themeId; + if (fontState.theme !== 0) + $book.addClass('color-theme-'+fontState.theme); + + saveFontSettings(); + } + + // Return the correct id for a font-family config key + // Default to first font-family + function getFontFamilyId(configName) { + // Search for plugin configured font family + var configFamily = $.grep(FAMILIES, function(family) { + return family.config == configName; + })[0]; + // Fallback to default font family + return (!!configFamily)? configFamily.id : 0; + } + + // Return the correct id for a theme config key + // Default to first theme + function getThemeId(configName) { + // Search for plugin configured theme + var configTheme = $.grep(THEMES, function(theme) { + return theme.config == configName; + })[0]; + // Fallback to default theme + return (!!configTheme)? configTheme.id : 0; + } + + function update() { + var $book = gitbook.state.$book; + + $('.font-settings .font-family-list li').removeClass('active'); + $('.font-settings .font-family-list li:nth-child('+(fontState.family+1)+')').addClass('active'); + + $book[0].className = $book[0].className.replace(/\bfont-\S+/g, ''); + $book.addClass('font-size-'+fontState.size); + $book.addClass('font-family-'+fontState.family); + + if(fontState.theme !== 0) { + $book[0].className = $book[0].className.replace(/\bcolor-theme-\S+/g, ''); + $book.addClass('color-theme-'+fontState.theme); + } + } + + function init(config) { + // Search for plugin configured font family + var configFamily = getFontFamilyId(config.family), + configTheme = getThemeId(config.theme); + + // Instantiate font state object + fontState = gitbook.storage.get('fontState', { + size: config.size || 2, + family: configFamily, + theme: configTheme + }); + + update(); + } + + function updateButtons() { + // Remove existing fontsettings buttons + if (!!BUTTON_ID) { + gitbook.toolbar.removeButton(BUTTON_ID); + } + + // Create buttons in toolbar + BUTTON_ID = gitbook.toolbar.createButton({ + icon: 'fa fa-font', + label: 'Font Settings', + className: 'font-settings', + dropdown: [ + [ + { + text: 'A', + className: 'font-reduce', + onClick: reduceFontSize + }, + { + text: 'A', + className: 'font-enlarge', + onClick: enlargeFontSize + } + ], + $.map(FAMILIES, function(family) { + family.onClick = function(e) { + return changeFontFamily(family.config, e); + }; + + return family; + }), + $.map(THEMES, function(theme) { + theme.onClick = function(e) { + return changeColorTheme(theme.config, e); + }; + + return theme; + }) + ] + }); + } + + // Init configuration at start + gitbook.events.bind('start', function(e, config) { + var opts = config.fontsettings; + + // Generate buttons at start + updateButtons(); + + // Init current settings + init(opts); + }); + + // Expose API + gitbook.fontsettings = { + enlargeFontSize: enlargeFontSize, + reduceFontSize: reduceFontSize, + setTheme: changeColorTheme, + setFamily: changeFontFamily, + getThemes: getThemes, + setThemes: setThemes, + getFamilies: getFamilies, + setFamilies: setFamilies + }; +}); + + diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/website.css b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/website.css new file mode 100644 index 00000000..26591fe8 --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-fontsettings/website.css @@ -0,0 +1,291 @@ +/* + * Theme 1 + */ +.color-theme-1 .dropdown-menu { + background-color: #111111; + border-color: #7e888b; +} +.color-theme-1 .dropdown-menu .dropdown-caret .caret-inner { + border-bottom: 9px solid #111111; +} +.color-theme-1 .dropdown-menu .buttons { + border-color: #7e888b; +} +.color-theme-1 .dropdown-menu .button { + color: #afa790; +} +.color-theme-1 .dropdown-menu .button:hover { + color: #73553c; +} +/* + * Theme 2 + */ +.color-theme-2 .dropdown-menu { + background-color: #2d3143; + border-color: #272a3a; +} +.color-theme-2 .dropdown-menu .dropdown-caret .caret-inner { + border-bottom: 9px solid #2d3143; +} +.color-theme-2 .dropdown-menu .buttons { + border-color: #272a3a; +} +.color-theme-2 .dropdown-menu .button { + color: #62677f; +} +.color-theme-2 .dropdown-menu .button:hover { + color: #f4f4f5; +} +.book .book-header .font-settings .font-enlarge { + line-height: 30px; + font-size: 1.4em; +} +.book .book-header .font-settings .font-reduce { + line-height: 30px; + font-size: 1em; +} +.book.color-theme-1 .book-body { + color: #704214; + background: #f3eacb; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section { + background: #f3eacb; +} +.book.color-theme-2 .book-body { + color: #bdcadb; + background: #1c1f2b; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section { + background: #1c1f2b; +} +.book.font-size-0 .book-body .page-inner section { + font-size: 1.2rem; +} +.book.font-size-1 .book-body .page-inner section { + font-size: 1.4rem; +} +.book.font-size-2 .book-body .page-inner section { + font-size: 1.6rem; +} +.book.font-size-3 .book-body .page-inner section { + font-size: 2.2rem; +} +.book.font-size-4 .book-body .page-inner section { + font-size: 4rem; +} +.book.font-family-0 { + font-family: Georgia, serif; +} +.book.font-family-1 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal { + color: #704214; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal a { + color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h3, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h4, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h5, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { + color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2 { + border-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { + color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal hr { + background-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal blockquote { + border-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { + background: #fdf6e3; + color: #657b83; + border-color: #f8df9c; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal .highlight { + background-color: inherit; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table th, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table td { + border-color: #f5d06c; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr { + color: inherit; + background-color: #fdf6e3; + border-color: #444444; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { + background-color: #fbeecb; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal { + color: #bdcadb; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal a { + color: #3eb1d0; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h3, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h4, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h5, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { + color: #fffffa; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2 { + border-color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { + color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal hr { + background-color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal blockquote { + border-color: #373b4e; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { + color: #9dbed8; + background: #2d3143; + border-color: #2d3143; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal .highlight { + background-color: #282a39; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table th, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table td { + border-color: #3b3f54; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr { + color: #b6c2d2; + background-color: #2d3143; + border-color: #3b3f54; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { + background-color: #35394b; +} +.book.color-theme-1 .book-header { + color: #afa790; + background: transparent; +} +.book.color-theme-1 .book-header .btn { + color: #afa790; +} +.book.color-theme-1 .book-header .btn:hover { + color: #73553c; + background: none; +} +.book.color-theme-1 .book-header h1 { + color: #704214; +} +.book.color-theme-2 .book-header { + color: #7e888b; + background: transparent; +} +.book.color-theme-2 .book-header .btn { + color: #3b3f54; +} +.book.color-theme-2 .book-header .btn:hover { + color: #fffff5; + background: none; +} +.book.color-theme-2 .book-header h1 { + color: #bdcadb; +} +.book.color-theme-1 .book-body .navigation { + color: #afa790; +} +.book.color-theme-1 .book-body .navigation:hover { + color: #73553c; +} +.book.color-theme-2 .book-body .navigation { + color: #383f52; +} +.book.color-theme-2 .book-body .navigation:hover { + color: #fffff5; +} +/* + * Theme 1 + */ +.book.color-theme-1 .book-summary { + color: #afa790; + background: #111111; + border-right: 1px solid rgba(0, 0, 0, 0.07); +} +.book.color-theme-1 .book-summary .book-search { + background: transparent; +} +.book.color-theme-1 .book-summary .book-search input, +.book.color-theme-1 .book-summary .book-search input:focus { + border: 1px solid transparent; +} +.book.color-theme-1 .book-summary ul.summary li.divider { + background: #7e888b; + box-shadow: none; +} +.book.color-theme-1 .book-summary ul.summary li i.fa-check { + color: #33cc33; +} +.book.color-theme-1 .book-summary ul.summary li.done > a { + color: #877f6a; +} +.book.color-theme-1 .book-summary ul.summary li a, +.book.color-theme-1 .book-summary ul.summary li span { + color: #877f6a; + background: transparent; + font-weight: normal; +} +.book.color-theme-1 .book-summary ul.summary li.active > a, +.book.color-theme-1 .book-summary ul.summary li a:hover { + color: #704214; + background: transparent; + font-weight: normal; +} +/* + * Theme 2 + */ +.book.color-theme-2 .book-summary { + color: #bcc1d2; + background: #2d3143; + border-right: none; +} +.book.color-theme-2 .book-summary .book-search { + background: transparent; +} +.book.color-theme-2 .book-summary .book-search input, +.book.color-theme-2 .book-summary .book-search input:focus { + border: 1px solid transparent; +} +.book.color-theme-2 .book-summary ul.summary li.divider { + background: #272a3a; + box-shadow: none; +} +.book.color-theme-2 .book-summary ul.summary li i.fa-check { + color: #33cc33; +} +.book.color-theme-2 .book-summary ul.summary li.done > a { + color: #62687f; +} +.book.color-theme-2 .book-summary ul.summary li a, +.book.color-theme-2 .book-summary ul.summary li span { + color: #c1c6d7; + background: transparent; + font-weight: 600; +} +.book.color-theme-2 .book-summary ul.summary li.active > a, +.book.color-theme-2 .book-summary ul.summary li a:hover { + color: #f4f4f5; + background: #252737; + font-weight: 600; +} diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-highlight/website.css b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-highlight/website.css new file mode 100644 index 00000000..6674448f --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-highlight/website.css @@ -0,0 +1,434 @@ +.book .book-body .page-wrapper .page-inner section.normal pre, +.book .book-body .page-wrapper .page-inner section.normal code { + /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-title { + color: #8e908c; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-tag, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-tag, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-deletion, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-id, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-class, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo { + color: #c82829; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-literal, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-literal, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-params, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-params, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-constant { + color: #f5871f; +} +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute { + color: #eab700; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-value, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-value, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-header, +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-addition, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-addition, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + color: #718c00; +} +.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor, +.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor { + color: #3e999f; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator, +.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator, +.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub, +.book .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title, +.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title { + color: #4271ae; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function { + color: #8959a8; +} +.book .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + background: white; + color: #4d4d4c; + padding: 0.5em; +} +.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript, +.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript, +.book .book-body .page-wrapper .page-inner section.normal pre .javascript .xml, +.book .book-body .page-wrapper .page-inner section.normal code .javascript .xml, +.book .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .javascript, +.book .book-body .page-wrapper .page-inner section.normal code .xml .javascript, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript, +.book .book-body .page-wrapper .page-inner section.normal code .xml .vbscript, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .css, +.book .book-body .page-wrapper .page-inner section.normal code .xml .css, +.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + opacity: 0.5; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { + /* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + /* Solarized Green */ + /* Solarized Cyan */ + /* Solarized Blue */ + /* Solarized Yellow */ + /* Solarized Orange */ + /* Solarized Red */ + /* Solarized Violet */ +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-template_comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-template_comment, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-doctype, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-doctype, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pi, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pi, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-javadoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-javadoc { + color: #93a1a1; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-winutils, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-winutils, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .method, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .method, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-addition, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-tag, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-tag, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-request, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-request, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-status, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-status, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .nginx .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .nginx .hljs-title { + color: #859900; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-command, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-command, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-tag .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-rules .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-rules .hljs-value, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-phpdoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-phpdoc, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-hexcolor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-hexcolor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_url, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_url { + color: #2aa198; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-localvars, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-localvars, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-chunk, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-chunk, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-decorator, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-decorator, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-identifier, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-identifier, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .vhdl .hljs-literal, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .vhdl .hljs-literal, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-id, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-id, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-function, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-function { + color: #268bd2; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-body, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-body, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .smalltalk .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .smalltalk .hljs-number, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-constant, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-class .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-class .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-parent, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-parent, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .haskell .hljs-type, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .haskell .hljs-type, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_reference, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_reference { + color: #b58900; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor .hljs-keyword, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-shebang, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-shebang, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol .hljs-string, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-change, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-change, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-special, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-special, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attr_selector, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attr_selector, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-subst, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-subst, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-cdata, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-cdata, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .clojure .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .clojure .hljs-title, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-header { + color: #cb4b16; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-important, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-important { + color: #dc322f; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_label, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_label { + color: #6c71c4; +} +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula { + background: #eee8d5; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { + /* Tomorrow Night Bright Theme */ + /* Original theme - https://github.com/chriskempson/tomorrow-theme */ + /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + /* Tomorrow Comment */ + /* Tomorrow Red */ + /* Tomorrow Orange */ + /* Tomorrow Yellow */ + /* Tomorrow Green */ + /* Tomorrow Aqua */ + /* Tomorrow Blue */ + /* Tomorrow Purple */ +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-comment, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-title { + color: #969896; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-variable, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-tag, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-id, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-class, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo { + color: #d54e53; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-number, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-number, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-literal, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-literal, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-params, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-params, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-constant { + color: #e78c45; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute { + color: #e7c547; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-string, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-string, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-value, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-value, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-header, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-header, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-addition, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + color: #b9ca4a; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor { + color: #70c0b1; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title { + color: #7aa6da; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function { + color: #c397d8; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs { + display: block; + background: black; + color: #eaeaea; + padding: 0.5em; +} +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .xml, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .xml, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .javascript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .vbscript, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .css, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .css, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata, +.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata { + opacity: 0.5; +} diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-hints/plugin-hints.css b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-hints/plugin-hints.css new file mode 100644 index 00000000..ed4480c5 --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-hints/plugin-hints.css @@ -0,0 +1,9 @@ +.hints-icon { + display: table-cell; + padding-right: 15px; + padding-left: 5px; +} + +.hints-container { + display: table-cell; +} diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-lunr/lunr.min.js b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-lunr/lunr.min.js new file mode 100644 index 00000000..6aa6bc7d --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-lunr/lunr.min.js @@ -0,0 +1,7 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.12 + * Copyright (C) 2015 Oliver Nightingale + * MIT Licensed + * @license + */ +!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.5.12",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(t){return arguments.length&&null!=t&&void 0!=t?Array.isArray(t)?t.map(function(t){return t.toLowerCase()}):t.toString().trim().toLowerCase().split(/[\s\-]+/):[]},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,o=0;n>o;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n element for each result + res.results.forEach(function(res) { + var $li = $('

                                                                                                                                                                                                                                  • ', { + 'class': 'search-results-item' + }); + + var $title = $('

                                                                                                                                                                                                                                    '); + + var $link = $('', { + 'href': gitbook.state.basePath + '/' + res.url, + 'text': res.title + }); + + var content = res.body.trim(); + if (content.length > MAX_DESCRIPTION_SIZE) { + content = content.slice(0, MAX_DESCRIPTION_SIZE).trim()+'...'; + } + var $content = $('

                                                                                                                                                                                                                                    ').html(content); + + $link.appendTo($title); + $title.appendTo($li); + $content.appendTo($li); + $li.appendTo($searchList); + }); + } + + function launchSearch(q) { + // Add class for loading + $body.addClass('with-search'); + $body.addClass('search-loading'); + + // Launch search query + throttle(gitbook.search.query(q, 0, MAX_RESULTS) + .then(function(results) { + displayResults(results); + }) + .always(function() { + $body.removeClass('search-loading'); + }), 1000); + } + + function closeSearch() { + $body.removeClass('with-search'); + $bookSearchResults.removeClass('open'); + } + + function launchSearchFromQueryString() { + var q = getParameterByName('q'); + if (q && q.length > 0) { + // Update search input + $searchInput.val(q); + + // Launch search + launchSearch(q); + } + } + + function bindSearch() { + // Bind DOM + $searchInput = $('#book-search-input input'); + $bookSearchResults = $('#book-search-results'); + $searchList = $bookSearchResults.find('.search-results-list'); + $searchTitle = $bookSearchResults.find('.search-results-title'); + $searchResultsCount = $searchTitle.find('.search-results-count'); + $searchQuery = $searchTitle.find('.search-query'); + + // Launch query based on input content + function handleUpdate() { + var q = $searchInput.val(); + + if (q.length == 0) { + closeSearch(); + } + else { + launchSearch(q); + } + } + + // Detect true content change in search input + // Workaround for IE < 9 + var propertyChangeUnbound = false; + $searchInput.on('propertychange', function(e) { + if (e.originalEvent.propertyName == 'value') { + handleUpdate(); + } + }); + + // HTML5 (IE9 & others) + $searchInput.on('input', function(e) { + // Unbind propertychange event for IE9+ + if (!propertyChangeUnbound) { + $(this).unbind('propertychange'); + propertyChangeUnbound = true; + } + + handleUpdate(); + }); + + // Push to history on blur + $searchInput.on('blur', function(e) { + // Update history state + if (usePushState) { + var uri = updateQueryString('q', $(this).val()); + history.pushState({ path: uri }, null, uri); + } + }); + } + + gitbook.events.on('page.change', function() { + bindSearch(); + closeSearch(); + + // Launch search based on query parameter + if (gitbook.search.isInitialized()) { + launchSearchFromQueryString(); + } + }); + + gitbook.events.on('search.ready', function() { + bindSearch(); + + // Launch search from query param at start + launchSearchFromQueryString(); + }); + + function getParameterByName(name) { + var url = window.location.href; + name = name.replace(/[\[\]]/g, '\\$&'); + var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)', 'i'), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return decodeURIComponent(results[2].replace(/\+/g, ' ')); + } + + function updateQueryString(key, value) { + value = encodeURIComponent(value); + + var url = window.location.href; + var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'), + hash; + + if (re.test(url)) { + if (typeof value !== 'undefined' && value !== null) + return url.replace(re, '$1' + key + '=' + value + '$2$3'); + else { + hash = url.split('#'); + url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); + if (typeof hash[1] !== 'undefined' && hash[1] !== null) + url += '#' + hash[1]; + return url; + } + } + else { + if (typeof value !== 'undefined' && value !== null) { + var separator = url.indexOf('?') !== -1 ? '&' : '?'; + hash = url.split('#'); + url = hash[0] + separator + key + '=' + value; + if (typeof hash[1] !== 'undefined' && hash[1] !== null) + url += '#' + hash[1]; + return url; + } + else + return url; + } + } +}); diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-sharing/buttons.js b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-sharing/buttons.js new file mode 100644 index 00000000..709a4e4c --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook-plugin-sharing/buttons.js @@ -0,0 +1,90 @@ +require(['gitbook', 'jquery'], function(gitbook, $) { + var SITES = { + 'facebook': { + 'label': 'Facebook', + 'icon': 'fa fa-facebook', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href)); + } + }, + 'twitter': { + 'label': 'Twitter', + 'icon': 'fa fa-twitter', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href)); + } + }, + 'google': { + 'label': 'Google+', + 'icon': 'fa fa-google-plus', + 'onClick': function(e) { + e.preventDefault(); + window.open('https://plus.google.com/share?url='+encodeURIComponent(location.href)); + } + }, + 'weibo': { + 'label': 'Weibo', + 'icon': 'fa fa-weibo', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://service.weibo.com/share/share.php?content=utf-8&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)); + } + }, + 'instapaper': { + 'label': 'Instapaper', + 'icon': 'fa fa-instapaper', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://www.instapaper.com/text?u='+encodeURIComponent(location.href)); + } + }, + 'vk': { + 'label': 'VK', + 'icon': 'fa fa-vk', + 'onClick': function(e) { + e.preventDefault(); + window.open('http://vkontakte.ru/share.php?url='+encodeURIComponent(location.href)); + } + } + }; + + + + gitbook.events.bind('start', function(e, config) { + var opts = config.sharing; + + // Create dropdown menu + var menu = $.map(opts.all, function(id) { + var site = SITES[id]; + + return { + text: site.label, + onClick: site.onClick + }; + }); + + // Create main button with dropdown + if (menu.length > 0) { + gitbook.toolbar.createButton({ + icon: 'fa fa-share-alt', + label: 'Share', + position: 'right', + dropdown: [menu] + }); + } + + // Direct actions to share + $.each(SITES, function(sideId, site) { + if (!opts[sideId]) return; + + gitbook.toolbar.createButton({ + icon: site.icon, + label: site.text, + position: 'right', + onClick: site.onClick + }); + }); + }); +}); diff --git a/clones/llthw.common-lisp.dev/gitbook/gitbook.js b/clones/llthw.common-lisp.dev/gitbook/gitbook.js new file mode 100644 index 00000000..13077b45 --- /dev/null +++ b/clones/llthw.common-lisp.dev/gitbook/gitbook.js @@ -0,0 +1,4 @@ +!function e(t,n,r){function o(s,a){if(!n[s]){if(!t[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s0&&t-1 in e)}function o(e,t,n){return de.isFunction(t)?de.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?de.grep(e,function(e){return e===t!==n}):"string"!=typeof t?de.grep(e,function(e){return se.call(t,e)>-1!==n}):je.test(t)?de.filter(t,e,n):(t=de.filter(t,e),de.grep(e,function(e){return se.call(t,e)>-1!==n&&1===e.nodeType}))}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function s(e){var t={};return de.each(e.match(qe)||[],function(e,n){t[n]=!0}),t}function a(e){return e}function u(e){throw e}function c(e,t,n){var r;try{e&&de.isFunction(r=e.promise)?r.call(e).done(t).fail(n):e&&de.isFunction(r=e.then)?r.call(e,t,n):t.call(void 0,e)}catch(e){n.call(void 0,e)}}function l(){te.removeEventListener("DOMContentLoaded",l),e.removeEventListener("load",l),de.ready()}function f(){this.expando=de.expando+f.uid++}function p(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Ie.test(e)?JSON.parse(e):e)}function h(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Pe,"-$&").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n=p(n)}catch(e){}Re.set(e,t,n)}else n=void 0;return n}function d(e,t,n,r){var o,i=1,s=20,a=r?function(){return r.cur()}:function(){return de.css(e,t,"")},u=a(),c=n&&n[3]||(de.cssNumber[t]?"":"px"),l=(de.cssNumber[t]||"px"!==c&&+u)&&$e.exec(de.css(e,t));if(l&&l[3]!==c){c=c||l[3],n=n||[],l=+u||1;do i=i||".5",l/=i,de.style(e,t,l+c);while(i!==(i=a()/u)&&1!==i&&--s)}return n&&(l=+l||+u||0,o=n[1]?l+(n[1]+1)*n[2]:+n[2],r&&(r.unit=c,r.start=l,r.end=o)),o}function g(e){var t,n=e.ownerDocument,r=e.nodeName,o=Ue[r];return o?o:(t=n.body.appendChild(n.createElement(r)),o=de.css(t,"display"),t.parentNode.removeChild(t),"none"===o&&(o="block"),Ue[r]=o,o)}function m(e,t){for(var n,r,o=[],i=0,s=e.length;i-1)o&&o.push(i);else if(c=de.contains(i.ownerDocument,i),s=v(f.appendChild(i),"script"),c&&y(s),n)for(l=0;i=s[l++];)Ve.test(i.type||"")&&n.push(i);return f}function b(){return!0}function w(){return!1}function T(){try{return te.activeElement}catch(e){}}function C(e,t,n,r,o,i){var s,a;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(a in t)C(e,a,n,r,t[a],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),o===!1)o=w;else if(!o)return e;return 1===i&&(s=o,o=function(e){return de().off(e),s.apply(this,arguments)},o.guid=s.guid||(s.guid=de.guid++)),e.each(function(){de.event.add(this,t,o,r,n)})}function j(e,t){return de.nodeName(e,"table")&&de.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e:e}function k(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function E(e){var t=rt.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function S(e,t){var n,r,o,i,s,a,u,c;if(1===t.nodeType){if(Fe.hasData(e)&&(i=Fe.access(e),s=Fe.set(t,i),c=i.events)){delete s.handle,s.events={};for(o in c)for(n=0,r=c[o].length;n1&&"string"==typeof d&&!pe.checkClone&&nt.test(d))return e.each(function(n){var i=e.eq(n);g&&(t[0]=d.call(this,n,i.html())),A(i,t,r,o)});if(p&&(i=x(t,e[0].ownerDocument,!1,e,o),s=i.firstChild,1===i.childNodes.length&&(i=s),s||o)){for(a=de.map(v(i,"script"),k),u=a.length;f=0&&nC.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[$]=!0,e}function o(e){var t=L.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function i(e,t){for(var n=e.split("|"),r=n.length;r--;)C.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return function(t){return"form"in t?t.parentNode&&t.disabled===!1?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&je(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var o,i=e([],n.length,t),s=i.length;s--;)n[o=i[s]]&&(n[o]=!(r[o]=n[o]))})})}function f(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function p(){}function h(e){for(var t=0,n=e.length,r="";t1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function m(e,n,r){for(var o=0,i=n.length;o-1&&(r[c]=!(s[c]=f))}}else x=v(x===s?x.splice(d,x.length):x),i?i(null,s,x,u):K.apply(s,x)})}function x(e){for(var t,n,r,o=e.length,i=C.relative[e[0].type],s=i||C.relative[" "],a=i?1:0,u=d(function(e){return e===t},s,!0),c=d(function(e){return ee(t,e)>-1},s,!0),l=[function(e,n,r){var o=!i&&(r||n!==A)||((t=n).nodeType?u(e,n,r):c(e,n,r));return t=null,o}];a1&&g(l),a>1&&h(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(ae,"$1"),n,a0,i=e.length>0,s=function(r,s,a,u,c){var l,f,p,h=0,d="0",g=r&&[],m=[],y=A,x=r||i&&C.find.TAG("*",c),b=B+=null==y?1:Math.random()||.1,w=x.length;for(c&&(A=s===L||s||c);d!==w&&null!=(l=x[d]);d++){if(i&&l){for(f=0,s||l.ownerDocument===L||(O(l),a=!F);p=e[f++];)if(p(l,s||L,a)){u.push(l);break}c&&(B=b)}o&&((l=!p&&l)&&h--,r&&g.push(l))}if(h+=d,o&&d!==h){for(f=0;p=n[f++];)p(g,m,s,a);if(r){if(h>0)for(;d--;)g[d]||m[d]||(m[d]=Q.call(u));m=v(m)}K.apply(u,m),c&&!r&&m.length>0&&h+n.length>1&&t.uniqueSort(u)}return c&&(B=b,A=y),g};return o?r(s):s}var w,T,C,j,k,E,S,N,A,q,D,O,L,H,F,R,I,P,M,$="sizzle"+1*new Date,W=e.document,B=0,_=0,U=n(),z=n(),X=n(),V=function(e,t){return e===t&&(D=!0),0},G={}.hasOwnProperty,Y=[],Q=Y.pop,J=Y.push,K=Y.push,Z=Y.slice,ee=function(e,t){for(var n=0,r=e.length;n+~]|"+ne+")"+ne+"*"),le=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(ie),pe=new RegExp("^"+re+"$"),he={ID:new RegExp("^#("+re+")"),CLASS:new RegExp("^\\.("+re+")"),TAG:new RegExp("^("+re+"|[*])"),ATTR:new RegExp("^"+oe),PSEUDO:new RegExp("^"+ie),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},de=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,me=/^[^{]+\{\s*\[native \w/,ve=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ye=/[+~]/,xe=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),be=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},we=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,Te=function(e,t){return t?"\0"===e?"๏ฟฝ":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},Ce=function(){O()},je=d(function(e){return e.disabled===!0&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{K.apply(Y=Z.call(W.childNodes),W.childNodes),Y[W.childNodes.length].nodeType}catch(e){K={apply:Y.length?function(e,t){J.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}T=t.support={},k=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},O=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:W;return r!==L&&9===r.nodeType&&r.documentElement?(L=r,H=L.documentElement,F=!k(L),W!==L&&(n=L.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Ce,!1):n.attachEvent&&n.attachEvent("onunload",Ce)),T.attributes=o(function(e){return e.className="i",!e.getAttribute("className")}),T.getElementsByTagName=o(function(e){return e.appendChild(L.createComment("")),!e.getElementsByTagName("*").length}),T.getElementsByClassName=me.test(L.getElementsByClassName),T.getById=o(function(e){return H.appendChild(e).id=$,!L.getElementsByName||!L.getElementsByName($).length}),T.getById?(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){return e.getAttribute("id")===t}},C.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&F){var n=t.getElementById(e);return n?[n]:[]}}):(C.filter.ID=function(e){var t=e.replace(xe,be);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},C.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&F){var n,r,o,i=t.getElementById(e);if(i){if(n=i.getAttributeNode("id"),n&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if(n=i.getAttributeNode("id"),n&&n.value===e)return[i]}return[]}}),C.find.TAG=T.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):T.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],o=0,i=t.getElementsByTagName(e);if("*"===e){for(;n=i[o++];)1===n.nodeType&&r.push(n);return r}return i},C.find.CLASS=T.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&F)return t.getElementsByClassName(e)},I=[],R=[],(T.qsa=me.test(L.querySelectorAll))&&(o(function(e){H.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&R.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||R.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+$+"-]").length||R.push("~="),e.querySelectorAll(":checked").length||R.push(":checked"),e.querySelectorAll("a#"+$+"+*").length||R.push(".#.+[+~]")}),o(function(e){e.innerHTML="";var t=L.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&R.push("name"+ne+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&R.push(":enabled",":disabled"),H.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&R.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),R.push(",.*:")})),(T.matchesSelector=me.test(P=H.matches||H.webkitMatchesSelector||H.mozMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){T.disconnectedMatch=P.call(e,"*"),P.call(e,"[s!='']:x"),I.push("!=",ie)}),R=R.length&&new RegExp(R.join("|")),I=I.length&&new RegExp(I.join("|")),t=me.test(H.compareDocumentPosition),M=t||me.test(H.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},V=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!T.sortDetached&&t.compareDocumentPosition(e)===n?e===L||e.ownerDocument===W&&M(W,e)?-1:t===L||t.ownerDocument===W&&M(W,t)?1:q?ee(q,e)-ee(q,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,r=0,o=e.parentNode,i=t.parentNode,a=[e],u=[t];if(!o||!i)return e===L?-1:t===L?1:o?-1:i?1:q?ee(q,e)-ee(q,t):0;if(o===i)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;a[r]===u[r];)r++;return r?s(a[r],u[r]):a[r]===W?-1:u[r]===W?1:0},L):L},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==L&&O(e),n=n.replace(le,"='$1']"),T.matchesSelector&&F&&!X[n+" "]&&(!I||!I.test(n))&&(!R||!R.test(n)))try{var r=P.call(e,n);if(r||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,L,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==L&&O(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==L&&O(e);var n=C.attrHandle[t.toLowerCase()],r=n&&G.call(C.attrHandle,t.toLowerCase())?n(e,t,!F):void 0;return void 0!==r?r:T.attributes||!F?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+"").replace(we,Te)},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,o=0;if(D=!T.detectDuplicates,q=!T.sortStable&&e.slice(0),e.sort(V),D){for(;t=e[o++];)t===e[o]&&(r=n.push(o));for(;r--;)e.splice(n[r],1)}return q=null,e},j=t.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=j(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=j(t);return n},C=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xe,be),e[3]=(e[3]||e[4]||e[5]||"").replace(xe,be),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=E(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(xe,be).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=U[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&U(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(o){var i=t.attr(o,e);return null==i?"!="===n:!n||(i+="","="===n?i===r:"!="===n?i!==r:"^="===n?r&&0===i.indexOf(r):"*="===n?r&&i.indexOf(r)>-1:"$="===n?r&&i.slice(-r.length)===r:"~="===n?(" "+i.replace(se," ")+" ").indexOf(r)>-1:"|="===n&&(i===r||i.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,o){var i="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,u){var c,l,f,p,h,d,g=i!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!u&&!a,x=!1;if(m){if(i){for(;g;){for(p=t;p=p[g];)if(a?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&y){for(p=m,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h&&c[2],p=h&&m.childNodes[h];p=++h&&p&&p[g]||(x=h=0)||d.pop();)if(1===p.nodeType&&++x&&p===t){l[e]=[B,h,x];break}}else if(y&&(p=t,f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),c=l[e]||[],h=c[0]===B&&c[1],x=h),x===!1)for(;(p=++h&&p&&p[g]||(x=h=0)||d.pop())&&((a?p.nodeName.toLowerCase()!==v:1!==p.nodeType)||!++x||(y&&(f=p[$]||(p[$]={}),l=f[p.uniqueID]||(f[p.uniqueID]={}),l[e]=[B,x]),p!==t)););return x-=o,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var o,i=C.pseudos[e]||C.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return i[$]?i(n):i.length>1?(o=[e,e,"",n],C.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,o=i(e,n),s=o.length;s--;)r=ee(e,o[s]),e[r]=!(t[r]=o[s])}):function(e){return i(e,0,o)}):i}},pseudos:{not:r(function(e){var t=[],n=[],o=S(e.replace(ae,"$1"));return o[$]?r(function(e,t,n,r){for(var i,s=o(e,null,r,[]),a=e.length;a--;)(i=s[a])&&(e[a]=!(t[a]=i))}):function(e,r,i){return t[0]=e,o(t,null,i,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){ +return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(xe,be),function(t){return(t.textContent||t.innerText||j(t)).indexOf(e)>-1}}),lang:r(function(e){return pe.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(xe,be).toLowerCase(),function(t){var n;do if(n=F?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===L.activeElement&&(!L.hasFocus||L.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:c(!1),disabled:c(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!C.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return de.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r2&&"ID"===(s=i[0]).type&&9===t.nodeType&&F&&C.relative[i[1].type]){if(t=(C.find.ID(s.matches[0].replace(xe,be),t)||[])[0],!t)return n;c&&(t=t.parentNode),e=e.slice(i.shift().value.length)}for(o=he.needsContext.test(e)?0:i.length;o--&&(s=i[o],!C.relative[a=s.type]);)if((u=C.find[a])&&(r=u(s.matches[0].replace(xe,be),ye.test(i[0].type)&&f(t.parentNode)||t))){if(i.splice(o,1),e=r.length&&h(i),!e)return K.apply(n,r),n;break}}return(c||S(e,l))(r,t,!F,n,!t||ye.test(e)&&f(t.parentNode)||t),n},T.sortStable=$.split("").sort(V).join("")===$,T.detectDuplicates=!!D,O(),T.sortDetached=o(function(e){return 1&e.compareDocumentPosition(L.createElement("fieldset"))}),o(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||i("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),T.attributes&&o(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||i("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),o(function(e){return null==e.getAttribute("disabled")})||i(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);de.find=xe,de.expr=xe.selectors,de.expr[":"]=de.expr.pseudos,de.uniqueSort=de.unique=xe.uniqueSort,de.text=xe.getText,de.isXMLDoc=xe.isXML,de.contains=xe.contains,de.escapeSelector=xe.escape;var be=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&de(e).is(n))break;r.push(e)}return r},we=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},Te=de.expr.match.needsContext,Ce=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,je=/^.[^:#\[\.,]*$/;de.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?de.find.matchesSelector(r,e)?[r]:[]:de.find.matches(e,de.grep(t,function(e){return 1===e.nodeType}))},de.fn.extend({find:function(e){var t,n,r=this.length,o=this;if("string"!=typeof e)return this.pushStack(de(e).filter(function(){for(t=0;t1?de.uniqueSort(n):n},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,"string"==typeof e&&Te.test(e)?de(e):e||[],!1).length}});var ke,Ee=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,Se=de.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||ke,"string"==typeof e){if(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:Ee.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof de?t[0]:t,de.merge(this,de.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:te,!0)),Ce.test(r[1])&&de.isPlainObject(t))for(r in t)de.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return o=te.getElementById(r[2]),o&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):de.isFunction(e)?void 0!==n.ready?n.ready(e):e(de):de.makeArray(e,this)};Se.prototype=de.fn,ke=de(te);var Ne=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};de.fn.extend({has:function(e){var t=de(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&de.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?de.uniqueSort(i):i)},index:function(e){return e?"string"==typeof e?se.call(de(e),this[0]):se.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(de.uniqueSort(de.merge(this.get(),de(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),de.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return be(e,"parentNode")},parentsUntil:function(e,t,n){return be(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return be(e,"nextSibling")},prevAll:function(e){return be(e,"previousSibling")},nextUntil:function(e,t,n){return be(e,"nextSibling",n)},prevUntil:function(e,t,n){return be(e,"previousSibling",n)},siblings:function(e){return we((e.parentNode||{}).firstChild,e)},children:function(e){return we(e.firstChild)},contents:function(e){return e.contentDocument||de.merge([],e.childNodes)}},function(e,t){de.fn[e]=function(n,r){var o=de.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(o=de.filter(r,o)),this.length>1&&(Ae[e]||de.uniqueSort(o),Ne.test(e)&&o.reverse()),this.pushStack(o)}});var qe=/[^\x20\t\r\n\f]+/g;de.Callbacks=function(e){e="string"==typeof e?s(e):de.extend({},e);var t,n,r,o,i=[],a=[],u=-1,c=function(){for(o=e.once,r=t=!0;a.length;u=-1)for(n=a.shift();++u-1;)i.splice(n,1),n<=u&&u--}),this},has:function(e){return e?de.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=a=[],i=n="",this},disabled:function(){return!i},lock:function(){return o=a=[],n||t||(i=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},de.extend({Deferred:function(t){var n=[["notify","progress",de.Callbacks("memory"),de.Callbacks("memory"),2],["resolve","done",de.Callbacks("once memory"),de.Callbacks("once memory"),0,"resolved"],["reject","fail",de.Callbacks("once memory"),de.Callbacks("once memory"),1,"rejected"]],r="pending",o={state:function(){return r},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return de.Deferred(function(t){de.each(n,function(n,r){var o=de.isFunction(e[r[4]])&&e[r[4]];i[r[1]](function(){var e=o&&o.apply(this,arguments);e&&de.isFunction(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,o?[e]:arguments)})}),e=null}).promise()},then:function(t,r,o){function i(t,n,r,o){return function(){var c=this,l=arguments,f=function(){var e,f;if(!(t=s&&(r!==u&&(c=void 0,l=[e]),n.rejectWith(c,l))}};t?p():(de.Deferred.getStackHook&&(p.stackTrace=de.Deferred.getStackHook()),e.setTimeout(p))}}var s=0;return de.Deferred(function(e){n[0][3].add(i(0,e,de.isFunction(o)?o:a,e.notifyWith)),n[1][3].add(i(0,e,de.isFunction(t)?t:a)),n[2][3].add(i(0,e,de.isFunction(r)?r:u))}).promise()},promise:function(e){return null!=e?de.extend(e,o):o}},i={};return de.each(n,function(e,t){var s=t[2],a=t[5];o[t[1]]=s.add,a&&s.add(function(){r=a},n[3-e][2].disable,n[0][2].lock),s.add(t[3].fire),i[t[0]]=function(){return i[t[0]+"With"](this===i?void 0:this,arguments),this},i[t[0]+"With"]=s.fireWith}),o.promise(i),t&&t.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=re.call(arguments),i=de.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?re.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(c(e,i.done(s(n)).resolve,i.reject),"pending"===i.state()||de.isFunction(o[n]&&o[n].then)))return i.then();for(;n--;)c(o[n],s(n),i.reject);return i.promise()}});var De=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;de.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&De.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},de.readyException=function(t){e.setTimeout(function(){throw t})};var Oe=de.Deferred();de.fn.ready=function(e){return Oe.then(e).catch(function(e){de.readyException(e)}),this},de.extend({isReady:!1,readyWait:1,holdReady:function(e){e?de.readyWait++:de.ready(!0)},ready:function(e){(e===!0?--de.readyWait:de.isReady)||(de.isReady=!0,e!==!0&&--de.readyWait>0||Oe.resolveWith(te,[de]))}}),de.ready.then=Oe.then,"complete"===te.readyState||"loading"!==te.readyState&&!te.documentElement.doScroll?e.setTimeout(de.ready):(te.addEventListener("DOMContentLoaded",l),e.addEventListener("load",l));var Le=function(e,t,n,r,o,i,s){var a=0,u=e.length,c=null==n;if("object"===de.type(n)){o=!0;for(a in n)Le(e,t,a,n[a],!0,i,s)}else if(void 0!==r&&(o=!0,de.isFunction(r)||(s=!0),c&&(s?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(de(e),n)})),t))for(;a1,null,!0)},removeData:function(e){return this.each(function(){Re.remove(this,e)})}}),de.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Fe.get(e,t),n&&(!r||de.isArray(n)?r=Fe.access(e,t,de.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=de.queue(e,t),r=n.length,o=n.shift(),i=de._queueHooks(e,t),s=function(){de.dequeue(e,t)};"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===t&&n.unshift("inprogress"),delete i.stop,o.call(e,s,i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Fe.get(e,n)||Fe.access(e,n,{empty:de.Callbacks("once memory").add(function(){Fe.remove(e,[t+"queue",n])})})}}),de.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,Ve=/^$|\/(?:java|ecma)script/i,Ge={option:[1,""],thead:[1,"","
                                                                                                                                                                                                                                    "],col:[2,"","
                                                                                                                                                                                                                                    "],tr:[2,"","
                                                                                                                                                                                                                                    "],td:[3,"","
                                                                                                                                                                                                                                    "],_default:[0,"",""]};Ge.optgroup=Ge.option,Ge.tbody=Ge.tfoot=Ge.colgroup=Ge.caption=Ge.thead,Ge.th=Ge.td;var Ye=/<|&#?\w+;/;!function(){var e=te.createDocumentFragment(),t=e.appendChild(te.createElement("div")),n=te.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),pe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",pe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Qe=te.documentElement,Je=/^key/,Ke=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ze=/^([^.]*)(?:\.(.+)|)/;de.event={global:{},add:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.get(e);if(m)for(n.handler&&(i=n,n=i.handler,o=i.selector),o&&de.find.matchesSelector(Qe,o),n.guid||(n.guid=de.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return"undefined"!=typeof de&&de.event.triggered!==t.type?de.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(qe)||[""],c=t.length;c--;)a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h&&(f=de.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=de.event.special[h]||{},l=de.extend({type:h,origType:g,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&de.expr.match.needsContext.test(o),namespace:d.join(".")},i),(p=u[h])||(p=u[h]=[],p.delegateCount=0,f.setup&&f.setup.call(e,r,d,s)!==!1||e.addEventListener&&e.addEventListener(h,s)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),o?p.splice(p.delegateCount++,0,l):p.push(l),de.event.global[h]=!0)},remove:function(e,t,n,r,o){var i,s,a,u,c,l,f,p,h,d,g,m=Fe.hasData(e)&&Fe.get(e);if(m&&(u=m.events)){for(t=(t||"").match(qe)||[""],c=t.length;c--;)if(a=Ze.exec(t[c])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){for(f=de.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],a=a[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=i=p.length;i--;)l=p[i],!o&&g!==l.origType||n&&n.guid!==l.guid||a&&!a.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(p.splice(i,1),l.selector&&p.delegateCount--,f.remove&&f.remove.call(e,l));s&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||de.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)de.event.remove(e,h+t[c],n,r,!0);de.isEmptyObject(u)&&Fe.remove(e,"handle events")}},dispatch:function(e){var t,n,r,o,i,s,a=de.event.fix(e),u=new Array(arguments.length),c=(Fe.get(this,"events")||{})[a.type]||[],l=de.event.special[a.type]||{};for(u[0]=a,t=1;t=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==e.type||c.disabled!==!0)){for(i=[],s={},n=0;n-1:de.find(o,this,null,[c]).length),s[o]&&i.push(r);i.length&&a.push({elem:c,handlers:i})}return c=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,tt=/\s*$/g;de.extend({htmlPrefilter:function(e){return e.replace(et,"<$1>")},clone:function(e,t,n){var r,o,i,s,a=e.cloneNode(!0),u=de.contains(e.ownerDocument,e);if(!(pe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||de.isXMLDoc(e)))for(s=v(a),i=v(e),r=0,o=i.length;r0&&y(s,!u&&v(e,"script")),a},cleanData:function(e){for(var t,n,r,o=de.event.special,i=0;void 0!==(n=e[i]);i++)if(He(n)){if(t=n[Fe.expando]){if(t.events)for(r in t.events)o[r]?de.event.remove(n,r):de.removeEvent(n,r,t.handle);n[Fe.expando]=void 0}n[Re.expando]&&(n[Re.expando]=void 0)}}}),de.fn.extend({detach:function(e){return q(this,e,!0)},remove:function(e){return q(this,e)},text:function(e){return Le(this,function(e){return void 0===e?de.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.appendChild(e)}})},prepend:function(){return A(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=j(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return A(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(de.cleanData(v(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return de.clone(this,e,t)})},html:function(e){return Le(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!tt.test(e)&&!Ge[(Xe.exec(e)||["",""])[1].toLowerCase()]){e=de.htmlPrefilter(e);try{for(;n1)}}),de.Tween=I,I.prototype={constructor:I,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||de.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(de.cssNumber[n]?"":"px")},cur:function(){var e=I.propHooks[this.prop];return e&&e.get?e.get(this):I.propHooks._default.get(this)},run:function(e){var t,n=I.propHooks[this.prop];return this.options.duration?this.pos=t=de.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):I.propHooks._default.set(this),this}},I.prototype.init.prototype=I.prototype,I.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=de.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){de.fx.step[e.prop]?de.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[de.cssProps[e.prop]]&&!de.cssHooks[e.prop]?e.elem[e.prop]=e.now:de.style(e.elem,e.prop,e.now+e.unit)}}},I.propHooks.scrollTop=I.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},de.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},de.fx=I.prototype.init,de.fx.step={};var ht,dt,gt=/^(?:toggle|show|hide)$/,mt=/queueHooks$/;de.Animation=de.extend(U,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,$e.exec(t),n),n}]},tweener:function(e,t){de.isFunction(e)?(t=e,e=["*"]):e=e.match(qe);for(var n,r=0,o=e.length;r1)},removeAttr:function(e){return this.each(function(){de.removeAttr(this,e)})}}),de.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return"undefined"==typeof e.getAttribute?de.prop(e,t,n):(1===i&&de.isXMLDoc(e)||(o=de.attrHooks[t.toLowerCase()]||(de.expr.match.bool.test(t)?vt:void 0)),void 0!==n?null===n?void de.removeAttr(e,t):o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+""),n):o&&"get"in o&&null!==(r=o.get(e,t))?r:(r=de.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!pe.radioValue&&"radio"===t&&de.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(qe);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),vt={set:function(e,t,n){return t===!1?de.removeAttr(e,n):e.setAttribute(n,n),n}},de.each(de.expr.match.bool.source.match(/\w+/g),function(e,t){var n=yt[t]||de.find.attr;yt[t]=function(e,t,r){var o,i,s=t.toLowerCase();return r||(i=yt[s],yt[s]=o,o=null!=n(e,t,r)?s:null,yt[s]=i),o}});var xt=/^(?:input|select|textarea|button)$/i,bt=/^(?:a|area)$/i;de.fn.extend({prop:function(e,t){return Le(this,de.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[de.propFix[e]||e]})}}),de.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&de.isXMLDoc(e)||(t=de.propFix[t]||t,o=de.propHooks[t]),void 0!==n?o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&"get"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=de.find.attr(e,"tabindex");return t?parseInt(t,10):xt.test(e.nodeName)||bt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),pe.optSelected||(de.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),de.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){de.propFix[this.toLowerCase()]=this}),de.fn.extend({addClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).addClass(e.call(this,t,X(this)))});if("string"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&" "+z(o)+" "){for(s=0;i=t[s++];)r.indexOf(" "+i+" ")<0&&(r+=i+" ");a=z(r),o!==a&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,r,o,i,s,a,u=0;if(de.isFunction(e))return this.each(function(t){de(this).removeClass(e.call(this,t,X(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(qe)||[];n=this[u++];)if(o=X(n),r=1===n.nodeType&&" "+z(o)+" "){for(s=0;i=t[s++];)for(;r.indexOf(" "+i+" ")>-1;)r=r.replace(" "+i+" "," ");a=z(r),o!==a&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):de.isFunction(e)?this.each(function(n){de(this).toggleClass(e.call(this,n,X(this),t),t)}):this.each(function(){var t,r,o,i;if("string"===n)for(r=0,o=de(this),i=e.match(qe)||[];t=i[r++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||(t=X(this),t&&Fe.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||e===!1?"":Fe.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+z(X(n))+" ").indexOf(t)>-1)return!0;return!1}});var wt=/\r/g;de.fn.extend({val:function(e){var t,n,r,o=this[0];{if(arguments.length)return r=de.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=r?e.call(this,n,de(this).val()):e,null==o?o="":"number"==typeof o?o+="":de.isArray(o)&&(o=de.map(o,function(e){return null==e?"":e+""})),t=de.valHooks[this.type]||de.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,o,"value")||(this.value=o))});if(o)return t=de.valHooks[o.type]||de.valHooks[o.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(o,"value"))?n:(n=o.value,"string"==typeof n?n.replace(wt,""):null==n?"":n)}}}),de.extend({valHooks:{option:{get:function(e){var t=de.find.attr(e,"value");return null!=t?t:z(de.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,s="select-one"===e.type,a=s?null:[],u=s?i+1:o.length;for(r=i<0?u:s?i:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),de.each(["radio","checkbox"],function(){de.valHooks[this]={set:function(e,t){if(de.isArray(t))return e.checked=de.inArray(de(e).val(),t)>-1}},pe.checkOn||(de.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Tt=/^(?:focusinfocus|focusoutblur)$/;de.extend(de.event,{trigger:function(t,n,r,o){var i,s,a,u,c,l,f,p=[r||te],h=ce.call(t,"type")?t.type:t,d=ce.call(t,"namespace")?t.namespace.split("."):[];if(s=a=r=r||te,3!==r.nodeType&&8!==r.nodeType&&!Tt.test(h+de.event.triggered)&&(h.indexOf(".")>-1&&(d=h.split("."),h=d.shift(),d.sort()),c=h.indexOf(":")<0&&"on"+h,t=t[de.expando]?t:new de.Event(h,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=d.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:de.makeArray(n,[t]),f=de.event.special[h]||{},o||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!o&&!f.noBubble&&!de.isWindow(r)){for(u=f.delegateType||h,Tt.test(u+h)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(r.ownerDocument||te)&&p.push(a.defaultView||a.parentWindow||e)}for(i=0;(s=p[i++])&&!t.isPropagationStopped();)t.type=i>1?u:f.bindType||h,l=(Fe.get(s,"events")||{})[t.type]&&Fe.get(s,"handle"),l&&l.apply(s,n),l=c&&s[c],l&&l.apply&&He(s)&&(t.result=l.apply(s,n),t.result===!1&&t.preventDefault());return t.type=h,o||t.isDefaultPrevented()||f._default&&f._default.apply(p.pop(),n)!==!1||!He(r)||c&&de.isFunction(r[h])&&!de.isWindow(r)&&(a=r[c],a&&(r[c]=null),de.event.triggered=h,r[h](),de.event.triggered=void 0,a&&(r[c]=a)),t.result}},simulate:function(e,t,n){var r=de.extend(new de.Event,n,{type:e,isSimulated:!0});de.event.trigger(r,null,t)}}),de.fn.extend({trigger:function(e,t){return this.each(function(){de.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return de.event.trigger(e,t,n,!0)}}),de.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){de.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),de.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),pe.focusin="onfocusin"in e,pe.focusin||de.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){de.event.simulate(t,e.target,de.event.fix(e))};de.event.special[t]={setup:function(){var r=this.ownerDocument||this,o=Fe.access(r,t);o||r.addEventListener(e,n,!0),Fe.access(r,t,(o||0)+1)},teardown:function(){var r=this.ownerDocument||this,o=Fe.access(r,t)-1;o?Fe.access(r,t,o):(r.removeEventListener(e,n,!0),Fe.remove(r,t))}}});var Ct=e.location,jt=de.now(),kt=/\?/;de.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||de.error("Invalid XML: "+t),n};var Et=/\[\]$/,St=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;de.param=function(e,t){var n,r=[],o=function(e,t){var n=de.isFunction(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(de.isArray(e)||e.jquery&&!de.isPlainObject(e))de.each(e,function(){o(this.name,this.value)});else for(n in e)V(n,e[n],t,o);return r.join("&")},de.fn.extend({serialize:function(){return de.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=de.prop(this,"elements");return e?de.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!de(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!ze.test(e))}).map(function(e,t){var n=de(this).val();return null==n?null:de.isArray(n)?de.map(n,function(e){return{name:t.name,value:e.replace(St,"\r\n")}}):{name:t.name,value:n.replace(St,"\r\n")}}).get()}});var qt=/%20/g,Dt=/#.*$/,Ot=/([?&])_=[^&]*/,Lt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ht=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ft=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Pt={},Mt="*/".concat("*"),$t=te.createElement("a");$t.href=Ct.href,de.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Ht.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Mt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":de.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Q(Q(e,de.ajaxSettings),t):Q(de.ajaxSettings,e)},ajaxPrefilter:G(It),ajaxTransport:G(Pt),ajax:function(t,n){function r(t,n,r,a){var c,p,h,b,w,T=n;l||(l=!0,u&&e.clearTimeout(u),o=void 0,s=a||"",C.readyState=t>0?4:0,c=t>=200&&t<300||304===t,r&&(b=J(d,C,r)),b=K(d,b,C,c),c?(d.ifModified&&(w=C.getResponseHeader("Last-Modified"),w&&(de.lastModified[i]=w),w=C.getResponseHeader("etag"),w&&(de.etag[i]=w)),204===t||"HEAD"===d.type?T="nocontent":304===t?T="notmodified":(T=b.state,p=b.data,h=b.error,c=!h)):(h=T,!t&&T||(T="error",t<0&&(t=0))),C.status=t,C.statusText=(n||T)+"",c?v.resolveWith(g,[p,T,C]):v.rejectWith(g,[C,T,h]),C.statusCode(x),x=void 0,f&&m.trigger(c?"ajaxSuccess":"ajaxError",[C,d,c?p:h]),y.fireWith(g,[C,T]),f&&(m.trigger("ajaxComplete",[C,d]),--de.active||de.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var o,i,s,a,u,c,l,f,p,h,d=de.ajaxSetup({},n),g=d.context||d,m=d.context&&(g.nodeType||g.jquery)?de(g):de.event,v=de.Deferred(),y=de.Callbacks("once memory"),x=d.statusCode||{},b={},w={},T="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a)for(a={};t=Lt.exec(s);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return l?s:null},setRequestHeader:function(e,t){return null==l&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==l&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)C.always(e[C.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||T;return o&&o.abort(t),r(0,t),this}};if(v.promise(C),d.url=((t||d.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||"*").toLowerCase().match(qe)||[""],null==d.crossDomain){c=te.createElement("a");try{c.href=d.url,c.href=c.href,d.crossDomain=$t.protocol+"//"+$t.host!=c.protocol+"//"+c.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!=typeof d.data&&(d.data=de.param(d.data,d.traditional)),Y(It,d,n,C),l)return C;f=de.event&&d.global,f&&0===de.active++&&de.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Ft.test(d.type),i=d.url.replace(Dt,""),d.hasContent?d.data&&d.processData&&0===(d.contentType||"").indexOf("application/x-www-form-urlencoded")&&(d.data=d.data.replace(qt,"+")):(h=d.url.slice(i.length),d.data&&(i+=(kt.test(i)?"&":"?")+d.data,delete d.data),d.cache===!1&&(i=i.replace(Ot,"$1"),h=(kt.test(i)?"&":"?")+"_="+jt++ +h),d.url=i+h),d.ifModified&&(de.lastModified[i]&&C.setRequestHeader("If-Modified-Since",de.lastModified[i]),de.etag[i]&&C.setRequestHeader("If-None-Match",de.etag[i])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",d.contentType),C.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Mt+"; q=0.01":""):d.accepts["*"]);for(p in d.headers)C.setRequestHeader(p,d.headers[p]);if(d.beforeSend&&(d.beforeSend.call(g,C,d)===!1||l))return C.abort();if(T="abort",y.add(d.complete),C.done(d.success),C.fail(d.error),o=Y(Pt,d,n,C)){if(C.readyState=1,f&&m.trigger("ajaxSend",[C,d]),l)return C;d.async&&d.timeout>0&&(u=e.setTimeout(function(){C.abort("timeout")},d.timeout));try{l=!1,o.send(b,r)}catch(e){if(l)throw e;r(-1,e)}}else r(-1,"No Transport");return C},getJSON:function(e,t,n){return de.get(e,t,n,"json")},getScript:function(e,t){return de.get(e,void 0,t,"script")}}),de.each(["get","post"],function(e,t){de[t]=function(e,n,r,o){return de.isFunction(n)&&(o=o||r,r=n,n=void 0),de.ajax(de.extend({url:e,type:t,dataType:o,data:n,success:r},de.isPlainObject(e)&&e))}}),de._evalUrl=function(e){return de.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},de.fn.extend({wrapAll:function(e){var t;return this[0]&&(de.isFunction(e)&&(e=e.call(this[0])),t=de(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return de.isFunction(e)?this.each(function(t){de(this).wrapInner(e.call(this,t))}):this.each(function(){var t=de(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=de.isFunction(e);return this.each(function(n){de(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){de(this).replaceWith(this.childNodes)}),this}}),de.expr.pseudos.hidden=function(e){return!de.expr.pseudos.visible(e)},de.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},de.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Wt={0:200,1223:204},Bt=de.ajaxSettings.xhr();pe.cors=!!Bt&&"withCredentials"in Bt,pe.ajax=Bt=!!Bt,de.ajaxTransport(function(t){var n,r;if(pe.cors||Bt&&!t.crossDomain)return{send:function(o,i){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest");for(s in o)a.setRequestHeader(s,o[s]);n=function(e){return function(){n&&(n=r=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?i(0,"error"):i(a.status,a.statusText):i(Wt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),r=a.onerror=n("error"),void 0!==a.onabort?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{a.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),de.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),de.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return de.globalEval(e),e}}}),de.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),de.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,o){t=de(" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/introduction.html b/clones/llthw.common-lisp.dev/introduction.html new file mode 100644 index 00000000..52a038d0 --- /dev/null +++ b/clones/llthw.common-lisp.dev/introduction.html @@ -0,0 +1,1853 @@ + + + + + + + Lisp: A Future History ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    + + + + + + + + +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    + +

                                                                                                                                                                                                                                    Preface pt. IV

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Lisp, a Future History

                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    "The future is better than the past. Despite the crepehangers, romanticists, and anti-intellectuals, the world steadily grows better because the human mind, applying itself to environment, makes it better. With hands...with tools...with horse sense and science and engineering."

                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    Robert A. Heinlein, The Door Into Summer
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Many of the books about Common Lisp currently available on the market start off with a review of Lisp's history. This is sensible, being that the Lisp family of languages has such a long and rich lineage, there is much to tell. Rather than present another take on the past, however, I wish to share my vision for the future of Lisp. If the history of the Lisp language and its community interests you, which it should, please check out the many fine books listed under the Resources section of this site.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    A Technology Driven Culture

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Human society has always been a technology-driven culture. In every period of history, society was driven by innovation, ever since the very beginning of history when the ancient Sumerians first began carving words into clay tablets, to capture and preserve the fleeting vocalizations that would otherwise be lost in time the moment they had been spoken. Even that innovation was not enough for them---they kept pushing the boundaries of what writing could do, from the very first accounting records to the hero's journey of Gilgamesh.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    We are no different today---we build on the work of those who came before us, we adapt and modify what already exists to suit our needs at the time, and sometimes, we stumble upon an innovation so important that it changes the world. John McCarthy's first paper on Lisp was such an innovation.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Programming Languages Today

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Today, Common Lisp is still setting the standard in the programming world, as no other language has yet come to match it in terms of speed, expressiveness, interactivity, and features. Every so often, a new programming language comes out, or a new version of an old one, luring in software developers and system architects alike with empty promises of game-changing innovation; meanwhile, Lisp Hackers are having a private chuckle amongst themselves at the naivety of developers in the outer circle of tech.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Specifically, such languages as Swift, Python, C++11, and Java 8 have been boasting recently about their ground-breaking new features, such as generics, functional programming constructs, lambda expressions, streams, and tail-call optimization, to name only a few. All of these features were established in the ANSI standardization of Common Lisp in the 1980s, plus countless more. Lisp Hackers have had decades to use these feature sets, and push innovation further still.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    However, because of popular opinions in the programming world, such as "Lisp is old and crufty", or "Lisp is too hard to learn for the average programmer", the Lisp community has gotten smaller and smaller, and Lisp Hackers more and more expensive to hire. As a result, many companies get scared when Lisp is pitched as the technology for a project, even when it is obviously the best choice. Safe choices like C++, Java, .NET, Ruby, or Python are preferred, despite the many disadvantages and notorious bugginess.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    But a number of companies around the world have changed their tune---they're tired of the marketing gimmicks. They're tired of paying for proprietary platforms, languages, and IDEs, riddled with bugs which need constant, daily security patches. They're tired of building their product line in a language so unstable that they have to rewrite large sections of code every time there is one of these updates. They're tired of feeling like every new programming language is just digital snake-oil. They want a platform that works everywhere the same, to write code that doesn't break between security updates, to build a product that stands the test of time. And as a result, more and more companies are turning to Lisp for answers---the only problem now is that there aren't enough Lisp Hackers to go around.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    The Lisp Community

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    The Lisp community, albeit relatively small compared to languages such as Python or Haskell, is a much friendlier place. Mostly because the Lisp language is itself inclusive, supporting every programming paradigm in the world, and allowing Lisp Hackers to create and implement their own paradigms easily.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Lisp Consciousness

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    There's just something about Lisp---it changes the way you think, the way you see the world, the way you act. Lisp Hackers have long known and proudly vocalized the near-mystical experience that comes with writing software in this language; they have adopted the Heinleinian terminology of 'grokking' to describe the state of consciousness a programmer achieves when they stop just writing code in Lisp and start becoming one with their software; they have incorporated religious and mystical concepts from Gnosticism, Zen Buddhism, Hinduism, Sufism, and Western Occultism into the Lisp mythos. Lisp teachers cannot simply teach a programming language as any other is taught; no, they feel compelled by a fire in their hearts to preach the gospel of Lisp. Naturally, other people---particularly non-Lisp programmers---find this extremely off-putting.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    There is a rational explanation of this phenomenon, however; as it so happens, the syntax of Lisp software, in practice, follows the structure of the central nervous system. Lisp models the brain. The mind, which is itself very much like software, recognizes this shared structure and responds positively to it. In other words, your mind, consciously or otherwise, sees itself and its underlying structure in Lisp as soon as it is able to make sense of what it is seeing, and as a result, awakens you to Lisp, just as you awakened once as a child the first time you looked into a mirror and realized you were seeing your own reflection. This is the moment you 'grok' Lisp.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    But it doesn't stop there---grokking is just the beginning of your Lisp journey. When the human brain and the computer are perfectly synchronized through a shared language that accurately models the underlying systems of both, the human mind naturally extends itself into the machine and experiences gestalt consciousness. The mind is capable of unconsciously understanding the structure of the computer through the Lisp language, and as such, is able to interface with the computer as if it was an extension to its own nervous system. This is Lisp Consciousness, where programmer and computer are one and the same; they drink of each other, and drink deep; and at least as long as the Lisp Hacker is there in the flow, riding the current of pure creativity and genius with their trusty companions Emacs and SLIME, neither programmer nor computer know where one ends and the other begins. In a manner of speaking, Lispers already know machine intelligence---and it is beautiful.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Convergence Theory and the Technological Singularity

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    The mysterious force driving human society towards the technological singularity, true and total unification of human with technology, also seems to be shaping all programming languages into Lisp, and all computers into Lisp Machines. Lisp, after all, can do everything, and do it every way; that Lisp is not already the de-facto programming language is just a reflection of the state of the world as a whole---only a very small percentage of the population are excited for the technological singularity, but the singularity is coming no matter how much people complain. One way or another, every programmer is going to end up being a Lisper, because every programming language continues to adopt features and syntax from Lisp, one piece at a time. It is in every programmer's interest to master Lisp now, before the world at large realizes how essential Lisp will become over the next two decades.

                                                                                                                                                                                                                                    +

                                                                                                                                                                                                                                    Quantum Computing, the next big leap in computing and a fundamental aspect of the singularity, also currently happens to rely entirely on Lisp. There are efforts underway to adapt quantum computer programming to all sorts of languages and familiar syntaxes, but the only real quantum computers currently available are effectively Quantum Lisp Machines, and have their operating system written in Common Lisp. The power, simplicity, and elegance of Lisp really shines where it matters most: quantum computer programming is nearly impossible to understand unless you're a Lisp Hacker, but for a Lisp Hacker, it makes more sense than classical computing.

                                                                                                                                                                                                                                    + + +
                                                                                                                                                                                                                                    + +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                    + +

                                                                                                                                                                                                                                    results matching ""

                                                                                                                                                                                                                                    +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      + +

                                                                                                                                                                                                                                      No results matching ""

                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                      + + +
                                                                                                                                                                                                                                      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/preface-part-three.html b/clones/llthw.common-lisp.dev/preface-part-three.html new file mode 100644 index 00000000..85e7a7ad --- /dev/null +++ b/clones/llthw.common-lisp.dev/preface-part-three.html @@ -0,0 +1,1859 @@ + + + + + + + Who Is This Book For? ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      + + + + + + + + +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      + +

                                                                                                                                                                                                                                      Preface pt. III

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Who Is This Book For?

                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      "Do not handicap your children by making their lives easy."

                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      Robert A. Heinlein, Time Enough for Love
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Programming books can be tedious, and usually come in only one of two bland flavours---so basic an introduction you know less about the language after reading the book, or so dense a tome it is not useful outside an ivy-league university's computer science program. The Hard Way is different.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      You don't have to know anything about programming or computer science to learn Lisp with this book, but I'm not going to talk down to you either. I'm going to assume that you know that learning any new skill is hard for everyone, and that you need to work hard in order to succeed.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Sometimes, you might not understand what I'm talking about, so I also expect you to take advantage of all the free research tools available on the internet---search engines, dictionaries, thesauri, encyclopedias, reference works, academic papers, programming blogs, and more. Any time you feel completely boggled, you should turn to these. I will be as casual as possible in my presentation, but sometimes it makes more sense to be formal.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      That being said, Lispers of all experience levels should benefit from this book. We'll be exploring the language through real, immediately useful source code examples, and dissecting the language down to its core. Later on in the book, we'll also be covering a wide variety of advanced, relevant practical applications using a selection of the most popular and powerful libraries from the Lisp community.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      So in summary, this book is for you if:

                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                      • You know nothing about programming, but want to learn
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • You tried to learn Lisp before, but other books made it seem too hard or not useful
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • You are an experienced programmer considering a move to Lisp
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • You are already a Lisper, but want to take your code to the next level, or
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      • You simply haven't seen what all the fuss is about when it comes to Lisp---but you keep hearing how amazing Lisp is, so here you are reading another book about it
                                                                                                                                                                                                                                      • +
                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Practice and Persistence

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      To learn any new skill, you have to take the time, while applying the five rules of learning the hard way. You'll have good days and bad, times when you feel inspired and everything makes perfect sense, and times when you would rather just veg-out in front of the TV because you feel completely brain-dead already. Keep in mind that to maintain a skill, the rule of thumb is to spend at least two hours a day practicing. To improve an existing skill or learn a new one, it may require a lot more commitment from you.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Once again, don't let yourself be disheartened if some days you can't seem to make sense of the exercises and material. Learning any new skill takes a considerable shift in the way you think, as well as effort. Also, don't let yourself get disheartened if you feel like you're not progressing fast enough---there's no timeline for the exercises, you're not competing with anyone else for the top grade. You should take the time you need to complete each exercise at your own pace, so that you actually learn the material that the exercise covers.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      The best advice I can offer for when you hit the wall is to stick to the five steps of the Hard Way, no matter what. Force yourself to work through the next exercise, even if it makes no sense. You might just wake up the next day and suddenly get it---or you may need to repeat it a few times. Persistence pays off, and if you stick with this methodology no matter what challenges you face, you will triumph.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Attitude and Intelligence

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Some of you will think I'm joking when I say, "forget everything you know." I assure you, I'm not. Lisp is different than other languages---it's not imperative, procedural, object-oriented, or functional; it's multi-paradigm. You need to be willing to set your ego aside and remember that everyone has more to learn than they have yet learned or ever can be learned. Yes, Lisp is that different from other languages, even from other multi-paradigm programming languages. If you take this to heart, you will discover that there is always something new to discover.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      From a technical perspective, intelligence is more of an attitude problem than a measure of ability. When you think you are smart, you tend to think you already know everything and have all the answers. This makes learning new skills an uphill battle. You might not be guaranteed to fail at everything new when you already think you know everything, but you will find yourself easily discouraged by "boredom" as new knowledge is beaten away by your ever-swelling ego.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Recognizing your own ignorance up-front allows you to learn without self-sabotage. It is the wisdom of the ancients, every great artist's secret weapon, and an indispensable tool to a programmer. And since The Lisp Way is so fundamentally different from other approaches to programming, this minor attitude adjustment will help you see Lisp without the blinders of previous experience.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      The End-Goal

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      The end-goal of teaching Lisp is to somehow convey the concept of 'grokking' Lisp to new students of the language. The main challenge with this task, in my humble opinion, is that not enough emphasis has been placed on first forgetting everything you know, and second on the core syntax of Lisp where the symmetry with the human mind and the fractal cosmology model of the universe are most obvious. While other books on Lisp leave the matter of grokking open, hoping that by the end the reader will just grok grokking for themselves, in this book, grokking is a first-class citizen of your Lisp education. It's that important.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      Lisp is, at its heart, a very mystical language which blurs the line between programming and magic. It is so inspired that, as one of my blog readers suggested, it seems more as though it was created by the ancient Egyptian god of writing and magic, Thoth, and handed down to John McCarthy in revelation. Several notable Lispers have even described that moment of their sudden awakening to understanding of Lisp as a religious experience, a suffusion of blue inspiring deep spiritual sentiments and a tendency towards prophesy.

                                                                                                                                                                                                                                      +

                                                                                                                                                                                                                                      This is where the term 'grokking' comes into the picture. It was coined by speculative/science fiction author Robert A. Heinlein in his novel, Stranger in a Strange Land, to describe the experience of knowing something so deeply that you become a part of it as much as it becomes a part of you. In short, Grokking is gnosis for the transhuman age. So being that learning Lisp shares so much in common with mystical initiation, using the initiatory techniques of Occult orders in teaching Lisp makes a lot of sense. This is why the Hard Way is the road to the Lisp Way, and why even experienced Lisp, Scheme, Clojure, Haskell, and OCaml programmers will benefit as greatly from this book as an absolute beginner.

                                                                                                                                                                                                                                      + + +
                                                                                                                                                                                                                                      + +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                      + +

                                                                                                                                                                                                                                      results matching ""

                                                                                                                                                                                                                                      +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        + +

                                                                                                                                                                                                                                        No results matching ""

                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                        + + +
                                                                                                                                                                                                                                        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/preface-part-two.html b/clones/llthw.common-lisp.dev/preface-part-two.html new file mode 100644 index 00000000..ddc5548c --- /dev/null +++ b/clones/llthw.common-lisp.dev/preface-part-two.html @@ -0,0 +1,1864 @@ + + + + + + + The Hard Way is Easier ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        + + + + + + + + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        + +

                                                                                                                                                                                                                                        Preface pt. II

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        The Hard Way Is Easier

                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        "The hardest part about gaining any new idea is sweeping out the false idea occupying that niche. As long as that niche is occupied, evidence and proof and logical demonstration get nowhere. But once the niche is emptied of the wrong idea that has been filling it---once you can honestly say, 'I don't know,' then it becomes possible to get at the truth."

                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        Robert A. Heinlein, The Cat Who Walks Through Walls
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Whatever you think you know about programming, forget it. Lisp is different from other programming languages.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        If you're coming to Lisp as an experienced developer, it is only fair to tell you up-front that your experience will hold you back. It will make you feel bored when the material isn't "challenging you". It will make you skip over sections you think you already understand. It will tell you reading the code examples once is enough to learn it, that it's okay to copy-and-paste. But this experience is a lie. If you slack off now, you'll only be making things harder for yourself later.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        No matter who you are or what your background is, if you stick to the steps of learning The Hard Way, you'll see that it is actually easier in the long run. You'll have to work hard, but you'll learn what you need to learn the first time, and you won't forget it.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Learning the hard way means following these five steps every day until you've completed this book:

                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                        1. Forget everything you know
                                                                                                                                                                                                                                        2. +
                                                                                                                                                                                                                                        3. Work through each exercise from beginning to end
                                                                                                                                                                                                                                        4. +
                                                                                                                                                                                                                                        5. Type in each example exactly
                                                                                                                                                                                                                                        6. +
                                                                                                                                                                                                                                        7. Make the code run
                                                                                                                                                                                                                                        8. +
                                                                                                                                                                                                                                        9. Reflect on what you've seen
                                                                                                                                                                                                                                        10. +
                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        And that's all.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Depending on your level of self-discipline, you may have a more difficult time sticking to these steps than some---but this isn't a contest. Don't worry about how long it takes you to work through an exercise, don't panic if you have to miss a day, and don't compare yourself to others. If you do your best to apply these steps every day, you will develop the self-discipline required to see this book through to the end.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        An important theme of this book is also on the skills necessary for programming in general, while using Lisp to reinforce them. These skills are: reading and writing, attention to detail, spotting differences, and mathematics. Thus, once you finish this book, you won't just be a Lisp Hacker, you'll be ready to tackle other programming languages too---and in the process you might just discover that learning a new skill is more fun than any hobby, game, movie, or tv show.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Reading and Writing

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Programming, much like human language, involves the intentional use of a specific set of language-dependent characters that have meaning, some of which you might not be used to typing. Programming is significantly more exact than human languages---if you have trouble reading, writing, or typing, you will struggle writing code.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Take the time to read over the code examples carefully, and double-check your work once you have typed it. This will save you from many stress headaches along the way.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Attention to Detail

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        More than any other skill, what separates a professional from an amateur in every field and trade is attention to detail. In programming, this is especially obvious; it makes the difference between sluggish, buggy software that regularly crashes and leads to hair-loss in its users, and a refined, user-friendly, indispensable tool.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        By manually typing each exercise exactly as you work through this book, you will be training your brain to focus on the subtle details of what you are doing, while you are doing it.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Spotting Differences

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        The natural extension to the first two skills is the ability to spot differences. With careful reading, typing, and attention to detail, you will also be training your brain to highlight subtle differences for you, so that when you make a mistake, you notice, and can correct it immediately.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Naturally, this skill will also help you more quickly spot and correct bugs in other people's code that you have to upgrade and maintain.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Mathematics

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        Remember in high school, there was always at least one classmate that would demand to know when, in life, any of you would ever need to know half the stuff they taught you? You may have even been that student. If so, you may be disappointed to know that many problem domains a professional programmer has to deal with on a daily basis require nearly the entire high school and university level math curricula. I'm not talking about highly specialized fields either, like Quantum Computing; Currency, Stock, and Commodity exchange; or Cryptography---junior game, mobile, and web developers need math too. As Zed Shaw argued in an excellent, albeit angry rant essay, at the very least you should know Statistics. But Algebra, Geometry, Trigonometry, Calculus, Lambda Calculus---and of course, Algorithms---are extremely useful tools that will help you reason about and abstract your code at a whole new level.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        If the very idea of math makes your heart skip a beat, your hands shake, and your brow drip with sweat, just remember the infamous words inscribed on the cover of the Hitchhiker's Guide to the Galaxy: DON'T PANIC. You don't have to be a math-whiz to learn programming or Lisp, and this book assumes little to no familiarity with math above the grade-school level. You can learn the math you need along the way, when you need it---and you will probably understand it better this time because you'll see its practical value. Just remember that math is your friend---even when it's not essential, formal quantitative reasoning, analysis, and deductive reasoning will give you an edge over other developers, and help you write better software. Oh right, and make sure you know where your towel is.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        No Copy-and-Paste

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        If you copy-and-paste the code from the exercises into the Lisp REPL instead of typing them out yourself, you might as well not do them at all. As both teacher and student for the duration of this book, you have to force yourself to type in every example. No matter how easy or self-evident a code example appears to be, you have to stop yourself from cheating.

                                                                                                                                                                                                                                        +

                                                                                                                                                                                                                                        The point of these exercises is to train your hands, your eyes, your brain, and your mind how to read, write, see, think, and dream code. When you cheat here, you're only cheating yourself.

                                                                                                                                                                                                                                        + + +
                                                                                                                                                                                                                                        + +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                        + +

                                                                                                                                                                                                                                        results matching ""

                                                                                                                                                                                                                                        +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          + +

                                                                                                                                                                                                                                          No results matching ""

                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                          + + +
                                                                                                                                                                                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clones/llthw.common-lisp.dev/preface.html b/clones/llthw.common-lisp.dev/preface.html new file mode 100644 index 00000000..dceca8a9 --- /dev/null +++ b/clones/llthw.common-lisp.dev/preface.html @@ -0,0 +1,1838 @@ + + + + + + + TANSTAAFL ยท Learn Lisp The Hard Way + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          + + + + + + + + +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          + +

                                                                                                                                                                                                                                          Preface pt. I

                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          TANSTAAFL

                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          "There Ain't No Such Thing As A Free Lunch... anything free costs twice as much in the long run or turns out worthless."

                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          Robert A. Heinlein, The Moon Is A Harsh Mistress
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          Programming is hard. Anyone who says differently is either trying to make you feel inferior to them or sell you something. In the case of many "easy-to-learn" programming languages, both happen to be true. But you're not here for inefficient, glorified, instant-gratification scripting languages that pigeon-hole you into prescribed execution control-flows and common use cases. You're not here for monolithic imperative languages that have to be tamed into submission for the simplest tasks. You've sought out the Hard Way, and the hardest language to master, Common Lisp. You're not afraid of working for what you want or committing to a new way of thinking---you're here because you want to be a Lisp Hacker, and you're not going to let anything get in your way.

                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          That being said, learning Lisp is not an impossible dream. Like any skill, practice makes perfect---and that's what the Hard Way is all about. Lisp may seem like an ancient mystical secret, cherished and protected by an impenetrable cabal of hacker elites, but that, much like the language's popular association solely with Artificial Intelligence, is a misconception. You don't have to be a genius or Black Hat to crack the mystery surrounding the language and the open-source subculture where it thrives. You just have to follow a few essential steps, and apply them without fail.

                                                                                                                                                                                                                                          +

                                                                                                                                                                                                                                          The biggest secret to Lisp is that it is actually the simplest programming language ever created---and that, coupled with its expressiveness and elegance, is why it is favored exclusively by the best programmers in the world. With hard work, attention to detail, and careful reflection over the subject material, you will be up and running with Lisp and writing real applications much earlier than you could with other, lesser languages.

                                                                                                                                                                                                                                          + + +
                                                                                                                                                                                                                                          + +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                          + +

                                                                                                                                                                                                                                          results matching ""

                                                                                                                                                                                                                                          +
                                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                            + +

                                                                                                                                                                                                                                            No results matching ""

                                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                                            +
                                                                                                                                                                                                                                            + +
                                                                                                                                                                                                                                            + + + + + + + + + + + + + + +
                                                                                                                                                                                                                                            + + +
                                                                                                                                                                                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

                                                                                                                                                                                                                                          • 8.1 Varieties of Ports

                                                                                                                                                                                                                                            Various functions create various kinds of ports. Here are a few +examples: